Windows build a full encrypted message from outside signing - winapi

I can encrypt a message in windows given a certificate with a private key with CryptMsgOpenToEncode and CryptMsgUpdate. This returns an ASN1 signature which contains the signature and the certificate enclosed in a full ASN1 message.
My problem now is that I am forced to use an external signing Web API site. Upon signing, the returned string from this Web site is the signature and the certificates in two separated messages, not within an ASN1.
The question is how to to build the message into a proper detached PKCS#7 signature (which would be put in a PDF file).
Must I build the ASN1 manually? I'm already using ASNC but I'm not sure how to build the complete message. Can I use openssl to combine certs + signature into a PKCS#7?
Thanks.

Related

How to include PDF signature's embedded timestamp authority chain revocation info in Adobe's RevInfoArchival attribute for LTV purposes?

I'm trying to create a LTV Enabled PDF Signature using Apache's PDFBox Detached Signature and the BouncyCastle API for the cryptographic signature itself.
So far I was able to make Adobe Reader display the "Signature is LTV enabled" message following these steps:
Retrieve revocation info (both CRLs and OCSP Responses, except for root certificates of course) for the signing certificate's full chain and for the timestamp authority certificate's full chain (used to add the signature's timestamp in step #4)
Include revocation info retrieved in step #1 as a signed attribute for the signature to be computed in Adobe OID "1.2.840.113583" format:
adbe-revocationInfoArchival OBJECT IDENTIFIER ::= {
adbe(1.2.840.113583) acrobat(1) security(1) 8 }
RevocationInfoArchival ::= SEQUENCE {
crl [0] EXPLICIT SEQUENCE of CRLs OPTIONAL,
ocsp [1] EXPLICIT SEQUENCE of OCSP Responses OPTIONAL,
otherRevInfo [2] EXPLICIT SEQUENCE of OtherRevInfo OPTIONAL
}
OtherRevInfo ::= SEQUENCE {
Type OBJECT IDENTIFIER
ValValue OCTET STRING
}
Perform the signature
Embed a qualified timestamp in the signature generated in the step #3
The previous steps' output gives me the "LTV Enabled" status in Adobe Reader:
When I check which data Adobe Reader used to validate the certificate chain validity it presents the expected "The selected certificate is considered valid because it has not been revoked as verified using the Online Certificate Status Protocol (OCSP) response that was embedded in the signature."
However, when I perform the same check for the Timestamp Authority's certificate chain it presents "The selected certificate is considered valid because it has not been revoked as verified in real-time using the Online Certificate Status Protocol (OCSP) obtained on-line."
The Signer's chain embedded CRLs/OCSPs are successfully used but the embedded TSA's chain CRLs/OCSPs are not.
This begs some questions that need to be answered:
Why are not the TSA embedded CRLs/OCSPs embedded used?
Do I have to place them elsewhere? If so, where?
Or do I have to ask the Timestamping authority to return the CRLs and/or OCSP responses as signed attribute within the timestamp token?

How do I find my server's public key info to do certificate pinning in OkHttp?

I have a server with a custom certificate on it issued by my own personal certificate authority. It's not on a public domain so it's not possible to use a standard certificate authority. I want to get an Android client to connect to this server using OkHttp. According to the docs, the code should look like this:
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("myserver.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
.build();
Where the SHA256 hash is, quoting the docs: "a hash of a certificate’s Subject Public Key Info, base64-encoded and prefixed with either sha256/ or sha1/". I have the cert and the key files for the server, but how can I get the required hash?
I'm using OkHttp 3.
Try making a request to your server with the configuration above to see how that fails. The exception should tell you which pins were found.
You must do certificate pinning in coordination with your server team! Otherwise a change they make will prevent your client from being able to reach the server.

Check if X509 Certificate matches a CertificateRequest (CSR)

How can I check if a x509 certificate matches a CSR (if the certificate was generated based on a specific CSR) in Go? Do I need to generate a new certificate from the CSR and compare them?
If your signing request is in the DER format there's a couple of functions in the standard library you can use; first to parse the CSR (https://golang.org/pkg/crypto/x509/#ParseCertificateRequest) and then the certificate (https://golang.org/pkg/crypto/x509/#ParseCertificate). Once parsed you can compare the public key values.
Standard but important security note:
Please note that this DOES NOT validate the certificate in anyway. It may or may not be safe to use, and could have been substituted or altered.

Loading paypal's x509 public certificate from file in Ruby

I am using website payments standard provided by paypal. I have generated the code for paypal pay now button. I have generated a key and certificate pair for my application and also have uploaded my application certificate to paypal and retrieved their public certificate as well as the cert id for my application certificate.
Using the paypal public certificate and the cert id I am attempting to encrypt data sent to paypal and then sign in it using my private key. The entire code for application is written in ruby on rails. But for some reason I always keep getting "Cannot decrypt cert id" when I try to make a payment. On investigation I found out that the error is in this line of code
OpenSSL::X509::Certificate.new File.read("paypal-public.pem");
This line throws a nested ASN1 error.
According to another stackoverflow question I tried adding \n to the end of the .pem file but to no avail.
Any assistance with this regards will be highly appreciated
Thanks in advance.

How to import an OpenSSL key file into the Windows Certificate Store

I've got an OpenSSL generated X.509 certificate in PEM format and it's associated key file. This certificate is required for authentication when connecting to a prototype server. This works fine on Linux. I've been using the Microsoft SChannel API to drive SSL/TLS connections on Windows platforms but I want to use the same test certificate. I can right-click on the certificate file and import it into my certificate store but I believe that the private key is not imported with it (even though I've concatenated them into the same file).
When I go to run the SChannel code, I get a 'SEC_E_NO_CREDENTIALS' error when I init the security context (via InitializeSecurityContext). I suspect this means that the private key is missing.
Does anyone know how to test the presence or absence of a private key in a certificate which is located in the Personal (or 'My') certificate store, accessed via 'certmgr.msc'?. Is it possible to import a new key file for a certificate in the store?
Any insight or advice would be much appreciated.
To test if private key is installed for the certificate, double click the certificate icon in certmgr.msc. If it has private key, it will show a message in the property page that you have private key, otherwise it will not give any reference the the private key.
To import the certificate with its private key, you can do the following:
Pack the certificate and its private key into a PKCS #12 file or PFX file using openssl pkcs12. Here's an example.
Import this PKCS #12 or PFX file into the certificate store.
Note that you may see errors when importing the pfx file, such as 'This file is invalid for use as the following: Personal Information Exchange'. This error was caused by the certificate lacking to appropriate X.509 v3 extensions (such as the usage fields (digital signature, etc))

Resources