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

↘锁芯ラ 提交于 2019-11-27 02:04:44
Mathias Brossard

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;
}

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.

Rune Torgersen

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().

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!