// Encode into PKCS#8 DER ByteString OSSLECPrivateKey::PKCS8Encode() { ByteString der; if (eckey == NULL) return der; EVP_PKEY* pkey = EVP_PKEY_new(); if (pkey == NULL) return der; if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); return der; } PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey); EVP_PKEY_free(pkey); if (p8inf == NULL) return der; int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL); if (len < 0) { PKCS8_PRIV_KEY_INFO_free(p8inf); return der; } der.resize(len); unsigned char* priv = &der[0]; int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv); PKCS8_PRIV_KEY_INFO_free(p8inf); if (len2 != len) der.wipe(); return der; }
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) { PKCS8_PRIV_KEY_INFO *p8; if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); return NULL; } p8->broken = broken; ASN1_INTEGER_set (p8->version, 0); if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) { EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } p8->pkey->type = V_ASN1_OCTET_STRING; switch (EVP_PKEY_type(pkey->type)) { #ifndef NO_RSA case EVP_PKEY_RSA: if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE; p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption); p8->pkeyalg->parameter->type = V_ASN1_NULL; if (!ASN1_pack_string ((char *)pkey, (i2d_func_t)i2d_PrivateKey, &p8->pkey->value.octet_string)) { EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } break; #endif #ifndef NO_DSA case EVP_PKEY_DSA: if(!dsa_pkey2pkcs8(p8, pkey)) { PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } break; #endif default: EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } RAND_add(p8->pkey->value.octet_string->data, p8->pkey->value.octet_string->length, 0); return p8; }
static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u) { X509_SIG *p8; PKCS8_PRIV_KEY_INFO *p8inf; char buf[PEM_BUFSIZE]; int ret; if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) { PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); return 0; } if (enc || (nid != -1)) { if (!kstr) { if (!cb) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); else klen = cb(buf, PEM_BUFSIZE, 1, u); if (klen <= 0) { PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY); PKCS8_PRIV_KEY_INFO_free(p8inf); return 0; } kstr = buf; } p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); if (kstr == buf) OPENSSL_cleanse(buf, klen); PKCS8_PRIV_KEY_INFO_free(p8inf); if (p8 == NULL) return 0; if (isder) ret = i2d_PKCS8_bio(bp, p8); else ret = PEM_write_bio_PKCS8(bp, p8); X509_SIG_free(p8); return ret; } else { if (isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); return ret; } }
EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { PKCS8_PRIV_KEY_INFO *p8inf = NULL; X509_SIG *p8 = NULL; int klen; EVP_PKEY *ret; char psbuf[PEM_BUFSIZE]; p8 = d2i_PKCS8_bio(bp, NULL); if (!p8) return NULL; if (cb) klen = cb(psbuf, PEM_BUFSIZE, 0, u); else klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (klen <= 0) { PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); return NULL; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if (!p8inf) return NULL; ret = EVP_PKCS82PKEY(p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); if (!ret) return NULL; if (x) { if (*x) EVP_PKEY_free(*x); *x = ret; } return ret; }
void PKCS12_SAFEBAG_free (PKCS12_SAFEBAG *a) { if (a == NULL) return; switch (OBJ_obj2nid(a->type)) { case NID_keyBag: PKCS8_PRIV_KEY_INFO_free (a->value.keybag); break; case NID_pkcs8ShroudedKeyBag: X509_SIG_free (a->value.shkeybag); break; case NID_certBag: case NID_crlBag: case NID_secretBag: PKCS12_BAGS_free (a->value.bag); break; default: ASN1_TYPE_free (a->value.other); break; } ASN1_OBJECT_free (a->type); sk_X509_ATTRIBUTE_pop_free (a->attrib, X509_ATTRIBUTE_free); OPENSSL_free (a); }
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) { PKCS8_PRIV_KEY_INFO *p8; p8 = PKCS8_PRIV_KEY_INFO_new(); if (p8 == NULL) { OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return NULL; } p8->broken = PKCS8_OK; if (pkey->ameth) { if (pkey->ameth->priv_encode) { if (!pkey->ameth->priv_encode(p8, pkey)) { OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, PKCS8_R_PRIVATE_KEY_ENCODE_ERROR); goto error; } } else { OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED); goto error; } } else { OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); goto error; } return p8; error: PKCS8_PRIV_KEY_INFO_free(p8); return NULL; }
/* Tests loading a bad key in PKCS8 format */ static int test_EVP_PKCS82PKEY(void) { int ret = 0; const unsigned char *derp = kExampleBadECKeyDER; PKCS8_PRIV_KEY_INFO *p8inf = NULL; EVP_PKEY *pkey = NULL; p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER)); if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) { fprintf(stderr, "Failed to parse key\n"); goto done; } pkey = EVP_PKCS82PKEY(p8inf); if (pkey) { fprintf(stderr, "Imported invalid EC key\n"); goto done; } ret = 1; done: PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); return ret; }
PKCS8_PRIV_KEY_INFO * EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) { PKCS8_PRIV_KEY_INFO *p8; if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { EVPerror(ERR_R_MALLOC_FAILURE); return NULL; } p8->broken = broken; if (pkey->ameth) { if (pkey->ameth->priv_encode) { if (!pkey->ameth->priv_encode(p8, pkey)) { EVPerror(EVP_R_PRIVATE_KEY_ENCODE_ERROR); goto error; } } else { EVPerror(EVP_R_METHOD_NOT_SUPPORTED); goto error; } } else { EVPerror(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); goto error; } return p8; error: PKCS8_PRIV_KEY_INFO_free(p8); return NULL; }
/* Tests loading a bad key in PKCS8 format */ static int test_EVP_PKCS82PKEY(void) { int ret = 0; const unsigned char *derp = kExampleBadECKeyDER; PKCS8_PRIV_KEY_INFO *p8inf = NULL; EVP_PKEY *pkey = NULL; if (!TEST_ptr(p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER)))) goto done; if (!TEST_ptr_eq(derp, kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER))) goto done; if (!TEST_ptr_null(pkey = EVP_PKCS82PKEY(p8inf))) goto done; ret = 1; done: PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); return ret; }
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) { PKCS8_PRIV_KEY_INFO *p8; if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE); return NULL; } p8->broken = broken; if (pkey->ameth) { if (pkey->ameth->priv_encode) { if (!pkey->ameth->priv_encode(p8, pkey)) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_PRIVATE_KEY_ENCODE_ERROR); goto error; } } else { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED); goto error; } } else { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); goto error; } RAND_add(p8->pkey->value.octet_string->data, p8->pkey->value.octet_string->length, 0.0); return p8; error: PKCS8_PRIV_KEY_INFO_free(p8); return NULL; }
int i2d_PKCS8PrivateKeyInfo_fp(TINYCLR_SSL_FILE *fp, EVP_PKEY *key) { PKCS8_PRIV_KEY_INFO *p8inf; int ret; p8inf = EVP_PKEY2PKCS8(key); if(!p8inf) return 0; ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); return ret; }
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) { PKCS8_PRIV_KEY_INFO *p8inf; int ret; p8inf = EVP_PKEY2PKCS8(key); if(!p8inf) return 0; ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); return ret; }
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, long len) { EVP_PKEY *ret; if (out == NULL || *out == NULL) { ret = EVP_PKEY_new(); if (ret == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB); return NULL; } } else { ret = *out; } if (!EVP_PKEY_set_type(ret, type)) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; } const uint8_t *in = *inp; if (!ret->ameth->old_priv_decode || !ret->ameth->old_priv_decode(ret, &in, len)) { if (ret->ameth->priv_decode) { /* Reset |in| in case |old_priv_decode| advanced it on error. */ in = *inp; PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &in, len); if (!p8) { goto err; } EVP_PKEY_free(ret); ret = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); if (ret == NULL) { goto err; } } else { OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB); goto err; } } if (out != NULL) { *out = ret; } *inp = in; return ret; err: if (out == NULL || *out != ret) { EVP_PKEY_free(ret); } return NULL; }
void keygen_free(void) { PKCS8_PRIV_KEY_INFO_free(m_p8info); EVP_PKEY_free(m_evpkey); BN_free(m_bignumber); RSA_free(m_rsa); BIO_free_all(m_bio); m_p8info=NULL; m_evpkey=NULL; m_bignumber=NULL; m_rsa=NULL; m_bio=NULL; }
static EVP_PKEY *getPrivateKey(PKCS12 *p12, X509 *x509, const char* pass) { // Extract all PKCS7 safes STACK_OF(PKCS7) *pkcs7s = PKCS12_unpack_authsafes(p12); if (!pkcs7s) { certutil_updateErrorString(); return NULL; } // For each PKCS7 safe int nump = sk_PKCS7_num(pkcs7s); for (int p = 0; p < nump; p++) { PKCS7 *p7 = sk_PKCS7_value(pkcs7s, p); if (!p7) continue; STACK_OF(PKCS12_SAFEBAG) *safebags = PKCS12_unpack_p7data(p7); if (!safebags) continue; // For each PKCS12 safebag int numb = sk_PKCS12_SAFEBAG_num(safebags); for (int i = 0; i < numb; i++) { PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(safebags, i); if (!bag) continue; switch (M_PKCS12_bag_type(bag)) { case NID_pkcs8ShroudedKeyBag:; // Encrypted key PKCS8_PRIV_KEY_INFO *p8 = PKCS12_decrypt_skey(bag, pass, strlen(pass)); if (p8) { EVP_PKEY *pk = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); if (!pk) break; // out of switch if (X509_check_private_key(x509, pk) > 0) { sk_PKCS12_SAFEBAG_pop_free(safebags, PKCS12_SAFEBAG_free); sk_PKCS7_pop_free(pkcs7s, PKCS7_free); return pk; } EVP_PKEY_free(pk); } break; } } sk_PKCS12_SAFEBAG_pop_free(safebags, PKCS12_SAFEBAG_free); } sk_PKCS7_pop_free(pkcs7s, PKCS7_free); return NULL; }
int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) { if (a->ameth && a->ameth->old_priv_encode) { return a->ameth->old_priv_encode(a, pp); } if (a->ameth && a->ameth->priv_encode) { PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp); PKCS8_PRIV_KEY_INFO_free(p8); return ret; } ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return(-1); }
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length) { STACK_OF(ASN1_TYPE) *inkey; const unsigned char *p; int keytype; p = *pp; /* * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by * analyzing it we can determine the passed structure: this assumes the * input is surrounded by an ASN1 SEQUENCE. */ inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); p = *pp; /* * Since we only need to discern "traditional format" RSA and DSA keys we * can just count the elements. */ if (sk_ASN1_TYPE_num(inkey) == 6) keytype = EVP_PKEY_DSA; else if (sk_ASN1_TYPE_num(inkey) == 4) keytype = EVP_PKEY_EC; else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not * traditional format */ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); EVP_PKEY *ret; sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); if (!p8) { ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return NULL; } ret = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); if (ret == NULL) return NULL; *pp = p; if (a) { *a = ret; } return ret; } else keytype = EVP_PKEY_RSA; sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); return d2i_PrivateKey(keytype, a, pp, length); }
static void add_from_bag(X509 **pX509, EVP_PKEY **pPkey, PKCS12_SAFEBAG *bag, const char *pw) { EVP_PKEY *pkey = NULL; X509 *x509 = NULL; PKCS8_PRIV_KEY_INFO *p8 = NULL; switch (M_PKCS12_bag_type(bag)) { case NID_keyBag: p8 = bag->value.keybag; pkey = EVP_PKCS82PKEY(p8); break; case NID_pkcs8ShroudedKeyBag: p8 = PKCS12_decrypt_skey(bag, pw, (int)strlen(pw)); if (p8) { pkey = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); } break; case NID_certBag: if (M_PKCS12_cert_bag_type(bag) == NID_x509Certificate) x509 = PKCS12_certbag2x509(bag); break; case NID_safeContentsBag: add_from_bags(pX509, pPkey, bag->value.safes, pw); break; } if (pkey) { if (!*pPkey) *pPkey = pkey; else EVP_PKEY_free(pkey); } if (x509) { if (!*pX509) *pX509 = x509; else X509_free(x509); } }
// Decode from PKCS#8 BER bool OSSLECPrivateKey::PKCS8Decode(const ByteString& ber) { int len = ber.size(); if (len <= 0) return false; const unsigned char* priv = ber.const_byte_str(); PKCS8_PRIV_KEY_INFO* p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &priv, len); if (p8 == NULL) return false; EVP_PKEY* pkey = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); if (pkey == NULL) return false; EC_KEY* key = EVP_PKEY_get1_EC_KEY(pkey); EVP_PKEY_free(pkey); if (key == NULL) return false; setFromOSSL(key); EC_KEY_free(key); return true; }
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { STACK_OF(ASN1_TYPE) *inkey; const uint8_t *p; int keytype; p = *inp; /* Dirty trick: read in the ASN1 data into out STACK_OF(ASN1_TYPE): * by analyzing it we can determine the passed structure: this * assumes the input is surrounded by an ASN1 SEQUENCE. */ inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, len); /* Since we only need to discern "traditional format" RSA and DSA * keys we can just count the elements. */ if (sk_ASN1_TYPE_num(inkey) == 6) { keytype = EVP_PKEY_DSA; } else if (sk_ASN1_TYPE_num(inkey) == 4) { keytype = EVP_PKEY_EC; } else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not traditional format */ p = *inp; PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); EVP_PKEY *ret; sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); if (!p8) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return NULL; } ret = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); if (ret == NULL) { return NULL; } *inp = p; if (out) { *out = ret; } return ret; } else { keytype = EVP_PKEY_RSA; } sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); return d2i_PrivateKey(keytype, out, inp, len); }
char *cipher_rsa_decrypt(const char *ciphertext, size_t len, const struct private_key *private_key) { PKCS8_PRIV_KEY_INFO *p8inf = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; BIO *memory = NULL; char *ret = NULL; if (!len) return NULL; memory = BIO_new(BIO_s_mem()); if (BIO_write(memory, private_key->key, private_key->len) < 0) goto out; p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(memory, NULL); if (!p8inf) goto out; pkey = EVP_PKCS82PKEY(p8inf); if (!pkey) goto out; if (p8inf->broken) goto out; rsa = EVP_PKEY_get1_RSA(pkey); if (!rsa) goto out; ret = xcalloc(len + 1, 1); if (RSA_private_decrypt(len, (unsigned char *)ciphertext, (unsigned char *)ret, rsa, RSA_PKCS1_OAEP_PADDING) < 0) { free(ret); ret = NULL; goto out; } out: PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); RSA_free(rsa); BIO_free_all(memory); return ret; }
static int autoca_gencert( Operation *op, genargs *args ) { X509_NAME *subj_name, *issuer_name; X509 *subj_cert; struct berval derdn; unsigned char *pp; EVP_PKEY *evpk = NULL; int rc; if ((subj_cert = X509_new()) == NULL) return -1; autoca_dnbv2der( op, args->subjectDN, &derdn ); pp = (unsigned char *)derdn.bv_val; subj_name = d2i_X509_NAME( NULL, (const unsigned char **)&pp, derdn.bv_len ); op->o_tmpfree( derdn.bv_val, op->o_tmpmemctx ); if ( subj_name == NULL ) { fail1: X509_free( subj_cert ); return -1; } rc = autoca_genpkey( args->keybits, &evpk ); if ( rc <= 0 ) { fail2: if ( subj_name ) X509_NAME_free( subj_name ); goto fail1; } /* encode DER in PKCS#8 */ { PKCS8_PRIV_KEY_INFO *p8inf; if (( p8inf = EVP_PKEY2PKCS8( evpk )) == NULL ) goto fail2; args->derpkey.bv_len = i2d_PKCS8_PRIV_KEY_INFO( p8inf, NULL ); args->derpkey.bv_val = op->o_tmpalloc( args->derpkey.bv_len, op->o_tmpmemctx ); pp = (unsigned char *)args->derpkey.bv_val; i2d_PKCS8_PRIV_KEY_INFO( p8inf, &pp ); PKCS8_PRIV_KEY_INFO_free( p8inf ); } args->newpkey = evpk; /* set random serial */ { BIGNUM *bn = BN_new(); if ( bn == NULL ) { fail3: EVP_PKEY_free( evpk ); goto fail2; } if (!BN_pseudo_rand(bn, SERIAL_BITS, 0, 0)) { BN_free( bn ); goto fail3; } if (!BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(subj_cert))) { BN_free( bn ); goto fail3; } BN_free(bn); } if (args->issuer_cert) { issuer_name = X509_get_subject_name(args->issuer_cert); } else { issuer_name = subj_name; args->issuer_cert = subj_cert; args->issuer_pkey = evpk; } if (!X509_set_version(subj_cert, 2) || /* set version to V3 */ !X509_set_issuer_name(subj_cert, issuer_name) || !X509_set_subject_name(subj_cert, subj_name) || !X509_gmtime_adj(X509_get_notBefore(subj_cert), 0) || !X509_time_adj_ex(X509_get_notAfter(subj_cert), args->days, 0, NULL) || !X509_set_pubkey(subj_cert, evpk)) { goto fail3; } X509_NAME_free(subj_name); subj_name = NULL; /* set cert extensions */ { X509V3_CTX ctx; X509_EXTENSION *ext; int i; X509V3_set_ctx(&ctx, args->issuer_cert, subj_cert, NULL, NULL, 0); for (i=0; args->cert_exts[i].name; i++) { ext = X509V3_EXT_nconf(NULL, &ctx, args->cert_exts[i].name, args->cert_exts[i].value); if ( ext == NULL ) goto fail3; rc = X509_add_ext(subj_cert, ext, -1); X509_EXTENSION_free(ext); if ( !rc ) goto fail3; } if (args->more_exts) { for (i=0; args->more_exts[i].name; i++) { ext = X509V3_EXT_nconf(NULL, &ctx, args->more_exts[i].name, args->more_exts[i].value); if ( ext == NULL ) goto fail3; rc = X509_add_ext(subj_cert, ext, -1); X509_EXTENSION_free(ext); if ( !rc ) goto fail3; } } } rc = autoca_signcert( subj_cert, args->issuer_pkey ); if ( rc < 0 ) goto fail3; args->dercert.bv_len = i2d_X509( subj_cert, NULL ); args->dercert.bv_val = op->o_tmpalloc( args->dercert.bv_len, op->o_tmpmemctx ); pp = (unsigned char *)args->dercert.bv_val; i2d_X509( subj_cert, &pp ); args->newcert = subj_cert; return 0; }
EVP_PKEY * PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { char *nm = NULL; const unsigned char *p = NULL; unsigned char *data = NULL; long len; int slen; EVP_PKEY *ret = NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { EVP_PKEY_free(*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; X509_SIG *p8; int klen; char psbuf[PEM_BUFSIZE]; p8 = d2i_X509_SIG(NULL, &p, len); if (!p8) goto p8err; if (cb) klen = cb(psbuf, PEM_BUFSIZE, 0, u); else klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (klen <= 0) { PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); goto err; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { EVP_PKEY_free(*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); if (!ameth || !ameth->old_priv_decode) goto p8err; ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); } p8err: if (ret == NULL) PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); err: free(nm); OPENSSL_cleanse(data, len); free(data); return (ret); }
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { char *nm=NULL; const unsigned char *p=NULL; unsigned char *data=NULL; long len; EVP_PKEY *ret=NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; if (strcmp(nm,PEM_STRING_RSA) == 0) ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len); else if (strcmp(nm,PEM_STRING_DSA) == 0) ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len); else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0) ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len); else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); if(!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if(x) { if(*x) EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if (strcmp(nm,PEM_STRING_PKCS8) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; X509_SIG *p8; int klen; char psbuf[PEM_BUFSIZE]; p8 = d2i_X509_SIG(NULL, &p, len); if(!p8) goto p8err; if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); if (klen <= 0) { PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); goto err; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if(!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if(x) { if(*x) EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } p8err: if (ret == NULL) PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB); err: OPENSSL_free(nm); OPENSSL_cleanse(data, len); OPENSSL_free(data); return(ret); }
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) { ASN1_STRING *params; ASN1_INTEGER *prkey; ASN1_TYPE *ttmp; STACK_OF(ASN1_TYPE) *ndsa; unsigned char *p, *q; int len; p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa); len = i2d_DSAparams (pkey->pkey.dsa, NULL); if (!(p = OPENSSL_malloc(len))) { EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return 0; } q = p; i2d_DSAparams (pkey->pkey.dsa, &q); params = ASN1_STRING_new(); ASN1_STRING_set(params, p, len); OPENSSL_free(p); /* Get private key into integer */ if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) { EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR); return 0; } switch(p8->broken) { case PKCS8_OK: case PKCS8_NO_OCTET: if (!ASN1_pack_string((char *)prkey, (i2d_func_t)i2d_ASN1_INTEGER, &p8->pkey->value.octet_string)) { EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); M_ASN1_INTEGER_free (prkey); return 0; } M_ASN1_INTEGER_free (prkey); p8->pkeyalg->parameter->value.sequence = params; p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; break; case PKCS8_NS_DB: p8->pkeyalg->parameter->value.sequence = params; p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; ndsa = sk_ASN1_TYPE_new_null(); ttmp = ASN1_TYPE_new(); if (!(ttmp->value.integer = BN_to_ASN1_INTEGER (pkey->pkey.dsa->pub_key, NULL))) { EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR); PKCS8_PRIV_KEY_INFO_free(p8); return 0; } ttmp->type = V_ASN1_INTEGER; sk_ASN1_TYPE_push(ndsa, ttmp); ttmp = ASN1_TYPE_new(); ttmp->value.integer = prkey; ttmp->type = V_ASN1_INTEGER; sk_ASN1_TYPE_push(ndsa, ttmp); p8->pkey->value.octet_string = ASN1_OCTET_STRING_new(); if (!ASN1_seq_pack_ASN1_TYPE(ndsa, (i2d_func_t)i2d_ASN1_TYPE, &p8->pkey->value.octet_string->data, &p8->pkey->value.octet_string->length)) { EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); M_ASN1_INTEGER_free(prkey); return 0; } sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); break; case PKCS8_EMBEDDED_PARAM: p8->pkeyalg->parameter->type = V_ASN1_NULL; ndsa = sk_ASN1_TYPE_new_null(); ttmp = ASN1_TYPE_new(); ttmp->value.sequence = params; ttmp->type = V_ASN1_SEQUENCE; sk_ASN1_TYPE_push(ndsa, ttmp); ttmp = ASN1_TYPE_new(); ttmp->value.integer = prkey; ttmp->type = V_ASN1_INTEGER; sk_ASN1_TYPE_push(ndsa, ttmp); p8->pkey->value.octet_string = ASN1_OCTET_STRING_new(); if (!ASN1_seq_pack_ASN1_TYPE(ndsa, (i2d_func_t)i2d_ASN1_TYPE, &p8->pkey->value.octet_string->data, &p8->pkey->value.octet_string->length)) { EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); M_ASN1_INTEGER_free (prkey); return 0; } sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); break; } return 1; }
static OSSL_STORE_INFO *try_decode_PrivateKey(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; EVP_PKEY *pkey = NULL; const EVP_PKEY_ASN1_METHOD *ameth = NULL; if (pem_name != NULL) { if (strcmp(pem_name, PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len); *matchcount = 1; if (p8inf != NULL) pkey = EVP_PKCS82PKEY(p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); } else { int slen; if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0 && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, slen)) != NULL) { *matchcount = 1; pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len); } } } else { int i; for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { EVP_PKEY *tmp_pkey = NULL; const unsigned char *tmp_blob = blob; ameth = EVP_PKEY_asn1_get0(i); if (ameth->pkey_flags & ASN1_PKEY_ALIAS) continue; tmp_pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &tmp_blob, len); if (tmp_pkey != NULL) { if (pkey != NULL) EVP_PKEY_free(tmp_pkey); else pkey = tmp_pkey; (*matchcount)++; } } if (*matchcount > 1) { EVP_PKEY_free(pkey); pkey = NULL; } } if (pkey == NULL) /* No match */ return NULL; store_info = OSSL_STORE_INFO_new_PKEY(pkey); if (store_info == NULL) EVP_PKEY_free(pkey); return store_info; }
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); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char **args, *infile = NULL, *outfile = NULL; char *passargin = NULL, *passargout = NULL; BIO *in = NULL, *out = NULL; int topk8 = 0; int pbe_nid = -1; const EVP_CIPHER *cipher = NULL; int iter = PKCS12_DEFAULT_ITER; int informat, outformat; int p8_broken = PKCS8_OK; int nocrypt = 0; X509_SIG *p8 = NULL; PKCS8_PRIV_KEY_INFO *p8inf = NULL; EVP_PKEY *pkey=NULL; char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; int badarg = 0; int ret = 1; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; informat=FORMAT_PEM; outformat=FORMAT_PEM; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args,"-v2")) { if (args[1]) { args++; cipher=EVP_get_cipherbyname(*args); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args,"-v1")) { if (args[1]) { args++; pbe_nid=OBJ_txt2nid(*args); if (pbe_nid == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args,"-v2prf")) { if (args[1]) { args++; pbe_nid=OBJ_txt2nid(*args); if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { BIO_printf(bio_err, "Unknown PRF algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args,"-inform")) { if (args[1]) { args++; informat=str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args,"-outform")) { if (args[1]) { args++; outformat=str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-topk8")) topk8 = 1; else if (!strcmp (*args, "-noiter")) iter = 1; else if (!strcmp (*args, "-iter")) { if (!args[1]) goto bad; iter = atoi(*(++args)); if (iter <= 0) goto bad; } else if (!strcmp (*args, "-nocrypt")) nocrypt = 1; else if (!strcmp (*args, "-nooct")) p8_broken = PKCS8_NO_OCTET; else if (!strcmp (*args, "-nsdb")) p8_broken = PKCS8_NS_DB; else if (!strcmp (*args, "-embed")) p8_broken = PKCS8_EMBEDDED_PARAM; else if (!strcmp(*args,"-passin")) { if (!args[1]) goto bad; passargin= *(++args); } else if (!strcmp(*args,"-passout")) { if (!args[1]) goto bad; passargout= *(++args); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*args,"-engine") == 0) { if (!args[1]) goto bad; engine= *(++args); } #endif 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 badarg = 1; args++; } if (badarg) { bad: BIO_printf(bio_err, "Usage pkcs8 [options]\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-in file input file\n"); BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-passout arg output file pass phrase source\n"); BIO_printf(bio_err, "-topk8 output PKCS8 file\n"); BIO_printf(bio_err, "-nooct use (nonstandard) no octet format\n"); BIO_printf(bio_err, "-embed use (nonstandard) embedded DSA parameters format\n"); BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netscape DB format\n"); BIO_printf(bio_err, "-iter count use count as iteration count\n"); BIO_printf(bio_err, "-noiter use 1 as iteration count\n"); BIO_printf(bio_err, "-nocrypt use or expect unencrypted private key\n"); BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n"); BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if ((pbe_nid == -1) && !cipher) pbe_nid = NID_pbeWithMD5AndDES_CBC; if (infile) { if (!(in = BIO_new_file(infile, "rb"))) { BIO_printf(bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp (stdin, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file (outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp (stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if (topk8) { pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); if (!pkey) goto end; if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); goto end; } if (nocrypt) { if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); else if (outformat == FORMAT_ASN1) i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } else { if (passout) p8pass = passout; else { p8pass = pass; if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:"******"Error encrypting key\n"); ERR_print_errors(bio_err); goto end; } app_RAND_write_file(NULL, bio_err); if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8(out, p8); else if (outformat == FORMAT_ASN1) i2d_PKCS8_bio(out, p8); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } ret = 0; goto end; } if (nocrypt) { if (informat == FORMAT_PEM) p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL); else if (informat == FORMAT_ASN1) p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } else { if (informat == FORMAT_PEM) p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p8 = d2i_PKCS8_bio(in, NULL); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } if (!p8) { BIO_printf (bio_err, "Error reading key\n"); ERR_print_errors(bio_err); goto end; } if (passin) p8pass = passin; else { p8pass = pass; EVP_read_pw_string(pass, sizeof pass, "Enter Password:"******"Error decrypting key\n"); ERR_print_errors(bio_err); goto end; } if (!(pkey = EVP_PKCS82PKEY(p8inf))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); goto end; } if (p8inf->broken) { BIO_printf(bio_err, "Warning: broken key encoding: "); switch (p8inf->broken) { case PKCS8_NO_OCTET: BIO_printf(bio_err, "No Octet String in PrivateKey\n"); break; case PKCS8_EMBEDDED_PARAM: BIO_printf(bio_err, "DSA parameters included in PrivateKey\n"); break; case PKCS8_NS_DB: BIO_printf(bio_err, "DSA public key include in PrivateKey\n"); break; case PKCS8_NEG_PRIVKEY: BIO_printf(bio_err, "DSA private key value is negative\n"); break; default: BIO_printf(bio_err, "Unknown broken type\n"); break; } } if (outformat == FORMAT_PEM) PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); else if (outformat == FORMAT_ASN1) i2d_PrivateKey_bio(out, pkey); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } ret = 0; end: X509_SIG_free(p8); PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); if (passin) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); return ret; }
void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; const unsigned char *p = *pp; if ((a == NULL) || (*a == NULL)) { if ((ret = EVP_PKEY_new()) == NULL) { ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB); return (NULL); } } else { ret = *a; #ifndef OPENSSL_NO_ENGINE if (ret->engine) { ENGINE_finish(ret->engine); ret->engine = NULL; } #endif } if (!EVP_PKEY_set_type(ret, type)) { ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; } if (!ret->ameth->old_priv_decode || !ret->ameth->old_priv_decode(ret, &p, length)) { if (ret->ameth->priv_decode) { EVP_PKEY *tmp; PKCS8_PRIV_KEY_INFO *p8 = NULL; p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); if (!p8) goto err; tmp = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); if (tmp == NULL) goto err; EVP_PKEY_free(ret); ret = tmp; } else { ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); goto err; } } *pp = p; if (a != NULL) (*a) = ret; return (ret); err: if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret); return (NULL); }