How to load a PKCS#12 file in OpenSSL programmatically?

后端 未结 3 753
失恋的感觉
失恋的感觉 2020-11-29 10:38

In an SSL Server Application based on OpenSSL, how can we load a PKCS#12 file programmatically?

Also, can I load a PKCS#12 file having Certificate, Key & CAs in

相关标签:
3条回答
  • 2020-11-29 10:41

    Try man SSL, which gives you a list of OpenSSL functions. Something like SSL_load_client_CA_file might suit your needs; it depends if the certificate is in a file on disk or already in memory. There are lots of helper functions, one of them will do the trick. Also check out man PEM for PEM handling routines.

    Edit: Hm, maybe a combination of d2i_PKCS12_fp and PKCS12_parse (both available from <openssl/pkcs12.h>) lets you read a certificate from file and parse it.

    0 讨论(0)
  • 2020-11-29 10:42

    Be warned that the code writes the certs out as trusted certificates (encrypted). If you want unencrypted certificates, change the calls to PEM_write_X509_AUX() to PEM_write_X509().

    0 讨论(0)
  • 2020-11-29 10:52

    Yes you can load a PKCS#12 file containing certificate, key and CAs in the same file with OpenSSL.

    • Use d2i_PKCS12_fp() or d2i_PKCS12_bio() to load the PKCS#12 file.
    • Optionally use PKCS12_verify_mac() to verify the password.
    • Use PKCS12_parse() which decrypts and extracts key, certificate and CA chain for you.

    From openssl-1.0.0d/demos/pkcs12/pkread.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <openssl/pem.h>
    #include <openssl/err.h>
    #include <openssl/pkcs12.h>
    
    /* Simple PKCS#12 file reader */
    
    int main(int argc, char **argv)
    {
        FILE *fp;
        EVP_PKEY *pkey;
        X509 *cert;
        STACK_OF(X509) *ca = NULL;
        PKCS12 *p12;
        int i;
        if (argc != 4) {
            fprintf(stderr, "Usage: pkread p12file password opfile\n");
            exit (1);
        }
        OpenSSL_add_all_algorithms();
        ERR_load_crypto_strings();
        if (!(fp = fopen(argv[1], "rb"))) {
            fprintf(stderr, "Error opening file %s\n", argv[1]);
            exit(1);
        }
        p12 = d2i_PKCS12_fp(fp, NULL);
        fclose (fp);
        if (!p12) {
            fprintf(stderr, "Error reading PKCS#12 file\n");
            ERR_print_errors_fp(stderr);
            exit (1);
        }
        if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
            fprintf(stderr, "Error parsing PKCS#12 file\n");
            ERR_print_errors_fp(stderr);
            exit (1);
        }
        PKCS12_free(p12);
        if (!(fp = fopen(argv[3], "w"))) {
            fprintf(stderr, "Error opening file %s\n", argv[1]);
            exit(1);
        }
        if (pkey) {
            fprintf(fp, "***Private Key***\n");
            PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
        }
        if (cert) {
            fprintf(fp, "***User Certificate***\n");
            PEM_write_X509_AUX(fp, cert);
        }
        if (ca && sk_X509_num(ca)) {
            fprintf(fp, "***Other Certificates***\n");
            for (i = 0; i < sk_X509_num(ca); i++) 
                PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
        }
    
        sk_X509_pop_free(ca, X509_free);
        X509_free(cert);
        EVP_PKEY_free(pkey);
    
        fclose(fp);
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题