PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1, int nid2) { PKCS12_BAGS *bag; PKCS12_SAFEBAG *safebag; if (!(bag = PKCS12_BAGS_new())) { PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); return NULL; } bag->type = OBJ_nid2obj(nid1); if (!ASN1_item_pack(obj, it, &bag->value.octet)) { PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); goto err; } if (!(safebag = PKCS12_SAFEBAG_new())) { PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); goto err; } safebag->value.bag = bag; safebag->type = OBJ_nid2obj(nid2); return safebag; err: PKCS12_BAGS_free(bag); return NULL; }
static int rsa_cms_encrypt(CMS_RecipientInfo *ri) { const EVP_MD *md, *mgf1md; RSA_OAEP_PARAMS *oaep = NULL; ASN1_STRING *os = NULL; X509_ALGOR *alg; EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; unsigned char *label; CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg); if (pkctx) { if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; } if (pad_mode == RSA_PKCS1_PADDING) { X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); return 1; } /* Not supported */ if (pad_mode != RSA_PKCS1_OAEP_PADDING) return 0; if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) goto err; if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) goto err; labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); if (labellen < 0) goto err; oaep = RSA_OAEP_PARAMS_new(); if (oaep == NULL) goto err; if (!rsa_md_to_algor(&oaep->hashFunc, md)) goto err; if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) goto err; if (labellen > 0) { ASN1_OCTET_STRING *los = ASN1_OCTET_STRING_new(); oaep->pSourceFunc = X509_ALGOR_new(); if (oaep->pSourceFunc == NULL) goto err; if (los == NULL) goto err; if (!ASN1_OCTET_STRING_set(los, label, labellen)) { ASN1_OCTET_STRING_free(los); goto err; } X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), V_ASN1_OCTET_STRING, los); } /* create string with pss parameter encoding. */ if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) goto err; X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); os = NULL; rv = 1; err: RSA_OAEP_PARAMS_free(oaep); ASN1_STRING_free(os); return rv; }
/* Allocate and set MGF1 algorithm ID from EVP_MD */ static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) { X509_ALGOR *algtmp = NULL; ASN1_STRING *stmp = NULL; *palg = NULL; if (EVP_MD_type(mgf1md) == NID_sha1) { return 1; } /* need to embed algorithm ID inside another */ if (!rsa_md_to_algor(&algtmp, mgf1md) || !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) { goto err; } *palg = X509_ALGOR_new(); if (!*palg) { goto err; } X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); stmp = NULL; err: ASN1_STRING_free(stmp); X509_ALGOR_free(algtmp); if (*palg) { return 1; } return 0; }
/* rsa_ctx_to_pss converts EVP_PKEY_CTX in PSS mode into corresponding * algorithm parameter, suitable for setting as an AlgorithmIdentifier. */ static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { const EVP_MD *sigmd, *mgf1md; RSA_PSS_PARAMS *pss = NULL; ASN1_STRING *os = NULL; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) || !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) || !EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) { goto err; } if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) { saltlen--; } } else { goto err; } pss = RSA_PSS_PARAMS_new(); if (!pss) { goto err; } if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength || !ASN1_INTEGER_set(pss->saltLength, saltlen)) { goto err; } } if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) { goto err; } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { goto err; } rv = 1; err: if (pss) { RSA_PSS_PARAMS_free(pss); } if (rv) { return os; } if (os) { ASN1_STRING_free(os); } return NULL; }
int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { const EVP_MD *sigmd, *mgf1md; int saltlen; if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) || !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) || !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) { return 0; } EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) { saltlen--; } } else { return 0; } int ret = 0; ASN1_STRING *os = NULL; RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); if (!pss) { goto err; } if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength || !ASN1_INTEGER_set(pss->saltLength, saltlen)) { goto err; } } if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) { goto err; } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { goto err; } X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); os = NULL; ret = 1; err: RSA_PSS_PARAMS_free(pss); ASN1_STRING_free(os); return ret; }
static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) { RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); ASN1_STRING *os; if (pss == NULL) return NULL; os = ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), NULL); RSA_PSS_PARAMS_free(pss); return os; }
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, const unsigned char *salt, int saltlen) { PBEPARAM *pbe=NULL; ASN1_STRING *pbe_str=NULL; unsigned char *sstr; pbe = PBEPARAM_new(); if (!pbe) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE); goto err; } if(iter <= 0) iter = PKCS5_DEFAULT_ITERATIONS; if (!ASN1_INTEGER_set(pbe->iter, iter)) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE); goto err; } sstr = ASN1_STRING_data(pbe->salt); if (salt) memcpy(sstr, salt, saltlen); else if (!RAND_bytes(sstr, saltlen)) goto err; if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE); goto err; } PBEPARAM_free(pbe); pbe = NULL; if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) return 1; err: if (pbe != NULL) PBEPARAM_free(pbe); if (pbe_str != NULL) ASN1_STRING_free(pbe_str); return 0; }
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, const unsigned char *salt, int saltlen) { PBEPARAM *pbe=NULL; ASN1_STRING *pbe_str=NULL; unsigned char *sstr; pbe = PBEPARAM_new(); if (!pbe) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,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_SET0_ALGOR,ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE); goto err; } sstr = ASN1_STRING_data(pbe->salt); if (salt) TINYCLR_SSL_MEMCPY(sstr, salt, saltlen); else if (RAND_pseudo_bytes(sstr, saltlen) < 0) goto err; if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE); goto err; } PBEPARAM_free(pbe); pbe = NULL; if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) return 1; err: if (pbe != NULL) PBEPARAM_free(pbe); if (pbe_str != NULL) ASN1_STRING_free(pbe_str); return 0; }
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, const unsigned char *salt, int saltlen) { PBEPARAM *pbe = NULL; ASN1_STRING *pbe_str = NULL; unsigned char *sstr = NULL; pbe = PBEPARAM_new(); if (pbe == NULL) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, 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_SET0_ALGOR, ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; sstr = OPENSSL_malloc(saltlen); if (sstr == NULL) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); goto err; } if (salt) memcpy(sstr, salt, saltlen); else if (RAND_bytes(sstr, saltlen) <= 0) goto err; ASN1_STRING_set0(pbe->salt, sstr, saltlen); sstr = NULL; if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); goto err; } PBEPARAM_free(pbe); pbe = NULL; if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) return 1; err: OPENSSL_free(sstr); PBEPARAM_free(pbe); ASN1_STRING_free(pbe_str); return 0; }
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, const unsigned char *salt, int saltlen) { PBEPARAM *pbe = NULL; ASN1_STRING *pbe_str = NULL; unsigned char *sstr; pbe = PBEPARAM_new(); if (!pbe) { ASN1error(ERR_R_MALLOC_FAILURE); goto err; } if (iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(pbe->iter, iter)) { ASN1error(ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) { ASN1error(ERR_R_MALLOC_FAILURE); goto err; } sstr = ASN1_STRING_data(pbe->salt); if (salt) memcpy(sstr, salt, saltlen); else arc4random_buf(sstr, saltlen); if (!ASN1_item_pack(pbe, &PBEPARAM_it, &pbe_str)) { ASN1error(ERR_R_MALLOC_FAILURE); goto err; } PBEPARAM_free(pbe); pbe = NULL; if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) return 1; err: if (pbe != NULL) PBEPARAM_free(pbe); ASN1_STRING_free(pbe_str); return 0; }
/* Create an OCSP response and encode an optional basic response */ OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs) { OCSP_RESPONSE *rsp = NULL; if (!(rsp = OCSP_RESPONSE_new())) goto err; if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) goto err; if (!bs) return rsp; if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) goto err; rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic); if (!ASN1_item_pack(bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response)) goto err; return rsp; err: if (rsp) OCSP_RESPONSE_free(rsp); return NULL; }
/* Set any parameters associated with pkey */ static int rsa_param_encode(const EVP_PKEY *pkey, ASN1_STRING **pstr, int *pstrtype) { const RSA *rsa = pkey->pkey.rsa; *pstr = NULL; /* If RSA it's just NULL type */ if (pkey->ameth->pkey_id == EVP_PKEY_RSA) { *pstrtype = V_ASN1_NULL; return 1; } /* If no PSS parameters we omit parameters entirely */ if (rsa->pss == NULL) { *pstrtype = V_ASN1_UNDEF; return 1; } /* Encode PSS parameters */ if (ASN1_item_pack(rsa->pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), pstr) == NULL) return 0; *pstrtype = V_ASN1_SEQUENCE; return 1; }
ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t) { ASN1_OCTET_STRING *oct; ASN1_TYPE *rt; oct = ASN1_item_pack(s, it, NULL); if (oct == NULL) return NULL; if (t && *t) { rt = *t; } else { rt = ASN1_TYPE_new(); if (rt == NULL) { ASN1_OCTET_STRING_free(oct); return NULL; } if (t) *t = rt; } ASN1_TYPE_set(rt, V_ASN1_SEQUENCE, oct); return rt; }
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, int prf_nid, int keylen) { X509_ALGOR *keyfunc = NULL; PBKDF2PARAM *kdf = NULL; ASN1_OCTET_STRING *osalt = NULL; if(!(kdf = PBKDF2PARAM_new())) goto merr; if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr; kdf->salt->value.octet_string = osalt; kdf->salt->type = V_ASN1_OCTET_STRING; 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_bytes(osalt->data, saltlen)) goto merr; if(iter <= 0) iter = PKCS5_DEFAULT_ITERATIONS; if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr; /* If have a key len set it up */ if(keylen > 0) { if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr; if(!ASN1_INTEGER_set (kdf->keylength, keylen)) goto merr; } /* prf can stay NULL if we are using hmacWithSHA1 */ if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) { kdf->prf = X509_ALGOR_new(); if (!kdf->prf) goto merr; X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); } /* Finally setup the keyfunc structure */ keyfunc = X509_ALGOR_new(); if (!keyfunc) goto merr; keyfunc->algorithm = (ASN1_OBJECT*) OBJ_nid2obj(NID_id_pbkdf2); /* Encode PBKDF2PARAM into parameter of pbe2 */ if(!(keyfunc->parameter = ASN1_TYPE_new())) goto merr; if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM), &keyfunc->parameter->value.sequence)) goto merr; keyfunc->parameter->type = V_ASN1_SEQUENCE; PBKDF2PARAM_free(kdf); return keyfunc; merr: OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); PBKDF2PARAM_free(kdf); X509_ALGOR_free(keyfunc); return NULL; }
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen, unsigned char *aiv, int prf_nid) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid, keylen; EVP_CIPHER_CTX ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; PBE2PARAM *pbe2 = NULL; const ASN1_OBJECT *obj; alg_nid = EVP_CIPHER_nid(cipher); if(alg_nid == NID_undef) { OPENSSL_PUT_ERROR(PKCS8, PKCS8_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 = (ASN1_OBJECT*) obj; if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; /* Create random IV */ if (EVP_CIPHER_iv_length(cipher)) { if (aiv) memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); else if (!RAND_bytes(iv, EVP_CIPHER_iv_length(cipher))) goto err; } EVP_CIPHER_CTX_init(&ctx); /* Dummy cipherinit to just setup the IV, and PRF */ if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0)) goto err; if(param_to_asn1(&ctx, scheme->parameter) < 0) { OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } /* If prf NID unspecified see if cipher has a preference. * An error is OK here: just means use default PRF. */ if ((prf_nid == -1) && EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { ERR_clear_error(); prf_nid = NID_hmacWithSHA1; } EVP_CIPHER_CTX_cleanup(&ctx); /* If its RC2 then we'd better setup the key length */ if(alg_nid == NID_rc2_cbc) keylen = EVP_CIPHER_key_length(cipher); else keylen = -1; /* Setup keyfunc */ X509_ALGOR_free(pbe2->keyfunc); pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen); if (!pbe2->keyfunc) goto merr; /* Now set up top level AlgorithmIdentifier */ if(!(ret = X509_ALGOR_new())) goto merr; if(!(ret->parameter = ASN1_TYPE_new())) goto merr; ret->algorithm = (ASN1_OBJECT*) OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM), &ret->parameter->value.sequence)) goto merr; ret->parameter->type = V_ASN1_SEQUENCE; PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; merr: OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); /* Note 'scheme' is freed as part of pbe2 */ X509_ALGOR_free(kalg); X509_ALGOR_free(ret); return NULL; }
static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) { int pad_mode; EVP_PKEY_CTX *pkctx = ctx->pctx; if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; if (pad_mode == RSA_PKCS1_PADDING) return 2; if (pad_mode == RSA_PKCS1_PSS_PADDING) { const EVP_MD *sigmd, *mgf1md; RSA_PSS_PARAMS *pss = NULL; X509_ALGOR *mgf1alg = NULL; ASN1_STRING *os1 = NULL, *os2 = NULL; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; sigmd = EVP_MD_CTX_md(ctx); if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) goto err; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) goto err; if (saltlen == -1) saltlen = EVP_MD_size(sigmd); else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) saltlen--; } pss = RSA_PSS_PARAMS_new(); if (!pss) goto err; if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength) goto err; if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) goto err; } if (EVP_MD_type(sigmd) != NID_sha1) { pss->hashAlgorithm = X509_ALGOR_new(); if (!pss->hashAlgorithm) goto err; X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); } if (EVP_MD_type(mgf1md) != NID_sha1) { ASN1_STRING *stmp = NULL; /* need to embed algorithm ID inside another */ mgf1alg = X509_ALGOR_new(); X509_ALGOR_set_md(mgf1alg, mgf1md); if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) goto err; pss->maskGenAlgorithm = X509_ALGOR_new(); if (!pss->maskGenAlgorithm) goto err; X509_ALGOR_set0(pss->maskGenAlgorithm, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1)) goto err; if (alg2) { os2 = ASN1_STRING_dup(os1); if (!os2) goto err; X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os2); } X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os1); os1 = os2 = NULL; rv = 3; err: if (mgf1alg) X509_ALGOR_free(mgf1alg); if (pss) RSA_PSS_PARAMS_free(pss); if (os1) ASN1_STRING_free(os1); return rv; } return 2; }
int PKI_X509_OCSP_RESP_DATA_sign (PKI_X509_OCSP_RESP *resp, PKI_X509_KEYPAIR *k, PKI_DIGEST_ALG *md ) { int ret = 0; OCSP_BASICRESP *bsrp = NULL; PKI_X509_OCSP_RESP_VALUE *resp_val = NULL; PKI_OCSP_RESP *r = NULL; if (!resp || !resp->value || !k || !k->value) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; } r = resp->value; if (r->bs == NULL) { PKI_ERROR(PKI_ERR_OCSP_RESP_SIGN, NULL); return PKI_ERR; } // If no digest is given, let's use the default one if (!md) md = PKI_DIGEST_ALG_SHA1; // DEBUG ONLY: Use this to check correctness /* PKI_X509_KEYPAIR_VALUE *key_val = NULL; key_val = PKI_X509_get_value(k); if (!OCSP_BASICRESP_sign(r->bs, key_val, md, 0)) { PKI_log_debug("ERROR: Can not sign with OCSP_BASICRESP_sign! %s!", ERR_error_string(ERR_get_error(), NULL)); return PKI_ERR; } */ // Using the generic signing function ret = PKI_X509_sign(resp, md, k); if (ret == PKI_ERR) { PKI_ERROR(PKI_ERR_OCSP_RESP_SIGN, ERR_error_string(ERR_get_error(), NULL)); r->bs->signature = NULL; return PKI_ERR; } resp_val = r->resp; bsrp = r->bs; // In case the responseBytes are not already set, let's generate them ourselves if (!resp_val->responseBytes) { if (!(resp_val->responseBytes = OCSP_RESPBYTES_new())) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return PKI_ERR; } resp_val->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic); } /* Now add the encoded data to the request bytes */ if (!ASN1_item_pack(bsrp, ASN1_ITEM_rptr(OCSP_BASICRESP), &resp_val->responseBytes->response)) { PKI_ERROR(PKI_ERR_OCSP_RESP_ENCODE, NULL); return PKI_ERR; } return ( PKI_OK ); }
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen, unsigned char *aiv, int prf_nid) { 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_IV, 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)) { if (aiv) memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) goto err; } EVP_CIPHER_CTX_init(&ctx); /* Dummy cipherinit to just setup the IV, and PRF */ 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_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } /* If prf NID unspecified see if cipher has a preference. * An error is OK here: just means use default PRF. */ if ((prf_nid == -1) && EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { ERR_clear_error(); prf_nid = NID_hmacWithSHA1; } 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 if we are using hmacWithSHA1 */ if (prf_nid != NID_hmacWithSHA1) { kdf->prf = X509_ALGOR_new(); if (!kdf->prf) goto merr; X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); } /* 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_item_pack(kdf, ASN1_ITEM_rptr(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_item_pack(pbe2, ASN1_ITEM_rptr(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_IV,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; }
CMS_RecipientInfo * CMS_add0_recipient_password(CMS_ContentInfo *cms, int iter, int wrap_nid, int pbe_nid, unsigned char *pass, ssize_t passlen, const EVP_CIPHER *kekciph) { CMS_RecipientInfo *ri = NULL; CMS_EnvelopedData *env; CMS_PasswordRecipientInfo *pwri; EVP_CIPHER_CTX ctx; X509_ALGOR *encalg = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; int ivlen; env = cms_get0_enveloped(cms); if (!env) return NULL; if (wrap_nid <= 0) wrap_nid = NID_id_alg_PWRI_KEK; if (pbe_nid <= 0) pbe_nid = NID_id_pbkdf2; /* Get from enveloped data */ if (kekciph == NULL) kekciph = env->encryptedContentInfo->cipher; if (kekciph == NULL) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); return NULL; } if (wrap_nid != NID_id_alg_PWRI_KEK) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); return NULL; } /* Setup algorithm identifier for cipher */ encalg = X509_ALGOR_new(); EVP_CIPHER_CTX_init(&ctx); if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); goto err; } ivlen = EVP_CIPHER_CTX_iv_length(&ctx); if (ivlen > 0) { arc4random_buf(iv, ivlen); if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); goto err; } encalg->parameter = ASN1_TYPE_new(); if (!encalg->parameter) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } } encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx)); EVP_CIPHER_CTX_cleanup(&ctx); /* Initialize recipient info */ ri = M_ASN1_new_of(CMS_RecipientInfo); if (!ri) goto merr; ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); if (!ri->d.pwri) goto merr; ri->type = CMS_RECIPINFO_PASS; pwri = ri->d.pwri; /* Since this is overwritten, free up empty structure already there */ X509_ALGOR_free(pwri->keyEncryptionAlgorithm); pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); if (!pwri->keyEncryptionAlgorithm) goto merr; pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); if (!pwri->keyEncryptionAlgorithm->parameter) goto merr; if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), &pwri->keyEncryptionAlgorithm->parameter->value.sequence)) goto merr; pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; X509_ALGOR_free(encalg); encalg = NULL; /* Setup PBE algorithm */ pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); if (!pwri->keyDerivationAlgorithm) goto err; CMS_RecipientInfo_set0_password(ri, pass, passlen); pwri->version = 0; if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) goto merr; return ri; merr: CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); err: EVP_CIPHER_CTX_cleanup(&ctx); if (ri) M_ASN1_free_of(ri, CMS_RecipientInfo); if (encalg) X509_ALGOR_free(encalg); return NULL; }