X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen) { PBEPARAM *pbe=NULL; ASN1_OBJECT *al; X509_ALGOR *algor; ASN1_TYPE *astype=NULL; if (!(pbe = PBEPARAM_new ())) { ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } if(iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(pbe->iter, iter)) { ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!(pbe->salt->data = OPENSSL_malloc (saltlen))) { ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } pbe->salt->length = saltlen; if (salt) memcpy (pbe->salt->data, salt, saltlen); else if (RAND_pseudo_bytes (pbe->salt->data, saltlen) < 0) goto err; if (!(astype = ASN1_TYPE_new())) { ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } astype->type = V_ASN1_SEQUENCE; if(!ASN1_pack_string_of(PBEPARAM, pbe, i2d_PBEPARAM, &astype->value.sequence)) { ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } PBEPARAM_free (pbe); pbe = NULL; al = OBJ_nid2obj(alg); /* never need to free al */ if (!(algor = X509_ALGOR_new())) { ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } ASN1_OBJECT_free(algor->algorithm); algor->algorithm = al; algor->parameter = astype; return (algor); err: if (pbe != NULL) PBEPARAM_free(pbe); if (astype != NULL) ASN1_TYPE_free(astype); return NULL; }
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) { ASN1_STRING *params = NULL; ASN1_INTEGER *prkey = NULL; ASN1_TYPE *ttmp = NULL; STACK_OF(ASN1_TYPE) *ndsa = NULL; unsigned char *p = NULL, *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_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } q = p; i2d_DSAparams (pkey->pkey.dsa, &q); if (!(params = ASN1_STRING_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_STRING_set(params, p, len)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } OPENSSL_free(p); p = NULL; /* Get private key into integer */ if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) { EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR); goto err; } switch(p8->broken) { case PKCS8_OK: case PKCS8_NO_OCTET: if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER, &p8->pkey->value.octet_string)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } M_ASN1_INTEGER_free (prkey); prkey = NULL; p8->pkeyalg->parameter->value.sequence = params; params = NULL; p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; break; case PKCS8_NS_DB: p8->pkeyalg->parameter->value.sequence = params; params = NULL; p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; if (!(ndsa = sk_ASN1_TYPE_new_null())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp->value.integer = BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) { EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR); goto err; } ttmp->type = V_ASN1_INTEGER; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp->value.integer = prkey; prkey = NULL; ttmp->type = V_ASN1_INTEGER; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp = NULL; if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, &p8->pkey->value.octet_string->data, &p8->pkey->value.octet_string->length)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); break; case PKCS8_EMBEDDED_PARAM: p8->pkeyalg->parameter->type = V_ASN1_NULL; if (!(ndsa = sk_ASN1_TYPE_new_null())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp->value.sequence = params; params = NULL; ttmp->type = V_ASN1_SEQUENCE; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp->value.integer = prkey; prkey = NULL; ttmp->type = V_ASN1_INTEGER; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp = NULL; if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, &p8->pkey->value.octet_string->data, &p8->pkey->value.octet_string->length)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); break; } return 1; err: if (p != NULL) OPENSSL_free(p); if (params != NULL) ASN1_STRING_free(params); if (prkey != NULL) M_ASN1_INTEGER_free(prkey); if (ttmp != NULL) ASN1_TYPE_free(ttmp); if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); return 0; }
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 (!ASN1_INTEGER_set(p8->version, 0)) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,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 OPENSSL_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_of (EVP_PKEY,pkey, i2d_PrivateKey, &p8->pkey->value.octet_string)) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } break; #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: if(!dsa_pkey2pkcs8(p8, pkey)) { PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } break; #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: if (!eckey_pkey2pkcs8(p8, pkey)) { PKCS8_PRIV_KEY_INFO_free(p8); return(NULL); } break; #endif default: EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, 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.0); return p8; }
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid; EVP_CIPHER_CTX ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; PBKDF2PARAM *kdf = NULL; PBE2PARAM *pbe2 = NULL; ASN1_OCTET_STRING *osalt = NULL; ASN1_OBJECT *obj; alg_nid = EVP_CIPHER_type(cipher); if(alg_nid == NID_undef) { ASN1err(ASN1_F_PKCS5_PBE2_SET, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); goto err; } obj = OBJ_nid2obj(alg_nid); if(!(pbe2 = PBE2PARAM_new())) goto merr; /* Setup the AlgorithmIdentifier for the encryption scheme */ scheme = pbe2->encryption; scheme->algorithm = obj; if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; /* Create random IV */ if (EVP_CIPHER_iv_length(cipher) && RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) goto err; EVP_CIPHER_CTX_init(&ctx); /* Dummy cipherinit to just setup the IV */ EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0); if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { ASN1err(ASN1_F_PKCS5_PBE2_SET, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } EVP_CIPHER_CTX_cleanup(&ctx); if(!(kdf = PBKDF2PARAM_new())) goto merr; if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr; if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!(osalt->data = OPENSSL_malloc (saltlen))) goto merr; osalt->length = saltlen; if (salt) memcpy (osalt->data, salt, saltlen); else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr; if(iter <= 0) iter = PKCS5_DEFAULT_ITER; if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr; /* Now include salt in kdf structure */ kdf->salt->value.octet_string = osalt; kdf->salt->type = V_ASN1_OCTET_STRING; osalt = NULL; /* If its RC2 then we'd better setup the key length */ if(alg_nid == NID_rc2_cbc) { if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr; if(!ASN1_INTEGER_set (kdf->keylength, EVP_CIPHER_key_length(cipher))) goto merr; } /* prf can stay NULL because we are using hmacWithSHA1 */ /* Now setup the PBE2PARAM keyfunc structure */ pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); /* Encode PBKDF2PARAM into parameter of pbe2 */ if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM, &pbe2->keyfunc->parameter->value.sequence)) goto merr; pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; PBKDF2PARAM_free(kdf); kdf = NULL; /* Now set up top level AlgorithmIdentifier */ if(!(ret = X509_ALGOR_new())) goto merr; if(!(ret->parameter = ASN1_TYPE_new())) goto merr; ret->algorithm = OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM, &ret->parameter->value.sequence)) goto merr; ret->parameter->type = V_ASN1_SEQUENCE; PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; merr: ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); /* Note 'scheme' is freed as part of pbe2 */ M_ASN1_OCTET_STRING_free(osalt); PBKDF2PARAM_free(kdf); X509_ALGOR_free(kalg); X509_ALGOR_free(ret); return NULL; }