locked
Merge X509 certificate request with signed certificate RRS feed

  • Question

  • I'm using CryptoAPI to create a certificate request along these lines:

    CryptAcquireContext(...)
    CryptGenKey(...)
    CryptExportPublicKeyInfo(...)
    CryptSignEndEncodeCertificate(X509_CERT_REQUEST_TO_BE_SIGNED)
    CyptBinaryToString(...)

    Now, the CSR is submitted to a CA which in turn returns the signed certificate to me (.p7b format)
    How do I now, using the CryptoAPI, merge this certificate with the private key?

    I have the handle to the HCRYPTKEY from CryptGenKey still valid, since it has not been destroyed. I also have the original HCRYPTPROV.

    The goal is to associate the private key with the .p7b and save it in the user's store.
    I've tried:

    CryptImportPublicKeyInfo(...)
    CertOpenStore(...)
    CertAddCertificateContextToStore(...)

    into the original context which would have a reference to the private key, but the saved certificate does not contain the private key, only the signed public key. What am I missing here?

    Regards Björn






    Bjorn

    Monday, October 17, 2016 12:06 PM

Answers

  • Hello Bjorn,

    Basically you've done all the work and you just need to finish it up. For example ...

    CertOpenStore() in the memory with your provider

    CertAddEncodedCertificateToStore() with store opened, flag add/replace and your certificate context

    you probably would want to set CRYPT_KEY_PROV_INFO structure for your cert at this point and finally to get your pfx with private key ...

    PFXExportCertStoreEx() with your store and EXPORT_PRIVATE_KEYS flag.

    Hope this helps,


    Slava Ivanov

    Monday, October 17, 2016 7:24 PM
  • Hi Slava,

    thank you for your reply. You pointed me in the right direction. The complete merge outline should be:

    CertSetCertificateContextProperty(CERT_KEY_PROV_INFO_PROP_ID)
    CertOpenStore(...)
    CertAddCertificateContextToStore(...)
    CertCloseStore(...)

    The really misleading thing here is there is no reference whatsoever to the original crypto-context or the generated keypair. I close the context and destroy the key after generating the request. I can reboot the computer and then when reloading the signed certificate, by calling the CertSetCertificateContextProperty with only a reference to the same certificate store, it will automatically associate the private key, which must be stored somewhere deep down..

    Regards Björn





    Bjorn

    Tuesday, October 18, 2016 2:02 PM

All replies

  • Hello Bjorn,

    Basically you've done all the work and you just need to finish it up. For example ...

    CertOpenStore() in the memory with your provider

    CertAddEncodedCertificateToStore() with store opened, flag add/replace and your certificate context

    you probably would want to set CRYPT_KEY_PROV_INFO structure for your cert at this point and finally to get your pfx with private key ...

    PFXExportCertStoreEx() with your store and EXPORT_PRIVATE_KEYS flag.

    Hope this helps,


    Slava Ivanov

    Monday, October 17, 2016 7:24 PM
  • Hi Slava,

    thank you for your reply. You pointed me in the right direction. The complete merge outline should be:

    CertSetCertificateContextProperty(CERT_KEY_PROV_INFO_PROP_ID)
    CertOpenStore(...)
    CertAddCertificateContextToStore(...)
    CertCloseStore(...)

    The really misleading thing here is there is no reference whatsoever to the original crypto-context or the generated keypair. I close the context and destroy the key after generating the request. I can reboot the computer and then when reloading the signed certificate, by calling the CertSetCertificateContextProperty with only a reference to the same certificate store, it will automatically associate the private key, which must be stored somewhere deep down..

    Regards Björn





    Bjorn

    Tuesday, October 18, 2016 2:02 PM