static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert) { int ret = 0; TS_REQ *ts_req = NULL; int len; TS_MSG_IMPRINT *msg_imprint = NULL; X509_ALGOR *algo = NULL; unsigned char *data = NULL; ASN1_OBJECT *policy_obj = NULL; ASN1_INTEGER *nonce_asn1 = NULL; if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL) goto err; if ((ts_req = TS_REQ_new()) == NULL) goto err; if (!TS_REQ_set_version(ts_req, 1)) goto err; if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL) goto err; if ((algo = X509_ALGOR_new()) == NULL) goto err; if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL) goto err; if ((algo->parameter = ASN1_TYPE_new()) == NULL) goto err; algo->parameter->type = V_ASN1_NULL; if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err; if ((len = create_digest(data_bio, digest, md, &data)) == 0) goto err; if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err; if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err; if (policy && (policy_obj = txt2obj(policy)) == NULL) goto err; if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err; /* Setting nonce if requested. */ if (!no_nonce && (nonce_asn1 = create_nonce(NONCE_LENGTH)) == NULL) goto err; if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err; if (!TS_REQ_set_cert_req(ts_req, cert)) goto err; ret = 1; err: if (!ret) { TS_REQ_free(ts_req); ts_req = NULL; BIO_printf(bio_err, "could not create query\n"); ERR_print_errors(bio_err); } TS_MSG_IMPRINT_free(msg_imprint); X509_ALGOR_free(algo); OPENSSL_free(data); ASN1_OBJECT_free(policy_obj); ASN1_INTEGER_free(nonce_asn1); return ts_req; }
static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) { int rv; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; pss = rsa_pss_decode(sigalg, &maskHash); rv = rsa_pss_param_print(bp, pss, maskHash, indent); if (pss) RSA_PSS_PARAMS_free(pss); if (maskHash) X509_ALGOR_free(maskHash); if (!rv) return 0; } else if (!sig && BIO_puts(bp, "\n") <= 0) return 0; if (sig) return X509_signature_dump(bp, sig, indent); return 1; }
void X509_KEY_free(X509 *a) { int i; if (a == NULL) return; i=CRYPTO_add_lock(&a->references,-1,CRYPTO_LOCK_X509_KEY); #ifdef REF_PRINT REF_PRINT("X509_KEY",a); #endif if (i > 0) return; #ifdef REF_CHECK if (i < 0) { fprintf(stderr,"X509_KEY_free, bad reference count\n"); abort(); } #endif X509_CINF_free(a->cert_info); X509_ALGOR_free(a->sig_alg); ASN1_BIT_STRING_free(a->signature); OPENSSL_free(a); }
TS_REQ* get_timestamp_request(char* hash, int hash_size, ASN1_INTEGER *nonce_asn1) { int ret = 0; TS_REQ *ts_req = NULL; TS_MSG_IMPRINT *msg_imprint = NULL; X509_ALGOR *algo = NULL; unsigned char *data = NULL; ASN1_OBJECT *policy_obj = NULL; const EVP_MD* md = NULL; /* Setting default message digest. */ if ((md = EVP_get_digestbyname("sha256")) == NULL) { goto err; } /* Creating request object. */ if ((ts_req = TS_REQ_new()) == NULL) { goto err; } /* Setting version. */ if (!TS_REQ_set_version(ts_req, 1)) goto err; /* Creating and adding MSG_IMPRINT object. */ if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL) { goto err; } /* Adding algorithm. */ if ((algo = X509_ALGOR_new()) == NULL) { goto err; } if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL) { goto err; } if ((algo->parameter = ASN1_TYPE_new()) == NULL) { goto err; } algo->parameter->type = V_ASN1_NULL; if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err; /* Adding message digest. */ if (!TS_MSG_IMPRINT_set_msg(msg_imprint, (unsigned char*)hash, hash_size)) goto err; if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err; /* Setting policy if requested. */ if ((policy_obj = OBJ_txt2obj("1.1.3", 0)) == NULL) { goto err; } if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err; /* Setting nonce if requested. */ if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err; /* Setting certificate request flag if requested. */ if (!TS_REQ_set_cert_req(ts_req, 1)) goto err; ret = 1; err: if (!ret) { TS_REQ_free(ts_req); ts_req = NULL; } TS_MSG_IMPRINT_free(msg_imprint); X509_ALGOR_free(algo); OPENSSL_free(data); ASN1_OBJECT_free(policy_obj); return ts_req; }
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; }
static int dh_cms_encrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pctx; EVP_PKEY *pkey; EVP_CIPHER_CTX *ctx; int keylen; X509_ALGOR *talg, *wrap_alg = NULL; ASN1_OBJECT *aoid; ASN1_BIT_STRING *pubkey; ASN1_STRING *wrap_str; ASN1_OCTET_STRING *ukm; unsigned char *penc = NULL, *dukm = NULL; int penclen; size_t dukmlen = 0; int rv = 0; int kdf_type, wrap_nid; const EVP_MD *kdf_md; pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!pctx) return 0; /* Get ephemeral key */ pkey = EVP_PKEY_CTX_get0_pkey(pctx); if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, NULL, NULL, NULL)) goto err; X509_ALGOR_get0(&aoid, NULL, NULL, talg); /* Is everything uninitialised? */ if (aoid == OBJ_nid2obj(NID_undef)) { ASN1_INTEGER *pubk; pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL); if (!pubk) goto err; /* Set the key */ penclen = i2d_ASN1_INTEGER(pubk, &penc); ASN1_INTEGER_free(pubk); if (penclen <= 0) goto err; ASN1_STRING_set0(pubkey, penc, penclen); pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; penc = NULL; X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), V_ASN1_UNDEF, NULL); } /* See if custom paraneters set */ kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); if (kdf_type <= 0) goto err; if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) goto err; if (kdf_type == EVP_PKEY_DH_KDF_NONE) { kdf_type = EVP_PKEY_DH_KDF_X9_42; if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) goto err; } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) /* Unknown KDF */ goto err; if (kdf_md == NULL) { /* Only SHA1 supported */ kdf_md = EVP_sha1(); if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) goto err; } else if (EVP_MD_type(kdf_md) != NID_sha1) /* Unsupported digest */ goto err; if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) goto err; /* Get wrap NID */ ctx = CMS_RecipientInfo_kari_get0_ctx(ri); wrap_nid = EVP_CIPHER_CTX_type(ctx); if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) goto err; keylen = EVP_CIPHER_CTX_key_length(ctx); /* Package wrap algorithm in an AlgorithmIdentifier */ wrap_alg = X509_ALGOR_new(); if (!wrap_alg) goto err; wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); wrap_alg->parameter = ASN1_TYPE_new(); if (!wrap_alg->parameter) goto err; if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) goto err; if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { ASN1_TYPE_free(wrap_alg->parameter); wrap_alg->parameter = NULL; } if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) goto err; if (ukm) { dukmlen = ASN1_STRING_length(ukm); dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); if (!dukm) goto err; } if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) goto err; dukm = NULL; /* * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter * of another AlgorithmIdentifier. */ penc = NULL; penclen = i2d_X509_ALGOR(wrap_alg, &penc); if (!penc || !penclen) goto err; wrap_str = ASN1_STRING_new(); if (!wrap_str) goto err; ASN1_STRING_set0(wrap_str, penc, penclen); penc = NULL; X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), V_ASN1_SEQUENCE, wrap_str); rv = 1; err: if (penc) OPENSSL_free(penc); if (wrap_alg) X509_ALGOR_free(wrap_alg); return rv; }
static int rsa_cms_decrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pkctx; X509_ALGOR *cmsalg; int nid; int rv = -1; unsigned char *label = NULL; int labellen = 0; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_OAEP_PARAMS *oaep; X509_ALGOR *maskHash; pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!pkctx) return 0; if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) return -1; nid = OBJ_obj2nid(cmsalg->algorithm); if (nid == NID_rsaEncryption) return 1; if (nid != NID_rsaesOaep) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); return -1; } /* Decode OAEP parameters */ oaep = rsa_oaep_decode(cmsalg, &maskHash); if (oaep == NULL) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(oaep->maskGenFunc, maskHash); if (!mgf1md) goto err; md = rsa_algor_to_md(oaep->hashFunc); if (!md) goto err; if (oaep->pSourceFunc) { X509_ALGOR *plab = oaep->pSourceFunc; if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); goto err; } if (plab->parameter->type != V_ASN1_OCTET_STRING) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); goto err; } label = plab->parameter->value.octet_string->data; /* Stop label being freed when OAEP parameters are freed */ plab->parameter->value.octet_string->data = NULL; labellen = plab->parameter->value.octet_string->length; } if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) goto err; /* Carry on */ rv = 1; err: RSA_OAEP_PARAMS_free(oaep); X509_ALGOR_free(maskHash); return rv; }
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, const EVP_MD *md, unsigned int flags) { CMS_SignedData *sd; CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; if(!X509_check_private_key(signer, pk)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } sd = cms_signed_data_init(cms); if (!sd) goto err; si = M_ASN1_new_of(CMS_SignerInfo); if (!si) goto merr; X509_check_purpose(signer, -1, -1); CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); si->pkey = pk; si->signer = signer; if (flags & CMS_USE_KEYID) { si->version = 3; if (sd->version < 3) sd->version = 3; type = CMS_SIGNERINFO_KEYIDENTIFIER; } else { type = CMS_SIGNERINFO_ISSUER_SERIAL; si->version = 1; } if (!cms_set1_SignerIdentifier(si->sid, signer, type)) goto err; /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */ if (md == NULL) md = EVP_sha1(); /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */ if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } cms_DigestAlgorithm_set(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { ASN1_OBJECT *aoid; alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); X509_ALGOR_get0(&aoid, NULL, NULL, alg); if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) break; } if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { alg = X509_ALGOR_new(); if (!alg) goto merr; cms_DigestAlgorithm_set(alg, md); if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { X509_ALGOR_free(alg); goto merr; } } /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, * hard code algorithm parameters. */ switch (pk->type) { case EVP_PKEY_RSA: X509_ALGOR_set0(si->signatureAlgorithm, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); break; case EVP_PKEY_DSA: X509_ALGOR_set0(si->signatureAlgorithm, OBJ_nid2obj(NID_dsaWithSHA1), V_ASN1_UNDEF, 0); break; case EVP_PKEY_EC: X509_ALGOR_set0(si->signatureAlgorithm, OBJ_nid2obj(NID_ecdsa_with_SHA1), V_ASN1_UNDEF, 0); break; default: CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } if (!(flags & CMS_NOATTR)) { /* Initialialize signed attributes strutucture so other * attributes such as signing time etc are added later * even if we add none here. */ if (!si->signedAttrs) { si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); if (!si->signedAttrs) goto merr; } if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; i = CMS_add_standard_smimecap(&smcap); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); if (!i) goto merr; } if (flags & CMS_REUSE_DIGEST) { if (!cms_copy_messageDigest(cms, si)) goto err; if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si)) goto err; } } if (!(flags & CMS_NOCERTS)) { /* NB ignore -1 return for duplicate cert */ if (!CMS_add1_cert(cms, signer)) goto merr; } if (!sd->signerInfos) sd->signerInfos = sk_CMS_SignerInfo_new_null(); if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) goto merr; return si; merr: CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); err: if (si) M_ASN1_free_of(si, CMS_SignerInfo); return NULL; }
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; }
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, const EVP_MD *md, unsigned int flags) { CMS_SignedData *sd; CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; if (!X509_check_private_key(signer, pk)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } sd = cms_signed_data_init(cms); if (!sd) goto err; si = M_ASN1_new_of(CMS_SignerInfo); if (!si) goto merr; /* Call for side-effect of computing hash and caching extensions */ X509_check_purpose(signer, -1, -1); X509_up_ref(signer); EVP_PKEY_up_ref(pk); si->pkey = pk; si->signer = signer; si->mctx = EVP_MD_CTX_new(); si->pctx = NULL; if (si->mctx == NULL) { CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); goto err; } if (flags & CMS_USE_KEYID) { si->version = 3; if (sd->version < 3) sd->version = 3; type = CMS_SIGNERINFO_KEYIDENTIFIER; } else { type = CMS_SIGNERINFO_ISSUER_SERIAL; si->version = 1; } if (!cms_set1_SignerIdentifier(si->sid, signer, type)) goto err; if (md == NULL) { int def_nid; if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) goto err; md = EVP_get_digestbynid(def_nid); if (md == NULL) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); goto err; } } if (!md) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); goto err; } X509_ALGOR_set_md(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { const ASN1_OBJECT *aoid; alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); X509_ALGOR_get0(&aoid, NULL, NULL, alg); if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) break; } if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { alg = X509_ALGOR_new(); if (alg == NULL) goto merr; X509_ALGOR_set_md(alg, md); if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { X509_ALGOR_free(alg); goto merr; } } if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) goto err; if (!(flags & CMS_NOATTR)) { /* * Initialize signed attributes structure so other attributes * such as signing time etc are added later even if we add none here. */ if (!si->signedAttrs) { si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); if (!si->signedAttrs) goto merr; } if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; i = CMS_add_standard_smimecap(&smcap); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); if (!i) goto merr; } if (flags & CMS_REUSE_DIGEST) { if (!cms_copy_messageDigest(cms, si)) goto err; if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && !CMS_SignerInfo_sign(si)) goto err; } } if (!(flags & CMS_NOCERTS)) { /* NB ignore -1 return for duplicate cert */ if (!CMS_add1_cert(cms, signer)) goto merr; } if (flags & CMS_KEY_PARAM) { if (flags & CMS_NOATTR) { si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); if (si->pctx == NULL) goto err; if (EVP_PKEY_sign_init(si->pctx) <= 0) goto err; if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) goto err; } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= 0) goto err; } if (!sd->signerInfos) sd->signerInfos = sk_CMS_SignerInfo_new_null(); if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) goto merr; return si; merr: CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(si, CMS_SignerInfo); return NULL; }
static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, size_t keylen, uint64_t N, uint64_t r, uint64_t p) { X509_ALGOR *keyfunc = NULL; SCRYPT_PARAMS *sparam = NULL; sparam = SCRYPT_PARAMS_new(); if (sparam == NULL) goto merr; if (!saltlen) saltlen = PKCS5_SALT_LEN; /* This will either copy salt or grow the buffer */ if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) goto merr; if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0) goto err; if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0) goto merr; if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0) goto merr; if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0) goto merr; /* If have a key len set it up */ if (keylen > 0) { sparam->keyLength = ASN1_INTEGER_new(); if (sparam->keyLength == NULL) goto merr; if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0) goto merr; } /* Finally setup the keyfunc structure */ keyfunc = X509_ALGOR_new(); if (keyfunc == NULL) goto merr; keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt); /* Encode SCRYPT_PARAMS into parameter of pbe2 */ if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam, &keyfunc->parameter) == NULL) goto merr; SCRYPT_PARAMS_free(sparam); return keyfunc; merr: ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE); err: SCRYPT_PARAMS_free(sparam); X509_ALGOR_free(keyfunc); return NULL; }
static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) { int rv = 0; X509_ALGOR *alg, *kekalg = NULL; ASN1_OCTET_STRING *ukm; const unsigned char *p; unsigned char *der = NULL; int plen, keylen; const EVP_CIPHER *kekcipher; EVP_CIPHER_CTX *kekctx; if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) return 0; if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR); return 0; } if (alg->parameter->type != V_ASN1_SEQUENCE) return 0; p = alg->parameter->value.sequence->data; plen = alg->parameter->value.sequence->length; kekalg = d2i_X509_ALGOR(NULL, &p, plen); if (!kekalg) goto err; kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); if (!kekctx) goto err; kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) goto err; if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) goto err; if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) goto err; keylen = EVP_CIPHER_CTX_key_length(kekctx); if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) goto err; plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); if (!plen) goto err; if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) goto err; der = NULL; rv = 1; err: if (kekalg) X509_ALGOR_free(kekalg); if (der) OPENSSL_free(der); return rv; }
/* PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a * PKCS#12 structure. */ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, struct pkcs12_context *ctx) { CBS content_type, wrapped_contents, contents, content_infos; int nid, ret = 0; if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || !CBS_get_asn1(content_info, &wrapped_contents, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_parse, PKCS8_R_BAD_PKCS12_DATA); goto err; } nid = OBJ_cbs2nid(&content_type); if (nid == NID_pkcs7_encrypted) { /* See https://tools.ietf.org/html/rfc2315#section-13. * * PKCS#7 encrypted data inside a PKCS#12 structure is generally an * encrypted certificate bag and it's generally encrypted with 40-bit * RC2-CBC. */ CBS version_bytes, eci, contents_type, ai, encrypted_contents; X509_ALGOR *algor = NULL; const uint8_t *inp; uint8_t *out; size_t out_len; if (!CBS_get_asn1(&wrapped_contents, &contents, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&contents, &version_bytes, CBS_ASN1_INTEGER) || /* EncryptedContentInfo, see * https://tools.ietf.org/html/rfc2315#section-10.1 */ !CBS_get_asn1(&contents, &eci, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&eci, &contents_type, CBS_ASN1_OBJECT) || /* AlgorithmIdentifier, see * https://tools.ietf.org/html/rfc5280#section-4.1.1.2 */ !CBS_get_asn1_element(&eci, &ai, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&eci, &encrypted_contents, CBS_ASN1_CONTEXT_SPECIFIC | 0)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } inp = CBS_data(&ai); algor = d2i_X509_ALGOR(NULL, &inp, CBS_len(&ai)); if (algor == NULL) { goto err; } if (inp != CBS_data(&ai) + CBS_len(&ai)) { X509_ALGOR_free(algor); OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (!pbe_crypt(algor, ctx->password, ctx->password_len, CBS_data(&encrypted_contents), CBS_len(&encrypted_contents), &out, &out_len, 0 /* decrypt */)) { X509_ALGOR_free(algor); goto err; } X509_ALGOR_free(algor); CBS_init(&content_infos, out, out_len); ret = PKCS12_handle_content_infos(&content_infos, depth + 1, ctx); OPENSSL_free(out); } else if (nid == NID_pkcs7_data) { CBS octet_string_contents; if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents, CBS_ASN1_OCTETSTRING)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } ret = PKCS12_handle_content_infos(&octet_string_contents, depth + 1, ctx); } else if (nid == NID_pkcs8ShroudedKeyBag) { /* See ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf, section * 4.2.2. */ const uint8_t *inp = CBS_data(&wrapped_contents); PKCS8_PRIV_KEY_INFO *pki = NULL; X509_SIG *encrypted = NULL; if (*ctx->out_key) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12); goto err; } /* encrypted isn't actually an X.509 signature, but it has the same * structure as one and so |X509_SIG| is reused to store it. */ encrypted = d2i_X509_SIG(NULL, &inp, CBS_len(&wrapped_contents)); if (encrypted == NULL) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (inp != CBS_data(&wrapped_contents) + CBS_len(&wrapped_contents)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); X509_SIG_free(encrypted); goto err; } pki = PKCS8_decrypt_pbe(encrypted, ctx->password, ctx->password_len); X509_SIG_free(encrypted); if (pki == NULL) { goto err; } *ctx->out_key = EVP_PKCS82PKEY(pki); PKCS8_PRIV_KEY_INFO_free(pki); if (ctx->out_key == NULL) { goto err; } ret = 1; } else if (nid == NID_certBag) { CBS cert_bag, cert_type, wrapped_cert, cert; if (!CBS_get_asn1(&wrapped_contents, &cert_bag, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || !CBS_get_asn1(&cert_bag, &wrapped_cert, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || !CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (OBJ_cbs2nid(&cert_type) == NID_x509Certificate) { const uint8_t *inp = CBS_data(&cert); X509 *x509 = d2i_X509(NULL, &inp, CBS_len(&cert)); if (!x509) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (inp != CBS_data(&cert) + CBS_len(&cert)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); X509_free(x509); goto err; } if (0 == sk_X509_push(ctx->out_certs, x509)) { X509_free(x509); goto err; } } ret = 1; } else { /* Unknown element type - ignore it. */ ret = 1; } err: return ret; }
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; }
int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, int en_de) { CMS_EncryptedContentInfo *ec; CMS_PasswordRecipientInfo *pwri; const unsigned char *p = NULL; int plen; int r = 0; X509_ALGOR *algtmp, *kekalg = NULL; EVP_CIPHER_CTX kekctx; const EVP_CIPHER *kekcipher; unsigned char *key = NULL; size_t keylen; ec = cms->d.envelopedData->encryptedContentInfo; pwri = ri->d.pwri; EVP_CIPHER_CTX_init(&kekctx); if (!pwri->pass) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); return 0; } algtmp = pwri->keyEncryptionAlgorithm; if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); return 0; } if (algtmp->parameter->type == V_ASN1_SEQUENCE) { p = algtmp->parameter->value.sequence->data; plen = algtmp->parameter->value.sequence->length; kekalg = d2i_X509_ALGOR(NULL, &p, plen); } if (kekalg == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); return 0; } kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); if (!kekcipher) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); goto err; } /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) goto err; EVP_CIPHER_CTX_set_padding(&kekctx, 0); if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } algtmp = pwri->keyDerivationAlgorithm; /* Finish password based key derivation to setup key in "ctx" */ if (EVP_PBE_CipherInit(algtmp->algorithm, (char *)pwri->pass, pwri->passlen, algtmp->parameter, &kekctx, en_de) < 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); goto err; } /* Finally wrap/unwrap the key */ if (en_de) { if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) goto err; key = malloc(keylen); if (!key) goto err; if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx)) goto err; pwri->encryptedKey->data = key; pwri->encryptedKey->length = keylen; } else { key = malloc(pwri->encryptedKey->length); if (!key) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!kek_unwrap_key(key, &keylen, pwri->encryptedKey->data, pwri->encryptedKey->length, &kekctx)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); goto err; } ec->key = key; ec->keylen = keylen; } r = 1; err: EVP_CIPHER_CTX_cleanup(&kekctx); if (!r && key) free(key); X509_ALGOR_free(kekalg); return r; }
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) TINYCLR_SSL_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 = (unsigned char*)OPENSSL_malloc (saltlen))) goto merr; //MS: cast to unsigned char* osalt->length = saltlen; if (salt) TINYCLR_SSL_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; }
static int openssl_xalgor_gc(lua_State* L) { X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); X509_ALGOR_free(alg); return 0; }
int i2d_RSA_NET(RSA *a, unsigned char **pp, int (*cb)(), int sgckey) { int i,j,l[6]; NETSCAPE_PKEY *pkey; unsigned char buf[256],*zz; unsigned char key[EVP_MAX_KEY_LENGTH]; EVP_CIPHER_CTX ctx; X509_ALGOR *alg=NULL; ASN1_OCTET_STRING os,os2; M_ASN1_I2D_vars(a); if (a == NULL) return(0); #ifdef WIN32 r=r; /* shut the damn compiler up :-) */ #endif os.data=os2.data=NULL; if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err; if (!ASN1_INTEGER_set(pkey->version,0)) goto err; if (pkey->algor->algorithm != NULL) ASN1_OBJECT_free(pkey->algor->algorithm); pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption); if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err; pkey->algor->parameter->type=V_ASN1_NULL; l[0]=i2d_RSAPrivateKey(a,NULL); pkey->private_key->length=l[0]; os2.length=i2d_NETSCAPE_PKEY(pkey,NULL); l[1]=i2d_ASN1_OCTET_STRING(&os2,NULL); if ((alg=X509_ALGOR_new()) == NULL) goto err; if (alg->algorithm != NULL) ASN1_OBJECT_free(alg->algorithm); alg->algorithm=OBJ_nid2obj(NID_rc4); if ((alg->parameter=ASN1_TYPE_new()) == NULL) goto err; alg->parameter->type=V_ASN1_NULL; l[2]=i2d_X509_ALGOR(alg,NULL); l[3]=ASN1_object_size(1,l[2]+l[1],V_ASN1_SEQUENCE); #ifndef CONST_STRICT os.data=(unsigned char *)"private-key"; #endif os.length=11; l[4]=i2d_ASN1_OCTET_STRING(&os,NULL); l[5]=ASN1_object_size(1,l[4]+l[3],V_ASN1_SEQUENCE); if (pp == NULL) { if (pkey != NULL) NETSCAPE_PKEY_free(pkey); if (alg != NULL) X509_ALGOR_free(alg); return(l[5]); } if (pkey->private_key->data != NULL) OPENSSL_free(pkey->private_key->data); if ((pkey->private_key->data=(unsigned char *)OPENSSL_malloc(l[0])) == NULL) { ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE); goto err; } zz=pkey->private_key->data; i2d_RSAPrivateKey(a,&zz); if ((os2.data=(unsigned char *)OPENSSL_malloc(os2.length)) == NULL) { ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE); goto err; } zz=os2.data; i2d_NETSCAPE_PKEY(pkey,&zz); if (cb == NULL) cb=EVP_read_pw_string; i=cb(buf,256,"Enter Private Key password:"******"SGCKEYSALT", 10); i = 26; } EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL); memset(buf,0,256); EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit(&ctx,EVP_rc4(),key,NULL); EVP_EncryptUpdate(&ctx,os2.data,&i,os2.data,os2.length); EVP_EncryptFinal(&ctx,&(os2.data[i]),&j); EVP_CIPHER_CTX_cleanup(&ctx); p= *pp; ASN1_put_object(&p,1,l[4]+l[3],V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); i2d_ASN1_OCTET_STRING(&os,&p); ASN1_put_object(&p,1,l[2]+l[1],V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); i2d_X509_ALGOR(alg,&p); i2d_ASN1_OCTET_STRING(&os2,&p); ret=l[5]; err: if (os2.data != NULL) OPENSSL_free(os2.data); if (alg != NULL) X509_ALGOR_free(alg); if (pkey != NULL) NETSCAPE_PKEY_free(pkey); r=r; return(ret); }
void openssl_xalgor_free(X509_ALGOR* alg) { X509_ALGOR_free(alg); }
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pctx; EVP_PKEY *pkey; EVP_CIPHER_CTX *ctx; int keylen; X509_ALGOR *talg, *wrap_alg = NULL; ASN1_OBJECT *aoid; ASN1_BIT_STRING *pubkey; ASN1_STRING *wrap_str; ASN1_OCTET_STRING *ukm; unsigned char *penc = NULL; int penclen; int rv = 0; int ecdh_nid, kdf_type, kdf_nid, wrap_nid; const EVP_MD *kdf_md; pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!pctx) return 0; /* Get ephemeral key */ pkey = EVP_PKEY_CTX_get0_pkey(pctx); if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, NULL, NULL, NULL)) goto err; X509_ALGOR_get0(&aoid, NULL, NULL, talg); /* Is everything uninitialised? */ if (aoid == OBJ_nid2obj(NID_undef)) { EC_KEY *eckey = pkey->pkey.ec; /* Set the key */ unsigned char *p; penclen = i2o_ECPublicKey(eckey, NULL); if (penclen <= 0) goto err; penc = OPENSSL_malloc(penclen); if (!penc) goto err; p = penc; penclen = i2o_ECPublicKey(eckey, &p); if (penclen <= 0) goto err; ASN1_STRING_set0(pubkey, penc, penclen); pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; penc = NULL; X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), V_ASN1_UNDEF, NULL); } /* See if custom paraneters set */ kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); if (kdf_type <= 0) goto err; if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) goto err; ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); if (ecdh_nid < 0) goto err; else if (ecdh_nid == 0) ecdh_nid = NID_dh_std_kdf; else if (ecdh_nid == 1) ecdh_nid = NID_dh_cofactor_kdf; if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { kdf_type = EVP_PKEY_ECDH_KDF_X9_62; if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) goto err; } else /* Uknown KDF */ goto err; if (kdf_md == NULL) { /* Fixme later for better MD */ kdf_md = EVP_sha1(); if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) goto err; } if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) goto err; /* Lookup NID for KDF+cofactor+digest */ if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) goto err; /* Get wrap NID */ ctx = CMS_RecipientInfo_kari_get0_ctx(ri); wrap_nid = EVP_CIPHER_CTX_type(ctx); keylen = EVP_CIPHER_CTX_key_length(ctx); /* Package wrap algorithm in an AlgorithmIdentifier */ wrap_alg = X509_ALGOR_new(); if (!wrap_alg) goto err; wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); wrap_alg->parameter = ASN1_TYPE_new(); if (!wrap_alg->parameter) goto err; if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) goto err; if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { ASN1_TYPE_free(wrap_alg->parameter); wrap_alg->parameter = NULL; } if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) goto err; penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); if (!penclen) goto err; if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) goto err; penc = NULL; /* * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter * of another AlgorithmIdentifier. */ penclen = i2d_X509_ALGOR(wrap_alg, &penc); if (!penc || !penclen) goto err; wrap_str = ASN1_STRING_new(); if (!wrap_str) goto err; ASN1_STRING_set0(wrap_str, penc, penclen); penc = NULL; X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); rv = 1; err: OPENSSL_free(penc); X509_ALGOR_free(wrap_alg); return rv; }
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, const unsigned char *salt, int saltlen, unsigned char *aiv, uint64_t N, uint64_t r, uint64_t p) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid; size_t keylen = 0; EVP_CIPHER_CTX ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; PBE2PARAM *pbe2 = NULL; ASN1_OBJECT *obj; if (!cipher) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER); goto err; } if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ASN1_R_INVALID_SCRYPT_PARAMETERS); goto err; } alg_nid = EVP_CIPHER_type(cipher); if (alg_nid == NID_undef) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); goto err; } obj = OBJ_nid2obj(alg_nid); pbe2 = PBE2PARAM_new(); if (pbe2 == NULL) goto merr; /* Setup the AlgorithmIdentifier for the encryption scheme */ scheme = pbe2->encryption; scheme->algorithm = obj; scheme->parameter = ASN1_TYPE_new(); if (scheme->parameter == NULL) 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)) < 0) goto err; } EVP_CIPHER_CTX_init(&ctx); /* Dummy cipherinit to just setup the IV */ if (EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0) == 0) goto err; if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } 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); /* Setup keyfunc */ X509_ALGOR_free(pbe2->keyfunc); pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p); if (pbe2->keyfunc == NULL) goto merr; /* Now set up top level AlgorithmIdentifier */ ret = X509_ALGOR_new(); if (ret == NULL) goto merr; ret->algorithm = OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2, &ret->parameter) == NULL) goto merr; PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; merr: ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); X509_ALGOR_free(kalg); X509_ALGOR_free(ret); return NULL; }
/* From PSS AlgorithmIdentifier set public key parameters. */ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { int ret = 0; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; EVP_PKEY_CTX *pkctx; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); return 0; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); if (!mgf1md) { goto err; } md = rsa_algor_to_md(pss->hashAlgorithm); if (!md) { goto err; } saltlen = 20; if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH); goto err; } } /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER); goto err; } if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) || !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) || !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) || !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) { goto err; } ret = 1; err: RSA_PSS_PARAMS_free(pss); if (maskHash) { X509_ALGOR_free(maskHash); } return ret; }
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; }
int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data) { long *aLong = NULL; PKI_TIME *aTime = NULL; PKI_INTEGER *aInt = NULL; PKI_X509_NAME *aName = NULL; PKI_X509_KEYPAIR_VALUE *aKey = NULL; int ret = 0; LIBPKI_X509_CERT *xVal = NULL; LIBPKI_X509_ALGOR *alg = NULL; // PKI_X509_CERT_VALUE *xVal = NULL; if ( !x || !x->value || !data || x->type != PKI_DATATYPE_X509_CERT) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (PKI_ERR); } // xVal = PKI_X509_get_value( x ); xVal = x->value; switch( type ) { case PKI_X509_DATA_VERSION: aLong = (long *) data; ret = X509_set_version( xVal, *aLong ); break; case PKI_X509_DATA_SERIAL: aInt = (PKI_INTEGER *) data; ret = X509_set_serialNumber( xVal, aInt); break; case PKI_X509_DATA_SUBJECT: aName = (PKI_X509_NAME *) data; ret = X509_set_subject_name( xVal, aName ); break; case PKI_X509_DATA_ISSUER: aName = (PKI_X509_NAME *) data; ret = X509_set_issuer_name( xVal, aName ); break; case PKI_X509_DATA_NOTBEFORE: aTime = (PKI_TIME *) data; ret = X509_set_notBefore( xVal, aTime ); break; case PKI_X509_DATA_NOTAFTER: aTime = (PKI_TIME *) data; ret = X509_set_notAfter( xVal, aTime ); break; case PKI_X509_DATA_KEYPAIR_VALUE: aKey = data; ret = X509_set_pubkey( xVal, aKey); break; case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG1: alg = data; #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (xVal->cert_info != NULL) xVal->cert_info->signature = alg; #else // Transfer Ownership xVal->cert_info.signature.algorithm = alg->algorithm; xVal->cert_info.signature.parameter = alg->parameter; // Remove the transfered data alg->algorithm = NULL; alg->parameter = NULL; // Free memory X509_ALGOR_free((X509_ALGOR *)data); data = NULL; #endif // Ok ret = 1; break; case PKI_X509_DATA_SIGNATURE_ALG2: // if (xVal->sig_alg != NULL ) X509_ALGOR_free(xVal->sig_alg); alg = data; #if OPENSSL_VERSION_NUMBER < 0x1010000fL xVal->sig_alg = alg; #else // Transfer Ownership xVal->sig_alg.algorithm = alg->algorithm; xVal->sig_alg.parameter = alg->parameter; // Remove the transfered data alg->algorithm = NULL; alg->parameter = NULL; // Free memory X509_ALGOR_free((X509_ALGOR *)alg); data = NULL; // Ok ret = 1; #endif break; default: /* Not Recognized/Supported DATATYPE */ ret = 0; break; } if (!ret) return PKI_ERR; return PKI_OK; }
static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) { int rv = 0; X509_ALGOR *alg, *kekalg = NULL; ASN1_OCTET_STRING *ukm; const unsigned char *p; unsigned char *dukm = NULL; size_t dukmlen = 0; int keylen, plen; const EVP_CIPHER *kekcipher; EVP_CIPHER_CTX *kekctx; if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) goto err; /* * For DH we only have one OID permissible. If ever any more get defined * we will need something cleverer. */ if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR); goto err; } if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0) goto err; if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) goto err; if (alg->parameter->type != V_ASN1_SEQUENCE) goto err; p = alg->parameter->value.sequence->data; plen = alg->parameter->value.sequence->length; kekalg = d2i_X509_ALGOR(NULL, &p, plen); if (!kekalg) goto err; kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); if (!kekctx) goto err; kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) goto err; if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) goto err; if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) goto err; keylen = EVP_CIPHER_CTX_key_length(kekctx); if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) goto err; /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) <= 0) goto err; if (ukm) { dukmlen = ASN1_STRING_length(ukm); dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); if (!dukm) goto err; } if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) goto err; dukm = NULL; rv = 1; err: if (kekalg) X509_ALGOR_free(kekalg); if (dukm) OPENSSL_free(dukm); return rv; }
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, const EVP_MD *md, unsigned int flags) { CMS_SignedData *sd; CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; if (!X509_check_private_key(signer, pk)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } sd = cms_signed_data_init(cms); if (!sd) goto err; si = M_ASN1_new_of(CMS_SignerInfo); if (!si) goto merr; X509_check_purpose(signer, -1, -1); CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); si->pkey = pk; si->signer = signer; if (flags & CMS_USE_KEYID) { si->version = 3; if (sd->version < 3) sd->version = 3; type = CMS_SIGNERINFO_KEYIDENTIFIER; } else { type = CMS_SIGNERINFO_ISSUER_SERIAL; si->version = 1; } if (!cms_set1_SignerIdentifier(si->sid, signer, type)) goto err; if (md == NULL) { int def_nid; if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) goto err; md = EVP_get_digestbynid(def_nid); if (md == NULL) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); goto err; } } if (!md) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); goto err; } cms_DigestAlgorithm_set(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { ASN1_OBJECT *aoid; alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); X509_ALGOR_get0(&aoid, NULL, NULL, alg); if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) break; } if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { alg = X509_ALGOR_new(); if (!alg) goto merr; cms_DigestAlgorithm_set(alg, md); if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { X509_ALGOR_free(alg); goto merr; } } if (pk->ameth && pk->ameth->pkey_ctrl) { i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN, 0, si); if (i == -2) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } if (i <= 0) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE); goto err; } } if (!(flags & CMS_NOATTR)) { /* * Initialialize signed attributes strutucture so other attributes * such as signing time etc are added later even if we add none here. */ if (!si->signedAttrs) { si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); if (!si->signedAttrs) goto merr; } if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; i = CMS_add_standard_smimecap(&smcap); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); if (!i) goto merr; } if (flags & CMS_REUSE_DIGEST) { if (!cms_copy_messageDigest(cms, si)) goto err; if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si)) goto err; } } if (!(flags & CMS_NOCERTS)) { /* NB ignore -1 return for duplicate cert */ if (!CMS_add1_cert(cms, signer)) goto merr; } if (!sd->signerInfos) sd->signerInfos = sk_CMS_SignerInfo_new_null(); if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) goto merr; return si; merr: CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); err: if (si) M_ASN1_free_of(si, CMS_SignerInfo); return NULL; }
static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { int rv = -1; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); if (!mgf1md) goto err; md = rsa_algor_to_md(pss->hashAlgorithm); if (!md) goto err; if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* * Could perform more salt length sanity checks but the main RSA * routines will trap other invalid values anyway. */ if (saltlen < 0) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH); goto err; } } else saltlen = 20; /* * low-level routines support only trailer field 0xbc (value 1) and * PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER); goto err; } /* We have all parameters now set up context */ if (pkey) { if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) goto err; } else { const EVP_MD *checkmd; if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) goto err; if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); goto err; } } if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; /* Carry on */ rv = 1; err: RSA_PSS_PARAMS_free(pss); X509_ALGOR_free(maskHash); return rv; }
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 (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) goto err; /* Dummy cipherinit to just setup the IV */ EVP_CipherInit(&ctx, cipher, 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); 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(kdf, (i2d_func_t)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(pbe2, (i2d_func_t)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; }
int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, ASN1_PCTX *pctx) { assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); int rv = 0; X509_ALGOR *maskHash; RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); if (!pss) { if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) { goto err; } rv = 1; goto err; } if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, indent, 128) || BIO_puts(bp, "Hash Algorithm: ") <= 0) { goto err; } if (pss->hashAlgorithm) { if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) { goto err; } } else if (BIO_puts(bp, "sha1 (default)") <= 0) { goto err; } if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, indent, 128) || BIO_puts(bp, "Mask Algorithm: ") <= 0) { goto err; } if (pss->maskGenAlgorithm) { if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || BIO_puts(bp, " with ") <= 0) { goto err; } if (maskHash) { if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) { goto err; } } else if (BIO_puts(bp, "INVALID") <= 0) { goto err; } } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { goto err; } BIO_puts(bp, "\n"); if (!BIO_indent(bp, indent, 128) || BIO_puts(bp, "Salt Length: 0x") <= 0) { goto err; } if (pss->saltLength) { if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) { goto err; } } else if (BIO_puts(bp, "14 (default)") <= 0) { goto err; } BIO_puts(bp, "\n"); if (!BIO_indent(bp, indent, 128) || BIO_puts(bp, "Trailer Field: 0x") <= 0) { goto err; } if (pss->trailerField) { if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) { goto err; } } else if (BIO_puts(bp, "BC (default)") <= 0) { goto err; } BIO_puts(bp, "\n"); rv = 1; err: RSA_PSS_PARAMS_free(pss); X509_ALGOR_free(maskHash); return rv; }
static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey) { int rv = -1; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; EVP_PKEY_CTX *pkctx; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS); goto err; } /* Check mask and lookup mask hash algorithm */ if (pss->maskGenAlgorithm) { if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM); goto err; } if (!maskHash) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER); goto err; } mgf1md = EVP_get_digestbyobj(maskHash->algorithm); if (mgf1md == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST); goto err; } } else mgf1md = EVP_sha1(); if (pss->hashAlgorithm) { md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm); if (md == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST); goto err; } } else md = EVP_sha1(); if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH); goto err; } } else saltlen = 20; /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER); goto err; } /* We have all parameters now set up context */ if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; /* Carry on */ rv = 2; err: RSA_PSS_PARAMS_free(pss); if (maskHash) X509_ALGOR_free(maskHash); return rv; }