/* This function take a user certificate and a private key in x509 format and convert it into pkcs12 format. This function returns -1 if a problem occurs, 0 otherwise */ int convert_x509_to_p12(char *privkey, char *clicert, char *p12cert) { X509 *cert; PKCS12 *p12; EVP_PKEY *cert_privkey; FILE *certfile, *keyfile, *p12file; int bytes = 0; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* Read the private key file */ if ((cert_privkey = EVP_PKEY_new()) == NULL){ printf("Error creating EVP_PKEY structure.\n"); return -1; } if (! (keyfile = fopen(privkey, "r"))){ printf("Error cant read certificate private key file.\n"); return -1; } if (! (cert_privkey = PEM_read_PrivateKey(keyfile, NULL, NULL, NULL))){ printf("Error loading certificate private key content.\n"); return -1; } fclose(keyfile); /* Read the user certificate */ if (! (certfile = fopen(clicert, "r"))){ printf("Error cant read certificate file.\n"); return -1; } if (! (cert = PEM_read_X509(certfile, NULL, NULL, NULL))){ printf("Error loading cert into memory.\n"); return -1; } fclose(certfile); /* Generate the p12 certificate */ if ((p12 = PKCS12_new()) == NULL){ printf("Error creating PKCS12 structure.\n"); return -1;} p12 = PKCS12_create(NULL, NULL, cert_privkey, cert, NULL, 0, 0, 0, 0, 0); if ( p12 == NULL){ printf("Error generating a valid PKCS12 certificate.\n"); return -1; } if (! (p12file = fopen(p12cert, "w"))){ printf("Error cant open pkcs12 certificate file for writing.\n"); return -1; } bytes = i2d_PKCS12_fp(p12file, p12); if (bytes <= 0){ printf("Error writing PKCS12 certificate.\n"); return -1; } fclose(p12file); PKCS12_free(p12); X509_free(cert); EVP_PKEY_free(cert_privkey); return 0; }
static Bool IsPKCS12(const char *file) { Bool ret = TRUE; EVP_PKEY *key = NULL; X509 *cert = NULL; BIO *input; PKCS12 *p12; int err_reason; if ((input = BIO_new_file(file, "r")) == NULL){ if (d2i_PKCS12_bio(input, &p12) == NULL) return FALSE; } p12 = d2i_PKCS12_bio(input, NULL); BIO_free(input); if (p12 == NULL) return FALSE; err_reason = PKCS12_parse(p12, "", &key, &cert, NULL); if (err_reason == PKCS12_R_MAC_VERIFY_FAILURE){ ret = FALSE; } if (cert){ X509_free(cert); cert = NULL; } if (key){ EVP_PKEY_free(key); key = NULL; } ERR_clear_error(); PKCS12_free(p12); return ret; }
pki_pkcs12::pki_pkcs12(const QString fname, pem_password_cb *cb) :pki_base(fname) { FILE *fp; char pass[MAX_PASS_LENGTH]; EVP_PKEY *mykey = NULL; X509 *mycert = NULL; key=NULL; cert=NULL; passcb = cb; class_name="pki_pkcs12"; certstack = sk_X509_new_null(); pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the PKCS#12 file.") + "\n'" + fname + "'"); fp = fopen(QString2filename(fname), "rb"); if (fp) { PKCS12 *pkcs12 = d2i_PKCS12_fp(fp, NULL); fclose(fp); if (ign_openssl_error()) { if (pkcs12) PKCS12_free(pkcs12); throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname)); } if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0)) pass[0] = '\0'; else if (passcb(pass, MAX_PASS_LENGTH, 0, &p) < 0) { /* cancel pressed */ PKCS12_free(pkcs12); throw errorEx("",""); } PKCS12_parse(pkcs12, pass, &mykey, &mycert, &certstack); int error = ERR_peek_error(); if (ERR_GET_REASON(error) == PKCS12_R_MAC_VERIFY_FAILURE) { ign_openssl_error(); PKCS12_free(pkcs12); throw errorEx(getClassName(), tr("The supplied password was wrong (%1)").arg(ERR_reason_error_string(error))); } ign_openssl_error(); if (mycert) { if (mycert->aux && mycert->aux->alias) { alias = asn1ToQString(mycert->aux->alias); alias = QString::fromUtf8(alias.toAscii()); } cert = new pki_x509(mycert); if (alias.isEmpty()) { cert->autoIntName(); } else { cert->setIntName(alias); } alias = cert->getIntName(); } if (mykey) { key = new pki_evp(mykey); key->setIntName(alias + "_key"); key->bogusEncryptKey(); } PKCS12_free(pkcs12); } else fopen_error(fname); }
int useCertFile(SSL_CTX* ctx, const char* path, const char* passphrase, const char* cacertfile) { FILE *p12_file; PKCS12 *p12_cert = NULL; EVP_PKEY *pkey; X509 *x509_cert; p12_file = fopen(path, "r"); if (!p12_file) { timestamp_f(stderr); perror(path); return -1; } d2i_PKCS12_fp(p12_file, &p12_cert); fclose(p12_file); if (!PKCS12_parse(p12_cert, passphrase, &pkey, &x509_cert, NULL)) { int error = ERR_get_error(); timestamp_f(stderr); fprintf(stderr, "failed to parse p12 file; error %d\n", error); PKCS12_free(p12_cert); return -1; } PKCS12_free(p12_cert); if (!SSL_CTX_use_certificate(ctx, x509_cert)) { int error = ERR_get_error(); timestamp_f(stderr); fprintf(stderr, "failed to set cert for SSL context; error %d\n", error); X509_free(x509_cert); EVP_PKEY_free(pkey); return -1; } X509_free(x509_cert); if (!SSL_CTX_use_PrivateKey(ctx, pkey)) { int error = ERR_get_error(); timestamp_f(stderr); fprintf(stderr, "failed to set private key for SSL context; error %d\n", error); EVP_PKEY_free(pkey); return -1; } EVP_PKEY_free(pkey); if (cacertfile && *cacertfile && !SSL_CTX_load_verify_locations(ctx, cacertfile, NULL)) { timestamp_f(stderr); fprintf(stderr, "failed to load root cert for verification from %s\n", cacertfile); return -1; } return 0; }
static int _parcPkcs12KeyStore_ParseFile(PARCPkcs12KeyStore *keystore, const char *filename, const char *password) { parcSecurity_AssertIsInitialized(); FILE *fp = fopen(filename, "rb"); assertNotNull(fp, "Error opening %s: %s", filename, strerror(errno)); if (fp == NULL) { return -1; } PKCS12 *p12Keystore = NULL; d2i_PKCS12_fp(fp, &p12Keystore); fclose(fp); int success = PKCS12_parse(p12Keystore, password, &keystore->private_key, &keystore->x509_cert, NULL); PKCS12_free(p12Keystore); if (!success) { unsigned long errcode; while ((errcode = ERR_get_error()) != 0) { fprintf(stderr, "openssl error: %s\n", ERR_error_string(errcode, NULL)); } return -1; } keystore->public_key = X509_get_pubkey(keystore->x509_cert); return 0; }
PKCS12 * PKCS12_init(int mode) { PKCS12 *pkcs12; if (!(pkcs12 = PKCS12_new())) { PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); return NULL; } ASN1_INTEGER_set(pkcs12->version, 3); pkcs12->authsafes->type = OBJ_nid2obj(mode); switch (mode) { case NID_pkcs7_data: if (!(pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new())) { PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); goto err; } break; default: PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE); goto err; } return pkcs12; err: if (pkcs12 != NULL) PKCS12_free(pkcs12); return NULL; }
/** * Releases a shared PKCS12 object. If nobody else is using the object then * it's freed. */ static void pkcs12_release(SharedPKCS12 *sharedP12) { if (--sharedP12->refCount == 0) { // We're the last reference holder to release the P12 PKCS12_free(sharedP12->data); free(sharedP12); } }
void pki_pkcs12::writePKCS12(const QString fname) { Passwd pass; pass_info p(XCA_TITLE, tr("Please enter the password to encrypt the PKCS#12 file")); if (cert == NULL || key == NULL) { my_error(tr("No key or no Cert and no pkcs12")); } FILE *fp = fopen(QString2filename(fname), "wb"); if (fp != NULL) { if (PwDialog::execute(&p, &pass, true) != 1) { fclose(fp); return; } PKCS12 *pkcs12 = PKCS12_create(pass.data(), getIntName().toUtf8().data(), key->decryptKey(), cert->getCert(), certstack, 0, 0, 0, 0, 0); i2d_PKCS12_fp(fp, pkcs12); fclose (fp); openssl_error(); PKCS12_free(pkcs12); } else fopen_error(fname); }
static LUA_FUNCTION(openssl_pkcs12_export) { X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509"); EVP_PKEY *priv_key = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); char * pass = (char*)luaL_checkstring(L, 3); int top = lua_gettop(L); BIO * bio_out = NULL; PKCS12 * p12 = NULL; const char * friendly_name = NULL; STACK_OF(X509) *ca = NULL; int ret = 0; luaL_argcheck(L, openssl_pkey_is_private(priv_key), 2, "must be private key"); if (top > 3) { if (lua_isstring(L, 4)) friendly_name = lua_tostring(L, 4); else if (lua_isuserdata(L, 4)) ca = CHECK_OBJECT(4, STACK_OF(X509), "openssl.stack_of_x509"); else luaL_argerror(L, 4, "must be string as friendly_name or openssl.stack_of_x509 object as cacets"); if (top > 4) ca = CHECK_OBJECT(5, STACK_OF(X509), "openssl.stack_of_x509"); } if (cert && !X509_check_private_key(cert, priv_key)) { luaL_error(L, "private key does not correspond to cert"); } /* end parse extra config */ /*PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype);*/ p12 = PKCS12_create(pass, (char*)friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0); if (!p12) luaL_error(L, "PKCS12_careate failed,pleases get more error info"); bio_out = BIO_new(BIO_s_mem()); if (i2d_PKCS12_bio(bio_out, p12)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); lua_pushlstring(L, bio_buf->data, bio_buf->length); ret = 1; } BIO_free(bio_out); PKCS12_free(p12); return ret; }
int __fastcall util_to_p12(struct util_cert cert, char *password, char** data) { PKCS12 *p12; int len; p12 = PKCS12_create(password, "Certificate", cert.pkey, cert.x509, NULL, 0, 0, 0, 0, 0); *data = NULL; len = i2d_PKCS12(p12, (unsigned char**)data); PKCS12_free(p12); return len; }
void SafetPKCS12Private::init( const QByteArray &data, const QByteArray &pin ) { OpenSSL_add_all_algorithms(); qDebug("... SafetPKCS12Private::init ... 1"); BIO *bio = BIO_new_mem_buf( const_cast<char*>(data.constData()), data.size() ); if( !bio ){ return setLastError(); /* qDebug("!bio"); qDebug(qPrintable(errorString)); SafetYAWL::streamlog << SafetLog::Error << QObject::tr("Error al inicializar objeto PKCS12: BIO no valida"); return; */ } PKCS12 *p12 = d2i_PKCS12_bio( bio, NULL ); BIO_free( bio ); if( !p12 ){ return setLastError(); /* qDebug("!p12"); qDebug(qPrintable(errorString)); SafetYAWL::streamlog << SafetLog::Debug << errorString; SafetYAWL::streamlog << SafetLog::Error << QObject::tr("Error al inicializar objeto PKCS12: PKCS12 no valida"); return; */ } X509 *c = NULL; EVP_PKEY *k = NULL; int ret = PKCS12_parse( p12, pin.constData(), &k, &c, NULL ); PKCS12_free( p12 ); if( !ret ){ return setLastError(); /* setLastError(); qDebug("!ret"); qDebug(qPrintable(errorString)); SafetYAWL::streamlog << SafetLog::Error << QObject::tr("Error al inicializar objeto PKCS12: EVP_PKEY no valida"); return; */ } SafetYAWL::streamlog << SafetLog::Debug << QObject::tr("Analizada correctamente la estructura PKCS12"); cert = SafetPKCS12::fromX509( c ); key = SafetPKCS12::keyFromEVP( k ); X509_free( c ); EVP_PKEY_free( k ); qDebug("... SafetPKCS12Private::init ... 2"); SafetYAWL::streamlog << SafetLog::Action << QObject::tr("Inicializado objeto SafetPKCS12 correctamente!"); }
int __fastcall util_from_p12(char* data, int datalen, char* password, struct util_cert* cert) { int r = 0; PKCS12 *p12 = NULL; if (data == NULL || datalen ==0) return 0; cert->x509 = NULL; cert->pkey = NULL; p12 = d2i_PKCS12(&p12, (const unsigned char**)&data, datalen); r = PKCS12_parse(p12, password, &(cert->pkey), &(cert->x509), NULL); PKCS12_free(p12); return r; }
void ne_ssl_clicert_free(ne_ssl_client_cert *cc) { if (cc->p12) PKCS12_free(cc->p12); if (cc->decrypted) { if (cc->cert.identity) ne_free(cc->cert.identity); EVP_PKEY_free(cc->pkey); X509_free(cc->cert.subject); } if (cc->friendly_name) ne_free(cc->friendly_name); ne_free(cc); }
int sign_with_rsa_sha256(const char *input, const char *private_key, unsigned char *buffer_out, int *buffer_out_len) { FILE *fp; EVP_PKEY *pkey = 0; EVP_MD_CTX *ctx = 0; const EVP_MD *sha256_md = 0; unsigned int s = 0; PKCS12 *p12 = 0; X509 *cert = 0; OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); ctx = EVP_MD_CTX_create(); EVP_MD_CTX_init(ctx); sha256_md = EVP_sha256(); EVP_SignInit(ctx, sha256_md); EVP_SignUpdate(ctx, input, strlen(input)); ERR_load_crypto_strings(); if (!(fp = fopen(private_key, "rb"))) { perror("Error opening file with private key"); return -1; } p12 = d2i_PKCS12_fp(fp, NULL); fclose (fp); if (!p12) { perror("Error reading PKCS#12 file"); return -1; } if (!PKCS12_parse(p12, "notasecret", &pkey, &cert, NULL)) { perror("Error parsing PKCS#12 file"); return -1; } s = EVP_PKEY_size(pkey); EVP_SignFinal(ctx, buffer_out, &s, pkey); *buffer_out_len = s; PKCS12_free(p12); EVP_MD_CTX_destroy(ctx); X509_free(cert); EVP_cleanup(); return 0; }
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); } SSLeay_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)); } fclose(fp); return 0; }
Pkcs12::~Pkcs12() { if(this->privKey != NULL) { delete this->privKey; } if(this->cert != NULL) { delete this->cert; } for(unsigned int i = 0 ; i < this->ca.size() ; i++) { delete ca.at(i); } PKCS12_free(this->pkcs12); }
/** * Parses a P12 file and returns a parsed representation of the file, with * a reference count so it can be shared by multiple tokens. */ static SharedPKCS12 *pkcs12_parse(const char *p12Data, int p12Length) { const unsigned char *temp = (const unsigned char*)p12Data; PKCS12 *data; // Parse P12 data data = d2i_PKCS12(NULL, &temp, p12Length); if (!data) return NULL; // Create a reference counted object SharedPKCS12 *sharedP12 = malloc(sizeof(SharedPKCS12)); if (!sharedP12) { PKCS12_free(data); return NULL; } sharedP12->refCount = 1; sharedP12->data = data; return sharedP12; }
static LUA_FUNCTION(openssl_pkcs12_read) { PKCS12 * p12 = NULL; EVP_PKEY * pkey = NULL; X509 * cert = NULL; STACK_OF(X509) * ca = NULL; int ret = 0; int base64 = 0; int olb64 = 0; BIO * b64 = NULL; BIO * bio_in = load_bio_object(L, 1); const char *pass = luaL_checkstring(L, 2); if (!lua_isnoneornil(L, 3)) base64 = auxiliar_checkboolean(L, 3); if (!lua_isnoneornil(L, 4)) olb64 = auxiliar_checkboolean(L, 4); if (base64) { if ((b64 = BIO_new(BIO_f_base64())) == NULL) return 0; if (olb64) BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bio_in = BIO_push(b64, bio_in); } if (d2i_PKCS12_bio(bio_in, &p12) && PKCS12_parse(p12, pass, &pkey, &cert, &ca)) { lua_newtable(L); AUXILIAR_SETOBJECT(L, cert, "openssl.x509" , -1, "cert"); AUXILIAR_SETOBJECT(L, pkey, "openssl.evp_pkey" , -1, "pkey"); AUXILIAR_SETOBJECT(L, ca, "openssl.stack_of_x509" , -1, "extracerts"); ret = 1; } if (b64) BIO_free(b64); BIO_free(bio_in); PKCS12_free(p12); return ret; }
static int loadPkcs12( const char *fn, const char* pw) { /* you are lost in a maze of twisty crypto algorithms... */ PKCS12 *p12; X509 *x509; EVP_PKEY *pkey; FILE *fp; int ret; fp = fopen(fn, "r"); if (fp == NULL) { printf("Could not open file `%s\n", fn); return -1; } p12 = d2i_PKCS12_fp(fp, NULL); fclose(fp); if (p12 == NULL) { printf("Could not read certificate from file `%s\n",fn); return -1; } /* we need some more for the P12 decoding */ OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); ERR_load_crypto_strings(); ret = PKCS12_parse(p12, getenv(pw),&pkey, &x509, NULL); saveCertificateHome(x509, true); savePKeyHome( x509, pkey); PKCS12_free(p12); if (ret != 1) { printf("Error parsing certificate (incorrect password?): %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } return 0; }
void pki_pkcs12::writePKCS12(const QString fname) { char pass[MAX_PASS_LENGTH]; pass_info p(XCA_TITLE, tr("Please enter the password to encrypt the PKCS#12 file")); if (cert == NULL || key == NULL) { my_error(tr("No key or no Cert and no pkcs12")); } FILE *fp = fopen(QString2filename(fname), "wb"); if (fp != NULL) { passcb(pass, MAX_PASS_LENGTH, 0, &p); PKCS12 *pkcs12 = PKCS12_create(pass, getIntName().toUtf8().data(), key->decryptKey(), cert->getCert(), certstack, 0, 0, 0, 0, 0); i2d_PKCS12_fp(fp, pkcs12); openssl_error(); fclose (fp); PKCS12_free(pkcs12); } else fopen_error(fname); }
static X509 *_load_certificate_from_mem(int format, uint8_t *buffer, uint32_t length, char *password) { X509 *x509 = NULL; BIO *mem = NULL; mem = BIO_new_mem_buf(buffer, length); if (mem != NULL) { switch (format) { case 0 : x509 = d2i_X509_bio(mem, NULL); break; case 1 : x509 = PEM_read_bio_X509(mem, NULL, NULL, NULL); break; case 2 : { PKCS12 *p12 = d2i_PKCS12_bio(mem, NULL); PKCS12_parse(p12, password, NULL, &x509, NULL); PKCS12_free(p12); } break; } BIO_free(mem); } else { DEBUG_ERR_MSG("X509_LOOKUP_load_file failed"); } return x509; }
int main(int argc, char **argv) { FILE *fp; EVP_PKEY *pkey; X509 *cert; PKCS12 *p12; if (argc != 5) { fprintf(stderr, "Usage: pkwrite infile password name p12file\n"); exit(1); } SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); if (!(fp = fopen(argv[1], "r"))) { fprintf(stderr, "Error opening file %s\n", argv[1]); exit(1); } cert = PEM_read_X509(fp, NULL, NULL, NULL); rewind(fp); pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); fclose(fp); p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0); if(!p12) { fprintf(stderr, "Error creating PKCS#12 structure\n"); ERR_print_errors_fp(stderr); exit(1); } if (!(fp = fopen(argv[4], "wb"))) { fprintf(stderr, "Error opening file %s\n", argv[1]); ERR_print_errors_fp(stderr); exit(1); } i2d_PKCS12_fp(fp, p12); PKCS12_free(p12); fclose(fp); return 0; }
void openssl_pkcs12_cert() { FILE *tmpfile; PKCS12 *pkcs12s; EVP_PKEY *certprk; X509 *cscert, *cacert; STACK_OF(X509) * cacerts; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); certprk = EVP_PKEY_new(); tmpfile = fopen(PKEYF, "r"); certprk = PEM_read_PrivateKey(tmpfile, NULL, NULL, NULL); fclose(tmpfile); tmpfile = fopen(PCERTF, "r"); cscert = PEM_read_X509(tmpfile, NULL, NULL, NULL); fclose(tmpfile); tmpfile = fopen(RCERTF, "r"); cacert = PEM_read_X509(tmpfile, NULL, NULL, NULL); fclose(tmpfile); pkcs12s = PKCS12_new(); cacerts = sk_X509_new_null(); sk_X509_push(cacerts, cacert); pkcs12s = PKCS12_create("beike2012", "mypkcs12", certprk, cscert, cacerts, 0, 0, 0, 0, 0); tmpfile = fopen(PKCS12F, "w"); if (i2d_PKCS12_fp(tmpfile, pkcs12s) <= 0) openssl_error_show("i2d_PKCS12_fp", 1); fclose(tmpfile); sk_X509_free(cacerts); PKCS12_free(pkcs12s); }
/*============================================================================ * OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile( OpcUa_StringA a_privateKeyFile, OpcUa_P_FileFormat a_fileFormat, OpcUa_StringA a_password, /* optional: just needed encrypted PEM */ OpcUa_ByteString* a_pPrivateKey) { BIO* pPrivateKeyFile = OpcUa_Null; RSA* pRsaPrivateKey = OpcUa_Null; EVP_PKEY* pEvpKey = OpcUa_Null; unsigned char* pData; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_LoadPrivateKeyFromFile"); /* check parameters */ OpcUa_ReturnErrorIfArgumentNull(a_privateKeyFile); OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey); if(a_fileFormat == OpcUa_Crypto_Encoding_Invalid) { return OpcUa_BadInvalidArgument; } OpcUa_ReferenceParameter(a_password); /* open file */ pPrivateKeyFile = BIO_new_file((const char*)a_privateKeyFile, "rb"); OpcUa_ReturnErrorIfArgumentNull(pPrivateKeyFile); /* read and convert file */ switch(a_fileFormat) { case OpcUa_Crypto_Encoding_PEM: { /* read from file */ pEvpKey = PEM_read_bio_PrivateKey( pPrivateKeyFile, /* file */ NULL, /* key struct */ 0, /* password callback */ a_password); /* default passphrase or arbitrary handle */ OpcUa_GotoErrorIfNull(pEvpKey, OpcUa_Bad); break; } case OpcUa_Crypto_Encoding_PKCS12: { int iResult = 0; /* read from file. */ PKCS12* pPkcs12 = d2i_PKCS12_bio(pPrivateKeyFile, NULL); if (pPkcs12 == 0) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } /* parse the certificate. */ iResult = PKCS12_parse(pPkcs12, a_password, &pEvpKey, NULL, NULL); if (iResult == 0) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } /* free certificate. */ PKCS12_free(pPkcs12); pPkcs12 = NULL; break; } case OpcUa_Crypto_Encoding_DER: default: { uStatus = OpcUa_BadNotSupported; OpcUa_GotoError; } } /* convert to intermediary openssl struct */ pRsaPrivateKey = EVP_PKEY_get1_RSA(pEvpKey); EVP_PKEY_free(pEvpKey); OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad); /* get required length */ a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, OpcUa_Null); OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad); /* allocate target buffer */ a_pPrivateKey->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pPrivateKey->Length); OpcUa_GotoErrorIfAllocFailed(a_pPrivateKey->Data); /* do real conversion */ pData = a_pPrivateKey->Data; a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, &pData); OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad); RSA_free(pRsaPrivateKey); BIO_free(pPrivateKeyFile); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pEvpKey) { EVP_PKEY_free(pEvpKey); } if(a_pPrivateKey != OpcUa_Null) { if(a_pPrivateKey->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pPrivateKey->Data); a_pPrivateKey->Data = OpcUa_Null; a_pPrivateKey->Length = -1; } } if(pPrivateKeyFile != NULL) { BIO_free(pPrivateKeyFile); } if(pRsaPrivateKey != NULL) { RSA_free(pRsaPrivateKey); } OpcUa_FinishErrorHandling; }
static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12) { EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *ca; int ret = 0; char *pass; pass = vpninfo->cert_password; vpninfo->cert_password = NULL; retrypass: /* We do this every time round the loop, to work around a bug in OpenSSL < 1.0.0-beta2 -- where the stack at *ca will be freed when PKCS12_parse() returns an error, but *ca is left pointing to the freed memory. */ ca = NULL; if (!pass && request_passphrase(vpninfo, "openconnect_pkcs12", &pass, _("Enter PKCS#12 pass phrase:")) < 0) { PKCS12_free(p12); return -EINVAL; } if (!PKCS12_parse(p12, pass, &pkey, &cert, &ca)) { unsigned long err = ERR_peek_error(); openconnect_report_ssl_errors(vpninfo); if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 && ERR_GET_FUNC(err) == PKCS12_F_PKCS12_PARSE && ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) { vpn_progress(vpninfo, PRG_ERR, _("Parse PKCS#12 failed (wrong passphrase?)\n")); free(pass); pass = NULL; goto retrypass; } vpn_progress(vpninfo, PRG_ERR, _("Parse PKCS#12 failed (see above errors)\n")); PKCS12_free(p12); free(pass); return -EINVAL; } free(pass); if (cert) { char buf[200]; vpninfo->cert_x509 = cert; SSL_CTX_use_certificate(vpninfo->https_ctx, cert); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); vpn_progress(vpninfo, PRG_INFO, _("Using client certificate '%s'\n"), buf); } else { vpn_progress(vpninfo, PRG_ERR, _("PKCS#12 contained no certificate!")); ret = -EINVAL; } if (pkey) { SSL_CTX_use_PrivateKey(vpninfo->https_ctx, pkey); EVP_PKEY_free(pkey); } else { vpn_progress(vpninfo, PRG_ERR, _("PKCS#12 contained no private key!")); ret = -EINVAL; } /* Only include supporting certificates which are actually necessary */ if (ca) { int i; next: for (i = 0; i < sk_X509_num(ca); i++) { X509 *cert2 = sk_X509_value(ca, i); if (X509_check_issued(cert2, cert) == X509_V_OK) { char buf[200]; if (cert2 == cert) break; if (X509_check_issued(cert2, cert2) == X509_V_OK) break; X509_NAME_oneline(X509_get_subject_name(cert2), buf, sizeof(buf)); vpn_progress(vpninfo, PRG_DEBUG, _("Extra cert from PKCS#12: '%s'\n"), buf); CRYPTO_add(&cert2->references, 1, CRYPTO_LOCK_X509); SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert2); cert = cert2; goto next; } } sk_X509_pop_free(ca, X509_free); } PKCS12_free(p12); return ret; }
DVT_STATUS CERTIFICATE_FILE_CLASS::importPkcs12(const char* filename, bool certificatesOnly, const char* password) // DESCRIPTION : Import certificates from a PKCS#12 formated file. // PRECONDITIONS : // POSTCONDITIONS : // EXCEPTIONS : // NOTES : Returns MSG_OK, MSG_ERROR, MSG_FILE_NOT_EXIST, MSG_NO_VALUE, MSG_INVALID_PASSWORD //<<=========================================================================== { DVT_STATUS status = MSG_ERROR; BIO* bio_ptr = NULL; PKCS12 *p12_ptr = NULL; EVP_PKEY *pkey_ptr = NULL; X509 *cert_ptr = NULL; STACK_OF(X509) *ca_ptr = NULL; const char* password_ptr = NULL; int count = 0; // clear the error queue ERR_clear_error(); // open the file bio_ptr = BIO_new(BIO_s_file_internal()); if (bio_ptr == NULL) { openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "setting up to read PKCS#12 file"); status = MSG_ERROR; goto end; } if (BIO_read_filename(bio_ptr, filename) <= 0) { unsigned long err; err = ERR_peek_error(); if ((ERR_GET_LIB(err) == ERR_LIB_SYS) && (ERR_GET_REASON(err) == ERROR_FILE_NOT_FOUND)) { // file does not exist ERR_clear_error(); // eat any errors status = MSG_FILE_NOT_EXIST; } else { openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "opening PKCS#12 file for reading"); status = MSG_ERROR; } goto end; } // read the file p12_ptr = d2i_PKCS12_bio(bio_ptr, NULL); if (!p12_ptr) { openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "reading PKCS#12 file"); status = MSG_ERROR; goto end; } // see if we have a password that will work if (PKCS12_verify_mac(p12_ptr, NULL, 0)) { password_ptr = NULL; } else if(PKCS12_verify_mac(p12_ptr, "", 0)) { password_ptr = ""; } else if(PKCS12_verify_mac(p12_ptr, password, strlen(password))) { password_ptr = password; } else { status = MSG_INVALID_PASSWORD; goto end; } // parse the data if (!PKCS12_parse(p12_ptr, password_ptr, &pkey_ptr, &cert_ptr, &ca_ptr)) { openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "parsing PKCS#12 file"); status = MSG_ERROR; ca_ptr = NULL; // this is freed by PKCS12_parse(), but not set to NULL goto end; } if ((pkey_ptr != NULL) && !certificatesOnly) { // save the private key if (!push(pkey_ptr)) { status = MSG_ERROR; goto end; } count++; } if (cert_ptr != NULL) { // save the certificate if (!push(cert_ptr)) { status = MSG_ERROR; goto end; } count++; } if ((ca_ptr != NULL) && (sk_X509_num(ca_ptr) > 0)) { X509* x509_ptr; // save each of the certificates while ((x509_ptr = sk_X509_shift(ca_ptr)) != NULL) { if (!push(x509_ptr)) { status = MSG_ERROR; goto end; } count++; } } if (count == 0) { status = MSG_NO_VALUE; } else { status = MSG_OK; } end: if (bio_ptr != NULL) BIO_free(bio_ptr); if (p12_ptr != NULL) PKCS12_free(p12_ptr); if (pkey_ptr != NULL) EVP_PKEY_free(pkey_ptr); if (cert_ptr != NULL) X509_free(cert_ptr); if (ca_ptr != NULL) sk_X509_pop_free(ca_ptr, X509_free); return status; }
/* * PKCS#12 decoder. It operates by decoding all of the blob content, * extracting all the interesting data from it and storing them internally, * then serving them one piece at a time. */ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name, const char *pem_header, const unsigned char *blob, size_t len, void **pctx, int *matchcount, const UI_METHOD *ui_method, void *ui_data) { OSSL_STORE_INFO *store_info = NULL; STACK_OF(OSSL_STORE_INFO) *ctx = *pctx; if (ctx == NULL) { /* Initial parsing */ PKCS12 *p12; int ok = 0; if (pem_name != NULL) /* No match, there is no PEM PKCS12 tag */ return NULL; if ((p12 = d2i_PKCS12(NULL, &blob, len)) != NULL) { char *pass = NULL; char tpass[PEM_BUFSIZE]; EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *chain = NULL; *matchcount = 1; if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) { pass = ""; } else { if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE, "PKCS12 import password", ui_data)) == NULL) { OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR); goto p12_end; } if (!PKCS12_verify_mac(p12, pass, strlen(pass))) { OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC); goto p12_end; } } if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) { OSSL_STORE_INFO *osi_pkey = NULL; OSSL_STORE_INFO *osi_cert = NULL; OSSL_STORE_INFO *osi_ca = NULL; if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL && (osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL && sk_OSSL_STORE_INFO_push(ctx, osi_pkey) != 0 && (osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL && sk_OSSL_STORE_INFO_push(ctx, osi_cert) != 0) { ok = 1; osi_pkey = NULL; osi_cert = NULL; while(sk_X509_num(chain) > 0) { X509 *ca = sk_X509_value(chain, 0); if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) == NULL || sk_OSSL_STORE_INFO_push(ctx, osi_ca) == 0) { ok = 0; break; } osi_ca = NULL; (void)sk_X509_shift(chain); } } if (!ok) { OSSL_STORE_INFO_free(osi_ca); OSSL_STORE_INFO_free(osi_cert); OSSL_STORE_INFO_free(osi_pkey); sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free); EVP_PKEY_free(pkey); X509_free(cert); sk_X509_pop_free(chain, X509_free); ctx = NULL; } *pctx = ctx; } } p12_end: PKCS12_free(p12); if (!ok) return NULL; } if (ctx != NULL) { *matchcount = 1; store_info = sk_OSSL_STORE_INFO_shift(ctx); } return store_info; }
static TokenError saveKeys(const CertReq *reqs, const char *hostname, const char *password, FILE *file) { TokenError error = TokenError_Unknown; PKCS12 *p12 = NULL; // Add PKCS7 safes with the keys STACK_OF(PKCS7) *authsafes = NULL; uint32_t localKeyId = 0; size_t error_count = 0; while (reqs) { STACK_OF(PKCS12_SAFEBAG) *bags = NULL; X509 *cert = NULL; ASN1_OBJECT *objOwningHost = NULL; uint32_t keyid = htonl(localKeyId++); bool success = false; // Add private key PKCS12_SAFEBAG *bag = PKCS12_add_key(&bags, reqs->privkey, opensslKeyUsages[reqs->pkcs10->keyUsage], ENC_ITER, ENC_NID, (char*)password); if (!bag) goto loop_end; // Add name and localKeyId to the key bag // TODO extract name from subject DN char *name = "names are not implemented yet"; if (!X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, MBSTRING_UTF8, (unsigned char*)name, strlen(name)) || !PKCS12_add_localkeyid(bag, (unsigned char*)&keyid, sizeof(keyid))) goto loop_end; // Add a certificate so we can find the key by the subject name cert = X509_REQ_to_X509(reqs->x509, 3650, reqs->privkey); if (!cert || !X509_keyid_set1(cert, (unsigned char*)&keyid, sizeof(keyid))) goto loop_end; if (!X509_add_ext(cert, makeKeyUsageExt(reqs->pkcs10->keyUsage), -1)) goto loop_end; if (!PKCS12_add_cert(&bags, cert)) goto loop_end; // Add hostname (FriBID extension) so we can do same-origin checks // TODO maybe we should use document.domain instead of document.location.hostname? objOwningHost = OBJ_txt2obj(OID_OWNING_HOST, 1); if (!objOwningHost) goto loop_end; bag = sk_PKCS12_SAFEBAG_value(bags, sk_PKCS12_SAFEBAG_num(bags)-1); if (!X509at_add1_attr_by_OBJ(&bag->attrib, objOwningHost, MBSTRING_UTF8, (unsigned char*)hostname, strlen(hostname))) goto loop_end; // Add a new authsafe if (!PKCS12_add_safe(&authsafes, bags, -1, 0, NULL)) goto loop_end; // Success! success = true; loop_end: if (!success) { error_count--; certutil_updateErrorString(); } ASN1_OBJECT_free(objOwningHost); X509_free(cert); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); reqs = reqs->next; } if (error_count != 0) goto end; // Create the PKCS12 wrapper p12 = PKCS12_add_safes(authsafes, 0); if (!p12) { certutil_updateErrorString(); goto end; } PKCS12_set_mac(p12, (char*)password, -1, NULL, 0, MAC_ITER, NULL); // Save file if (i2d_PKCS12_fp(file, p12)) { error = TokenError_Success; } end: sk_PKCS7_pop_free(authsafes, PKCS7_free); PKCS12_free(p12); return error; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char *infile=NULL, *outfile=NULL, *keyname = NULL; char *certfile=NULL; BIO *in=NULL, *out = NULL; char **args; char *name = NULL; char *csp_name = NULL; PKCS12 *p12 = NULL; char pass[50], macpass[50]; int export_cert = 0; int options = 0; int chain = 0; int badarg = 0; int iter = PKCS12_DEFAULT_ITER; int maciter = PKCS12_DEFAULT_ITER; int twopass = 0; int keytype = 0; int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; int ret = 1; int macver = 1; int noprompt = 0; STACK *canames = NULL; char *cpass = NULL, *mpass = NULL; char *passargin = NULL, *passargout = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL; char *inrand = NULL; char *CApath = NULL, *CAfile = NULL; char *engine=NULL; apps_startup(); enc = EVP_des_ede3_cbc(); if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; args = argv + 1; while (*args) { if (*args[0] == '-') { if (!strcmp (*args, "-nokeys")) options |= NOKEYS; else if (!strcmp (*args, "-keyex")) keytype = KEY_EX; else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG; else if (!strcmp (*args, "-nocerts")) options |= NOCERTS; else if (!strcmp (*args, "-clcerts")) options |= CLCERTS; else if (!strcmp (*args, "-cacerts")) options |= CACERTS; else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS); else if (!strcmp (*args, "-info")) options |= INFO; else if (!strcmp (*args, "-chain")) chain = 1; else if (!strcmp (*args, "-twopass")) twopass = 1; else if (!strcmp (*args, "-nomacver")) macver = 0; else if (!strcmp (*args, "-descert")) cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; else if (!strcmp (*args, "-export")) export_cert = 1; else if (!strcmp (*args, "-des")) enc=EVP_des_cbc(); #ifndef OPENSSL_NO_IDEA else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc(); #endif else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc(); #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc(); #endif else if (!strcmp (*args, "-noiter")) iter = 1; else if (!strcmp (*args, "-maciter")) maciter = PKCS12_DEFAULT_ITER; else if (!strcmp (*args, "-nomaciter")) maciter = 1; else if (!strcmp (*args, "-nodes")) enc=NULL; else if (!strcmp (*args, "-certpbe")) { if (args[1]) { args++; cert_pbe=OBJ_txt2nid(*args); if(cert_pbe == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-keypbe")) { if (args[1]) { args++; key_pbe=OBJ_txt2nid(*args); if(key_pbe == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-rand")) { if (args[1]) { args++; inrand = *args; } else badarg = 1; } else if (!strcmp (*args, "-inkey")) { if (args[1]) { args++; keyname = *args; } else badarg = 1; } else if (!strcmp (*args, "-certfile")) { if (args[1]) { args++; certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-name")) { if (args[1]) { args++; name = *args; } else badarg = 1; } else if (!strcmp (*args, "-CSP")) { if (args[1]) { args++; csp_name = *args; } else badarg = 1; } else if (!strcmp (*args, "-caname")) { if (args[1]) { args++; if (!canames) canames = sk_new_null(); sk_push(canames, *args); } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp(*args,"-passin")) { if (args[1]) { args++; passargin = *args; } else badarg = 1; } else if (!strcmp(*args,"-passout")) { if (args[1]) { args++; passargout = *args; } else badarg = 1; } else if (!strcmp (*args, "-password")) { if (args[1]) { args++; passarg = *args; noprompt = 1; } else badarg = 1; } else if (!strcmp(*args,"-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp(*args,"-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; } else badarg = 1; } else badarg = 1; args++; } if (badarg) { BIO_printf (bio_err, "Usage: pkcs12 [options]\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-export output PKCS12 file\n"); BIO_printf (bio_err, "-chain add certificate chain\n"); BIO_printf (bio_err, "-inkey file private key if not infile\n"); BIO_printf (bio_err, "-certfile f add all certs in f\n"); BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n"); BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n"); BIO_printf (bio_err, "-name \"name\" use name as friendly name\n"); BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); BIO_printf (bio_err, "-in infile input filename\n"); BIO_printf (bio_err, "-out outfile output filename\n"); BIO_printf (bio_err, "-noout don't output anything, just verify.\n"); BIO_printf (bio_err, "-nomacver don't verify MAC.\n"); BIO_printf (bio_err, "-nocerts don't output certificates.\n"); BIO_printf (bio_err, "-clcerts only output client certificates.\n"); BIO_printf (bio_err, "-cacerts only output CA certificates.\n"); BIO_printf (bio_err, "-nokeys don't output private keys.\n"); BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n"); BIO_printf (bio_err, "-des encrypt private keys with DES\n"); BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n"); #ifndef OPENSSL_NO_IDEA BIO_printf (bio_err, "-idea encrypt private keys with idea\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif BIO_printf (bio_err, "-nodes don't encrypt private keys\n"); BIO_printf (bio_err, "-noiter don't use encryption iteration\n"); BIO_printf (bio_err, "-maciter use MAC iteration\n"); BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n"); BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); BIO_printf (bio_err, "-keyex set MS key exchange type\n"); BIO_printf (bio_err, "-keysig set MS key signature type\n"); BIO_printf (bio_err, "-password p set import/export password source\n"); BIO_printf (bio_err, "-passin p input file pass phrase source\n"); BIO_printf (bio_err, "-passout p output file pass phrase source\n"); BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); goto end; } e = setup_engine(bio_err, engine, 0); if(passarg) { if(export_cert) passargout = passarg; else passargin = passarg; } if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if(!cpass) { if(export_cert) cpass = passout; else cpass = passin; } if(cpass) { mpass = cpass; noprompt = 1; } else { cpass = pass; mpass = macpass; } if(export_cert || inrand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ERR_load_crypto_strings(); #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read files"); #endif if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE); else in = BIO_new_file(infile, "rb"); if (!in) { BIO_printf(bio_err, "Error opening input file %s\n", infile ? infile : "<stdin>"); perror (infile); goto end; } #if 0 if (certfile) { if(!(certsin = BIO_new_file(certfile, "r"))) { BIO_printf(bio_err, "Can't open certificate file %s\n", certfile); perror (certfile); goto end; } } if (keyname) { if(!(inkey = BIO_new_file(keyname, "r"))) { BIO_printf(bio_err, "Can't key certificate file %s\n", keyname); perror (keyname); goto end; } } #endif #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("write files"); #endif if (!outfile) { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else out = BIO_new_file(outfile, "wb"); if (!out) { BIO_printf(bio_err, "Error opening output file %s\n", outfile ? outfile : "<stdout>"); perror (outfile); goto end; } if (twopass) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read MAC password"); #endif if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n"); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif } if (export_cert) { EVP_PKEY *key = NULL; STACK_OF(PKCS12_SAFEBAG) *bags = NULL; STACK_OF(PKCS7) *safes = NULL; PKCS12_SAFEBAG *bag = NULL; PKCS8_PRIV_KEY_INFO *p8 = NULL; PKCS7 *authsafe = NULL; X509 *ucert = NULL; STACK_OF(X509) *certs=NULL; char *catmp = NULL; int i; unsigned char keyid[EVP_MAX_MD_SIZE]; unsigned int keyidlen = 0; #ifdef CRYPTO_MDEBUG CRYPTO_push_info("process -export_cert"); CRYPTO_push_info("reading private key"); #endif key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1, passin, e, "private key"); if (!key) { goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from input"); #endif /* Load in all certs in input file */ if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, "certificates"))) { goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from input 2"); #endif for(i = 0; i < sk_X509_num(certs); i++) { ucert = sk_X509_value(certs, i); if(X509_check_private_key(ucert, key)) { X509_digest(ucert, EVP_sha1(), keyid, &keyidlen); break; } } if(!keyidlen) { ucert = NULL; BIO_printf(bio_err, "No certificate matches private key\n"); goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from certfile"); #endif bags = sk_PKCS12_SAFEBAG_new_null (); /* Add any more certificates asked for */ if (certfile) { STACK_OF(X509) *morecerts=NULL; if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, NULL, e, "certificates from certfile"))) { goto export_end; } while(sk_X509_num(morecerts) > 0) { sk_X509_push(certs, sk_X509_shift(morecerts)); } sk_X509_free(morecerts); } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building chain"); #endif /* If chaining get chain from user cert */ if (chain) { int vret; STACK_OF(X509) *chain2; X509_STORE *store = X509_STORE_new(); if (!store) { BIO_printf (bio_err, "Memory allocation error\n"); goto export_end; } if (!X509_STORE_load_locations(store, CAfile, CApath)) X509_STORE_set_default_paths (store); vret = get_cert_chain (ucert, store, &chain2); X509_STORE_free(store); if (!vret) { /* Exclude verified certificate */ for (i = 1; i < sk_X509_num (chain2) ; i++) sk_X509_push(certs, sk_X509_value (chain2, i)); /* Free first certificate */ X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); } else { BIO_printf (bio_err, "Error %s getting chain.\n", X509_verify_cert_error_string(vret)); goto export_end; } } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building bags"); #endif /* We now have loads of certificates: include them all */ for(i = 0; i < sk_X509_num(certs); i++) { X509 *cert = NULL; cert = sk_X509_value(certs, i); bag = PKCS12_x5092certbag(cert); /* If it matches private key set id */ if(cert == ucert) { if(name) PKCS12_add_friendlyname(bag, name, -1); PKCS12_add_localkeyid(bag, keyid, keyidlen); } else if((catmp = sk_shift(canames))) PKCS12_add_friendlyname(bag, catmp, -1); sk_PKCS12_SAFEBAG_push(bags, bag); } sk_X509_pop_free(certs, X509_free); certs = NULL; #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("encrypting bags"); #endif if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n"); goto export_end; } if (!twopass) strcpy(macpass, pass); /* Turn certbags into encrypted authsafe */ authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0, iter, bags); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; if (!authsafe) { ERR_print_errors (bio_err); goto export_end; } safes = sk_PKCS7_new_null (); sk_PKCS7_push (safes, authsafe); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building shrouded key bag"); #endif /* Make a shrouded key bag */ p8 = EVP_PKEY2PKCS8 (key); if(keytype) PKCS8_add_keyusage(p8, keytype); bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8); PKCS8_PRIV_KEY_INFO_free(p8); p8 = NULL; if (name) PKCS12_add_friendlyname (bag, name, -1); if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1); PKCS12_add_localkeyid (bag, keyid, keyidlen); bags = sk_PKCS12_SAFEBAG_new_null(); sk_PKCS12_SAFEBAG_push (bags, bag); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("encrypting shrouded key bag"); #endif /* Turn it into unencrypted safe bag */ authsafe = PKCS12_pack_p7data (bags); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; sk_PKCS7_push (safes, authsafe); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building pkcs12"); #endif p12 = PKCS12_init(NID_pkcs7_data); PKCS12_pack_authsafes(p12, safes); sk_PKCS7_pop_free(safes, PKCS7_free); safes = NULL; PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("writing pkcs12"); #endif i2d_PKCS12_bio (out, p12); ret = 0; export_end: #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_pop_info(); CRYPTO_push_info("process -export_cert: freeing"); #endif if (key) EVP_PKEY_free(key); if (certs) sk_X509_pop_free(certs, X509_free); if (safes) sk_PKCS7_pop_free(safes, PKCS7_free); if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif goto end; } if (!(p12 = d2i_PKCS12_bio (in, NULL))) { ERR_print_errors(bio_err); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read import password"); #endif if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n"); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif if (!twopass) strcpy(macpass, pass); if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("verify MAC"); #endif /* If we enter empty password try no password first */ if(!macpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ if(!twopass) cpass = NULL; } else if (!PKCS12_verify_mac(p12, mpass, -1)) { BIO_printf (bio_err, "Mac verify error: invalid password?\n"); ERR_print_errors (bio_err); goto end; } BIO_printf (bio_err, "MAC verified OK\n"); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif } #ifdef CRYPTO_MDEBUG CRYPTO_push_info("output keys and certificates"); #endif if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors (bio_err); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif ret = 0; end: if (p12) PKCS12_free(p12); if(export_cert || inrand) app_RAND_write_file(NULL, bio_err); #ifdef CRYPTO_MDEBUG CRYPTO_remove_all_info(); #endif BIO_free(in); BIO_free_all(out); if (canames) sk_free(canames); if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); OPENSSL_EXIT(ret); }
/* * Private */ static void ossl_pkcs12_free(void *ptr) { PKCS12_free(ptr); }