Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using certificate and private key from Windows cert store with OpenSSL

I am trying to make a program that uses some Web Services in Delphi XE. To connect to the Web Services, I have to use a self signed certificate, which is stored in the Windows cert store. I open the cert store with CertOpenSystemStore, get the cert with CertFindCertificateInStore and set it with SSL_CTX_use_certificate. No problem with this. Then I get the public key blob with CryptExportKey and make up a private key like this:

function PrivKeyBlob2RSA(const AKeyBlob: PByte; const ALength: Integer; const ASSLCtx: PSSL_CTX): IdSSLOpenSSLHeaders.PEVP_PKEY; var   modulus: PByte;   bh: PBLOBHEADER;   rp: PRSAPUBKEY;   rsa_modlen: DWORD;   rsa_modulus: PAnsiChar;   rkey: PRSA; begin   bh := PBLOBHEADER(AKeyBlob);   Assert(bh^.bType = PUBLICKEYBLOB);   rp := PRSAPUBKEY(AKeyBlob + 8);   Assert(rp.magic = $31415352);   rsa_modulus := PAnsiChar(Integer(Pointer(rp))+12);   rkey := RSA_new_method(ASSLCtx.client_cert_engine);   rkey^.References := 1;   rkey^.e := BN_new;   rkey^.n := BN_new;   BN_set_word(rkey^.e, rp^.pubexp);   rsa_modlen := (rp^.bitlen div 8) + 1;   modulus := AllocMem(rsa_modlen);   CopyMemory(modulus, rsa_modulus, rsa_modlen);   RevBuffer(modulus, rsa_modlen);   BN_bin2bn(modulus, rsa_modlen, rkey^.n);   Result := EVP_PKEY_new;   EVP_PKEY_assign_RSA(Result, PAnsiChar(rkey)); end; 

I then set it up with SSL_CTX_use_PrivateKey and SSL_CTX_check_private_key - no problem so far. But when the data transfer begins, I get an access violation in libeay32.dll. If I load the key from .pem file, everything is fine. I can't see what I am doing wrong, please help :)

Here is the exact error message:

Access violation at address 09881C5F in module 'libeay32.dll'. Read of address 00000000.

The libeay32.dll version is 1.0.0.5. Tried with version 0.9.something too - got the same error, just different address.

Below is the RSA structure I get in PrivKeyBlob2RSA:

pad    0 version  0 meth       $898030C engine     nil n      $A62D508 e      $A62D4D8 d      nil p      nil q      nil dmp1       nil dmq1       nil iqmp       nil ex_data (nil, -1163005939 {$BAADF00D}) references  1 flags      6 _method_mod_n   nil _method_mod_p   nil _method_mod_q   nil bignum_data nil {#0} blinding    nil mt_blinding nil 

I checked the n and e bignums, and they are CORRECT, and everything else looks ok. And yes, the error happens when calling function ssl_read.

like image 482
Andrejs Avatar asked Oct 27 '11 08:10

Andrejs


People also ask

Does OpenSSL use Windows certificate store?

No. Not out of the box.

How do I pair a certificate with a private key?

Assign the existing private key to a new certificateSign in to the computer that issued the certificate request by using an account that has administrative permissions. Select Start, select Run, type mmc, and then select OK. On the File menu, select Add/Remove Snap-in. In the Add/Remove Snap-in dialog box, select Add.

How do I export a certificate with private keys in Windows certification authority?

In the console tree under the logical store that contains the certificate to export, click Certificates. In the details pane, click the certificate that you want to export. On the Action menu, point to All Tasks, and then click Export. In the Certificate Export Wizard, click Yes, export the private key.

How do I create a PFX file from certificate and private key OpenSSL?

With that you can generate the pfx file by the following steps: Import private key in the "Private Keys" tab; Import the certificate in the "Certificates" tab; Generate the pfx file by selecting the certificate and then "Export", select PKCS #12 as the format.


1 Answers

It seems to me the most reasonable reasons you would get these errors include:

  1. Wrong version of OpenSSL dlls (libeay32 ssleay.dll) or error in declaring SSL wrappers (in this case you might need an Indy Version 10 upgrade).

  2. Having already freed the block of memory you're passing into the DLL, as per Ken's comment.

  3. Some subtle pointer dereferencing bug in the code you posted. A call to CopyMemory might be missing a level of pointer indirection via "PointerVariableName^" instead of just "PointerVariableName". Read up on "untyped var parameters and pointers in pascal" if you're unclear.

like image 82
Warren P Avatar answered Sep 20 '22 13:09

Warren P