Use in CMP+CRMF libctx and propq param added to sign/verify/HMAC/decrypt

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11808)
This commit is contained in:
Dr. David von Oheimb 2020-08-13 17:44:54 +02:00
parent cac30a69bc
commit 6d1f50b520
28 changed files with 387 additions and 341 deletions

View File

@ -1653,8 +1653,11 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
CMP_err1("digest algorithm name not recognized: '%s'", opt_digest);
goto err;
}
(void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest);
(void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest);
if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest)
|| !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest)) {
CMP_err1("digest algorithm name not supported: '%s'", opt_digest);
goto err;
}
}
if (opt_mac != NULL) {

View File

@ -425,10 +425,8 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
goto err;
case OSSL_CMP_PKISTATUS_grantedWithMods:
ossl_cmp_warn(ctx, "received \"grantedWithMods\" for certificate");
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
break;
case OSSL_CMP_PKISTATUS_accepted:
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
break;
/* get all information in case of a rejection before going to error */
case OSSL_CMP_PKISTATUS_rejection:
@ -438,19 +436,16 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
case OSSL_CMP_PKISTATUS_revocationWarning:
ossl_cmp_warn(ctx,
"received \"revocationWarning\" - a revocation of the cert is imminent");
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
break;
case OSSL_CMP_PKISTATUS_revocationNotification:
ossl_cmp_warn(ctx,
"received \"revocationNotification\" - a revocation of the cert has occurred");
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
break;
case OSSL_CMP_PKISTATUS_keyUpdateWarning:
if (bodytype != OSSL_CMP_PKIBODY_KUR) {
CMPerr(0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING);
goto err;
}
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
break;
default:
ossl_cmp_log1(ERROR, ctx,
@ -459,6 +454,7 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
CMPerr(0, CMP_R_UNKNOWN_PKISTATUS);
goto err;
}
crt = ossl_cmp_certresponse_get1_cert(crep, ctx, privkey);
if (crt == NULL) /* according to PKIStatus, we can expect a cert */
CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND);

View File

@ -90,6 +90,20 @@ int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
return 0;
}
static int cmp_ctx_set_md(OSSL_CMP_CTX *ctx, EVP_MD **pmd, int nid)
{
EVP_MD *md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propq);
/* fetching in advance to be able to throw error early if unsupported */
if (md == NULL) {
CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM);
return 0;
}
EVP_MD_free(*pmd);
*pmd = md;
return 1;
}
/*
* Allocates and initializes OSSL_CMP_CTX context structure with default values.
* Returns new context on success, NULL on error
@ -116,11 +130,13 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(OPENSSL_CTX *libctx, const char *propq)
goto err;
ctx->pbm_slen = 16;
ctx->pbm_owf = NID_sha256;
if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, NID_sha256))
goto err;
ctx->pbm_itercnt = 500;
ctx->pbm_mac = NID_hmac_sha1;
ctx->digest = NID_sha256;
if (!cmp_ctx_set_md(ctx, &ctx->digest, NID_sha256))
goto err;
ctx->popoMethod = OSSL_CRMF_POPO_SIGNATURE;
ctx->revocationReason = CRL_REASON_NONE;
@ -177,8 +193,10 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
if (ctx->secretValue != NULL)
OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
ASN1_OCTET_STRING_free(ctx->secretValue);
EVP_MD_free(ctx->pbm_owf);
X509_NAME_free(ctx->recipient);
EVP_MD_free(ctx->digest);
ASN1_OCTET_STRING_free(ctx->transactionID);
ASN1_OCTET_STRING_free(ctx->senderNonce);
ASN1_OCTET_STRING_free(ctx->recipNonce);
@ -977,10 +995,12 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
ctx->popoMethod = val;
break;
case OSSL_CMP_OPT_DIGEST_ALGNID:
ctx->digest = val;
if (!cmp_ctx_set_md(ctx, &ctx->digest, val))
return 0;
break;
case OSSL_CMP_OPT_OWF_ALGNID:
ctx->pbm_owf = val;
if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, val))
return 0;
break;
case OSSL_CMP_OPT_MAC_ALGNID:
ctx->pbm_mac = val;
@ -1044,9 +1064,9 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
case OSSL_CMP_OPT_POPO_METHOD:
return ctx->popoMethod;
case OSSL_CMP_OPT_DIGEST_ALGNID:
return ctx->digest;
return EVP_MD_type(ctx->digest);
case OSSL_CMP_OPT_OWF_ALGNID:
return ctx->pbm_owf;
return EVP_MD_type(ctx->pbm_owf);
case OSSL_CMP_OPT_MAC_ALGNID:
return ctx->pbm_mac;
case OSSL_CMP_OPT_MSG_TIMEOUT:

View File

@ -33,8 +33,6 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
"cert and key do not match"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKAFTER_OUT_OF_RANGE),
"checkafter out of range"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE),
"checking pbm no secret available"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING),
"encountered keyupdatewarning"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_WAITING),
@ -88,6 +86,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE),
"missing key usage digitalsignature"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_P10CSR), "missing p10csr"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PBM_SECRET), "missing pbm secret"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY),
"missing private key"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PROTECTION), "missing protection"},

View File

@ -149,8 +149,7 @@ static int set_random(ASN1_OCTET_STRING **tgt, OSSL_CMP_CTX *ctx, size_t len)
unsigned char *bytes = OPENSSL_malloc(len);
int res = 0;
if (bytes == NULL
|| RAND_bytes_ex(ctx->libctx, bytes, len) <= 0)
if (bytes == NULL || RAND_bytes_ex(ctx->libctx, bytes, len) <= 0)
CMPerr(0, CMP_R_FAILURE_OBTAINING_RANDOM);
else
res = ossl_cmp_asn1_octet_string_set1_bytes(tgt, bytes, len);

View File

@ -76,13 +76,13 @@ struct ossl_cmp_ctx_st {
ASN1_OCTET_STRING *secretValue; /* password/shared secret for MSG_MAC_ALG */
/* PBMParameters for MSG_MAC_ALG */
size_t pbm_slen; /* salt length, currently fixed to 16 */
int pbm_owf; /* NID of one-way function (OWF), default: SHA256 */
EVP_MD *pbm_owf; /* one-way function (OWF), default: SHA256 */
int pbm_itercnt; /* OWF iteration count, currently fixed to 500 */
int pbm_mac; /* NID of MAC algorithm, default: HMAC-SHA1 as per RFC 4210 */
/* CMP message header and extra certificates */
X509_NAME *recipient; /* to set in recipient in pkiheader */
int digest; /* NID of digest used in MSG_SIG_ALG and POPO, default SHA256 */
EVP_MD *digest; /* digest used in MSG_SIG_ALG and POPO, default SHA256 */
ASN1_OCTET_STRING *transactionID; /* the current transaction ID */
ASN1_OCTET_STRING *senderNonce; /* last nonce sent */
ASN1_OCTET_STRING *recipNonce; /* last nonce received */
@ -894,14 +894,14 @@ ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc,
OSSL_CMP_CERTRESPONSE *
ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
int rid);
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
const OSSL_CMP_CERTRESPONSE *crep);
X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep,
const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey);
OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
/* from cmp_protect.c */
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
const ASN1_OCTET_STRING *secret,
EVP_PKEY *pkey);
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
const OSSL_CMP_MSG *msg);
int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
/* from cmp_vfy.c */
@ -910,7 +910,10 @@ typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx,
int invalid_protection, int arg);
int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx,
const OSSL_CMP_MSG *msg, int accept_RAVerified);
/* from cmp_client.c */
int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info,

View File

@ -355,8 +355,9 @@ OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type,
type == OSSL_CMP_PKIBODY_KUR,
OSSL_CMP_CERTREQID);
if (local_crm == NULL
|| !OSSL_CRMF_MSG_create_popo(local_crm, privkey, ctx->digest,
ctx->popoMethod))
|| !OSSL_CRMF_MSG_create_popo(ctx->popoMethod, local_crm,
privkey, ctx->digest,
ctx->libctx, ctx->propq))
goto err;
} else {
if ((local_crm = OSSL_CRMF_MSG_dup(crm)) == NULL)
@ -957,19 +958,18 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
return NULL;
}
/*
* CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned
* certificate from the given certResponse B<crep>.
* Uses the privkey in case of indirect POP from B<ctx>.
/*-
* Retrieve the newly enrolled certificate from the given certResponse crep.
* In case of indirect POPO uses the libctx and propq from ctx and private key.
* Returns a pointer to a copy of the found certificate, or NULL if not found.
*/
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
const OSSL_CMP_CERTRESPONSE *crep)
X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep,
const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey)
{
OSSL_CMP_CERTORENCCERT *coec;
X509 *crt = NULL;
if (!ossl_assert(crep != NULL))
if (!ossl_assert(crep != NULL && ctx != NULL))
return NULL;
if (crep->certifiedKeyPair
@ -980,13 +980,14 @@ X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
break;
case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT:
/* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
if (privkey == NULL) {
if (pkey == NULL) {
CMPerr(0, CMP_R_MISSING_PRIVATE_KEY);
return NULL;
}
crt =
OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert,
privkey);
ctx->libctx, ctx->propq,
pkey);
break;
default:
CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE);

View File

@ -21,67 +21,62 @@
DEFINE_STACK_OF(X509)
/*
* This function is also used for verification from cmp_vfy.
* This function is also used by the internal verify_PBMAC() in cmp_vfy.c.
*
* Calculate protection for given PKImessage utilizing the given credentials
* and the algorithm parameters set inside the message header's protectionAlg.
* Calculate protection for given PKImessage according to
* the algorithm and parameters in the message header's protectionAlg
* using the credentials, library context, and property criteria in the ctx.
*
* secret or pkey must be set. Attempts doing PBMAC in case 'secret' is set
* and else signature if 'pkey' is set - but will only
* do the protection already marked in msg->header->protectionAlg.
*
* returns ptr to ASN1_BIT_STRING containing protection on success, else NULL
* returns ASN1_BIT_STRING representing the protection on success, else NULL
*/
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
const ASN1_OCTET_STRING *secret,
EVP_PKEY *pkey)
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
const OSSL_CMP_MSG *msg)
{
ASN1_BIT_STRING *prot = NULL;
OSSL_CMP_PROTECTEDPART prot_part;
const ASN1_OBJECT *algorOID = NULL;
int len;
size_t prot_part_der_len;
unsigned char *prot_part_der = NULL;
size_t sig_len;
unsigned char *protection = NULL;
const void *ppval = NULL;
int pptype = 0;
OSSL_CRMF_PBMPARAMETER *pbm = NULL;
ASN1_STRING *pbm_str = NULL;
const unsigned char *pbm_str_uc = NULL;
EVP_MD_CTX *evp_ctx = NULL;
int md_NID;
const EVP_MD *md = NULL;
if (!ossl_assert(msg != NULL))
if (!ossl_assert(ctx != NULL && msg != NULL))
return NULL;
/* construct data to be signed */
prot_part.header = msg->header;
prot_part.body = msg->body;
len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
if (len < 0 || prot_part_der == NULL) {
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
goto end;
}
prot_part_der_len = (size_t) len;
if (msg->header->protectionAlg == NULL) {
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
goto end;
return NULL;
}
X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg);
if (secret != NULL) {
if (OBJ_obj2nid(algorOID) == NID_id_PasswordBasedMAC) {
int len;
size_t prot_part_der_len;
unsigned char *prot_part_der = NULL;
size_t sig_len;
unsigned char *protection = NULL;
OSSL_CRMF_PBMPARAMETER *pbm = NULL;
ASN1_STRING *pbm_str = NULL;
const unsigned char *pbm_str_uc = NULL;
if (ctx->secretValue == NULL) {
CMPerr(0, CMP_R_MISSING_PBM_SECRET);
return NULL;
}
if (ppval == NULL) {
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
return NULL;
}
len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
if (len < 0 || prot_part_der == NULL) {
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
goto end;
}
if (NID_id_PasswordBasedMAC != OBJ_obj2nid(algorOID)) {
CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
goto end;
}
prot_part_der_len = (size_t)len;
pbm_str = (ASN1_STRING *)ppval;
pbm_str_uc = pbm_str->data;
pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, pbm_str->length);
@ -90,50 +85,49 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
goto end;
}
if (!OSSL_CRMF_pbm_new(pbm, prot_part_der, prot_part_der_len,
secret->data, secret->length,
if (!OSSL_CRMF_pbm_new(ctx->libctx, ctx->propq,
pbm, prot_part_der, prot_part_der_len,
ctx->secretValue->data, ctx->secretValue->length,
&protection, &sig_len))
goto end;
} else if (pkey != NULL) {
/* TODO combine this with large parts of CRMF_poposigningkey_init() */
/* EVP_DigestSignInit() checks that pkey type is correct for the alg */
if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_NID, NULL)
|| (md = EVP_get_digestbynid(md_NID)) == NULL
|| (evp_ctx = EVP_MD_CTX_new()) == NULL) {
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
goto end;
}
if (EVP_DigestSignInit(evp_ctx, NULL, md, NULL, pkey) <= 0
|| EVP_DigestSignUpdate(evp_ctx, prot_part_der,
prot_part_der_len) <= 0
|| EVP_DigestSignFinal(evp_ctx, NULL, &sig_len) <= 0
|| (protection = OPENSSL_malloc(sig_len)) == NULL
|| EVP_DigestSignFinal(evp_ctx, protection, &sig_len) <= 0) {
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
goto end;
if ((prot = ASN1_BIT_STRING_new()) == NULL)
return NULL;
/* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
prot->flags |= ASN1_STRING_FLAG_BITS_LEFT;
if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) {
ASN1_BIT_STRING_free(prot);
prot = NULL;
}
end:
OSSL_CRMF_PBMPARAMETER_free(pbm);
OPENSSL_free(protection);
OPENSSL_free(prot_part_der);
return prot;
} else {
CMPerr(0, CMP_R_INVALID_ARGS);
goto end;
}
int md_nid;
const EVP_MD *md = NULL;
if ((prot = ASN1_BIT_STRING_new()) == NULL)
goto end;
/* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
prot->flags |= ASN1_STRING_FLAG_BITS_LEFT;
if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) {
if (ctx->pkey == NULL) {
CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
return NULL;
}
if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_nid, NULL)
|| (md = EVP_get_digestbynid(md_nid)) == NULL) {
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
return NULL;
}
if ((prot = ASN1_BIT_STRING_new()) == NULL)
return NULL;
if (ASN1_item_sign_with_libctx(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART),
NULL, NULL, prot, &prot_part, NULL,
ctx->pkey, md, ctx->libctx, ctx->propq))
return prot;
ASN1_BIT_STRING_free(prot);
prot = NULL;
return NULL;
}
end:
OSSL_CRMF_PBMPARAMETER_free(pbm);
EVP_MD_CTX_free(evp_ctx);
OPENSSL_free(protection);
OPENSSL_free(prot_part_der);
return prot;
}
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
@ -182,24 +176,22 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
/*
* Create an X509_ALGOR structure for PasswordBasedMAC protection based on
* the pbm settings in the context
* returns pointer to X509_ALGOR on success, NULL on error
*/
static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx)
static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg)
{
X509_ALGOR *alg = NULL;
OSSL_CRMF_PBMPARAMETER *pbm = NULL;
unsigned char *pbm_der = NULL;
int pbm_der_len;
ASN1_STRING *pbm_str = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
return 0;
alg = X509_ALGOR_new();
pbm = OSSL_CRMF_pbmp_new(ctx->libctx, ctx->pbm_slen,
ctx->pbm_owf, ctx->pbm_itercnt, ctx->pbm_mac);
EVP_MD_type(ctx->pbm_owf), ctx->pbm_itercnt,
ctx->pbm_mac);
pbm_str = ASN1_STRING_new();
if (alg == NULL || pbm == NULL || pbm_str == NULL)
if (pbm == NULL || pbm_str == NULL)
goto err;
if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0)
@ -207,19 +199,49 @@ static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx)
if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len))
goto err;
if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL)
goto err;
OPENSSL_free(pbm_der);
X509_ALGOR_set0(alg, OBJ_nid2obj(NID_id_PasswordBasedMAC),
X509_ALGOR_set0(*alg, OBJ_nid2obj(NID_id_PasswordBasedMAC),
V_ASN1_SEQUENCE, pbm_str);
OSSL_CRMF_PBMPARAMETER_free(pbm);
return alg;
return 1;
err:
ASN1_STRING_free(pbm_str);
X509_ALGOR_free(alg);
OPENSSL_free(pbm_der);
OSSL_CRMF_PBMPARAMETER_free(pbm);
return NULL;
return 0;
}
static int set_sig_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg)
{
int nid = 0;
ASN1_OBJECT *algo = NULL;
if (!OBJ_find_sigid_by_algs(&nid, EVP_MD_type(ctx->digest),
EVP_PKEY_id(ctx->pkey))) {
CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
return 0;
}
if ((algo = OBJ_nid2obj(nid)) == NULL)
return 0;
if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL)
return 0;
if (X509_ALGOR_set0(*alg, algo, V_ASN1_UNDEF, NULL))
return 1;
ASN1_OBJECT_free(algo);
return 0;
}
static int set_senderKID(const OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg,
const ASN1_OCTET_STRING *id)
{
if (id == NULL)
id = ctx->referenceValue; /* standard for PBM, fallback for sig-based */
return id == NULL || ossl_cmp_hdr_set1_senderKID(msg->header, id);
}
int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
@ -241,20 +263,18 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
/* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */
if (ctx->secretValue != NULL) {
if ((msg->header->protectionAlg = create_pbmac_algor(ctx)) == NULL)
if (!set_pbmac_algor(ctx, &msg->header->protectionAlg))
goto err;
if (ctx->referenceValue != NULL
&& !ossl_cmp_hdr_set1_senderKID(msg->header,
ctx->referenceValue))
if (!set_senderKID(ctx, msg, NULL))
goto err;
} else if (ctx->cert != NULL && ctx->pkey != NULL) {
/*
* use MSG_SIG_ALG according to 5.1.3.3 if client Certificate and
* private key is given
* will add any additional certificates from ctx->extraCertsOut
* while not needed to validate the protection certificate,
* the option to do this might be handy for certain use cases
*/
const ASN1_OCTET_STRING *subjKeyIDStr = NULL;
int algNID = 0;
ASN1_OBJECT *alg = NULL;
} else if (ctx->cert != NULL && ctx->pkey != NULL) {
/* use MSG_SIG_ALG according to 5.1.3.3 if client cert and key given */
/* make sure that key and certificate match */
if (!X509_check_private_key(ctx->cert, ctx->pkey)) {
@ -262,37 +282,21 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
goto err;
}
if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
if (!set_sig_algor(ctx, &msg->header->protectionAlg))
goto err;
if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
EVP_PKEY_id(ctx->pkey))) {
CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
/* set senderKID to keyIdentifier of the cert according to 5.1.1 */
if (!set_senderKID(ctx, msg, X509_get0_subject_key_id(ctx->cert)))
goto err;
}
if ((alg = OBJ_nid2obj(algNID)) == NULL)
goto err;
if (!X509_ALGOR_set0(msg->header->protectionAlg, alg,
V_ASN1_UNDEF, NULL)) {
ASN1_OBJECT_free(alg);
goto err;
}
/*
* set senderKID to keyIdentifier of the used certificate according
* to section 5.1.1
* will add ctx->cert followed, if possible, by its chain built
* from ctx->untrusted_certs, and then ctx->extraCertsOut
*/
subjKeyIDStr = X509_get0_subject_key_id(ctx->cert);
if (subjKeyIDStr == NULL)
subjKeyIDStr = ctx->referenceValue; /* fallback */
if (subjKeyIDStr != NULL
&& !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
goto err;
} else {
CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
goto err;
}
if ((msg->protection =
ossl_cmp_calc_protection(msg, ctx->secretValue, ctx->pkey)) == NULL)
if ((msg->protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)
goto err;
/*

View File

@ -206,7 +206,7 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
}
if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) {
if (!ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) {
/* Proof of possession could not be verified */
si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
1 << OSSL_CMP_PKIFAILUREINFO_badPOP,

View File

@ -207,7 +207,7 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
/*-
* Builds up the chain of intermediate CA certificates
* starting from of the given certificate <cert> as high up as possible using
* starting from the given certificate <cert> as high up as possible using
* the given list of candidate certificates, similarly to ssl_add_cert_chain().
*
* Intended use of this function is to find all the certificates above the trust

View File

@ -28,14 +28,8 @@ DEFINE_STACK_OF(X509)
static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
const OSSL_CMP_MSG *msg, X509 *cert)
{
EVP_MD_CTX *ctx = NULL;
OSSL_CMP_PROTECTEDPART prot_part;
int digest_nid, pk_nid;
const EVP_MD *digest = NULL;
EVP_PKEY *pubkey = NULL;
int len;
size_t prot_part_der_len = 0;
unsigned char *prot_part_der = NULL;
BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */
int res = 0;
@ -55,35 +49,13 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
goto sig_err;
}
/* create the DER representation of protected part */
prot_part.header = msg->header;
prot_part.body = msg->body;
len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
if (len < 0 || prot_part_der == NULL)
goto end;
prot_part_der_len = (size_t) len;
/* verify signature of protected part */
if (!OBJ_find_sigid_algs(ossl_cmp_hdr_get_protection_nid(msg->header),
&digest_nid, &pk_nid)
|| digest_nid == NID_undef || pk_nid == NID_undef
|| (digest = EVP_get_digestbynid(digest_nid)) == NULL) {
CMPerr(0, CMP_R_ALGORITHM_NOT_SUPPORTED);
goto sig_err;
}
/* check msg->header->protectionAlg is consistent with public key type */
if (EVP_PKEY_type(pk_nid) != EVP_PKEY_base_id(pubkey)) {
CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
goto sig_err;
}
if ((ctx = EVP_MD_CTX_new()) == NULL)
goto end;
if (EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pubkey)
&& EVP_DigestVerify(ctx, msg->protection->data,
msg->protection->length,
prot_part_der, prot_part_der_len) == 1) {
if (ASN1_item_verify_with_libctx(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART),
msg->header->protectionAlg,
msg->protection, &prot_part, NULL, pubkey,
cmp_ctx->libctx, cmp_ctx->propq) > 0) {
res = 1;
goto end;
}
@ -96,8 +68,6 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
res = 0;
end:
EVP_MD_CTX_free(ctx);
OPENSSL_free(prot_part_der);
EVP_PKEY_free(pubkey);
BIO_free(bio);
@ -105,14 +75,13 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
}
/* Verify a message protected with PBMAC */
static int verify_PBMAC(const OSSL_CMP_MSG *msg,
const ASN1_OCTET_STRING *secret)
static int verify_PBMAC(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
{
ASN1_BIT_STRING *protection = NULL;
int valid = 0;
/* generate expected protection for the message */
if ((protection = ossl_cmp_calc_protection(msg, secret, NULL)) == NULL)
if ((protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)
return 0; /* failed to generate protection string! */
valid = msg->protection != NULL && msg->protection->length >= 0
@ -355,11 +324,11 @@ static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx,
* verify that the newly enrolled certificate (which assumed rid ==
* OSSL_CMP_CERTREQID) can also be validated with the same trusted store
*/
EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
EVP_PKEY *pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
OSSL_CMP_CERTRESPONSE *crep =
ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip,
OSSL_CMP_CERTREQID);
X509 *newcrt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
X509 *newcrt = ossl_cmp_certresponse_get1_cert(crep, ctx, pkey);
/*
* maybe better use get_cert_status() from cmp_client.c, which catches
* errors
@ -598,13 +567,34 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
switch (ossl_cmp_hdr_get_protection_nid(msg->header)) {
/* 5.1.3.1. Shared Secret Information */
case NID_id_PasswordBasedMAC:
if (ctx->secretValue == 0) {
CMPerr(0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE);
break;
}
if (verify_PBMAC(ctx, msg)) {
/*
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
* "shared secret information", then any certificate transported in
* the caPubs field may be directly trusted as a root CA
* certificate by the initiator.'
*/
switch (ossl_cmp_msg_get_bodytype(msg)) {
case -1:
return 0;
case OSSL_CMP_PKIBODY_IP:
case OSSL_CMP_PKIBODY_CP:
case OSSL_CMP_PKIBODY_KUP:
case OSSL_CMP_PKIBODY_CCP:
if (ctx->trusted != NULL) {
STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
/* value.ip is same for cp, kup, and ccp */
if (verify_PBMAC(msg, ctx->secretValue))
if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
/* adds both self-issued and not self-issued certs */
return 0;
}
break;
default:
break;
}
return 1;
}
break;
/*
@ -811,7 +801,8 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
return 1;
}
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx,
const OSSL_CMP_MSG *msg, int acceptRAVerified)
{
if (!ossl_assert(msg != NULL && msg->body != NULL))
return 0;
@ -820,7 +811,8 @@ int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
{
X509_REQ *req = msg->body->value.p10cr;
if (X509_REQ_verify(req, X509_REQ_get0_pubkey(req)) <= 0) {
if (X509_REQ_verify_with_libctx(req, X509_REQ_get0_pubkey(req),
ctx->libctx, ctx->propq) <= 0) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
CMPerr(0, CMP_R_REQUEST_NOT_ACCEPTED);
return 0;
@ -832,7 +824,8 @@ int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
case OSSL_CMP_PKIBODY_CR:
case OSSL_CMP_PKIBODY_KUR:
if (!OSSL_CRMF_MSGS_verify_popo(msg->body->value.ir, OSSL_CMP_CERTREQID,
accept_RAVerified)) {
acceptRAVerified,
ctx->libctx, ctx->propq)) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 0;
#endif

View File

@ -30,6 +30,8 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
"iterationcount below 100"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED),
"poposkinput not supported"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY),
"popo inconsistent public key"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"},
@ -45,8 +47,6 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
"setting owf algor failure"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM),
"unsupported algorithm"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY),
"unsupported alg for popsigningkey"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER),
"unsupported cipher"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO),

View File

@ -353,57 +353,47 @@ int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm,
return 0;
}
/* TODO: support cases 1+2 (besides case 3) defined in RFC 4211, section 4.1. */
static int CRMF_poposigningkey_init(OSSL_CRMF_POPOSIGNINGKEY *ps,
OSSL_CRMF_CERTREQUEST *cr,
EVP_PKEY *pkey, int dgst)
static int create_popo_signature(OSSL_CRMF_POPOSIGNINGKEY *ps,
const OSSL_CRMF_CERTREQUEST *cr,
EVP_PKEY *pkey, const EVP_MD *digest,
OPENSSL_CTX *libctx, const char *propq)
{
int ret = 0;
EVP_MD *fetched_md = NULL;
const EVP_MD *md = EVP_get_digestbynid(dgst);
if (ps == NULL || cr == NULL || pkey == NULL) {
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_NULL_ARGUMENT);
CRMFerr(0, CRMF_R_NULL_ARGUMENT);
return 0;
}
if (ps->poposkInput != NULL) {
/* TODO: support cases 1+2 defined in RFC 4211, section 4.1 */
CRMFerr(0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED);
return 0;
}
/* If we didn't find legacy MD, we try an implicit fetch */
if (md == NULL)
md = fetched_md = EVP_MD_fetch(NULL, OBJ_nid2sn(dgst), NULL);
if (md == NULL) {
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
return 0;
}
ret = ASN1_item_sign(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
ps->algorithmIdentifier, NULL, ps->signature,
cr, pkey, md);
EVP_MD_free(fetched_md);
return ret;
return ASN1_item_sign_with_libctx(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
ps->algorithmIdentifier, NULL,
ps->signature, cr, NULL, pkey, digest,
libctx, propq);
}
int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
int dgst, int ppmtd)
int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm,
EVP_PKEY *pkey, const EVP_MD *digest,
OPENSSL_CTX *libctx, const char *propq)
{
OSSL_CRMF_POPO *pp = NULL;
ASN1_INTEGER *tag = NULL;
if (crm == NULL || (ppmtd == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) {
if (crm == NULL || (meth == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) {
CRMFerr(CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, CRMF_R_NULL_ARGUMENT);
return 0;
}
if (ppmtd == OSSL_CRMF_POPO_NONE)
if (meth == OSSL_CRMF_POPO_NONE)
goto end;
if ((pp = OSSL_CRMF_POPO_new()) == NULL)
goto err;
pp->type = ppmtd;
pp->type = meth;
switch (ppmtd) {
switch (meth) {
case OSSL_CRMF_POPO_RAVERIFIED:
if ((pp->value.raVerified = ASN1_NULL_new()) == NULL)
goto err;
@ -412,8 +402,11 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
case OSSL_CRMF_POPO_SIGNATURE:
{
OSSL_CRMF_POPOSIGNINGKEY *ps = OSSL_CRMF_POPOSIGNINGKEY_new();
if (ps == NULL
|| !CRMF_poposigningkey_init(ps, crm->certReq, pkey, dgst)) {
if (ps == NULL)
goto err;
if (!create_popo_signature(ps, crm->certReq, pkey, digest,
libctx, propq)) {
OSSL_CRMF_POPOSIGNINGKEY_free(ps);
goto err;
}
@ -451,11 +444,14 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
/* verifies the Proof-of-Possession of the request with the given rid in reqs */
int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
int rid, int acceptRAVerified)
int rid, int acceptRAVerified,
OPENSSL_CTX *libctx, const char *propq)
{
OSSL_CRMF_MSG *req = NULL;
X509_PUBKEY *pubkey = NULL;
OSSL_CRMF_POPOSIGNINGKEY *sig = NULL;
const ASN1_ITEM *it;
void *asn;
if (reqs == NULL || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL) {
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, CRMF_R_NULL_ARGUMENT);
@ -499,21 +495,21 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
* TODO check the contents of the authInfo sub-field,
* see RFC 4211 https://tools.ietf.org/html/rfc4211#section-4.1
*/
if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT),
sig->algorithmIdentifier, sig->signature,
sig->poposkInput,
X509_PUBKEY_get0(pubkey)) < 1)
return 0;
it = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT);
asn = sig->poposkInput;
} else {
if (req->certReq->certTemplate->subject == NULL) {
CRMFerr(0, CRMF_R_POPO_MISSING_SUBJECT);
return 0;
}
if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
sig->algorithmIdentifier, sig->signature,
req->certReq, X509_PUBKEY_get0(pubkey)) < 1)
return 0;
it = ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST);
asn = req->certReq;
}
if (ASN1_item_verify_with_libctx(it, sig->algorithmIdentifier,
sig->signature, asn, NULL,
X509_PUBKEY_get0(pubkey),
libctx, propq) < 1)
return 0;
break;
case OSSL_CRMF_POPO_KEYENC:
/*
@ -594,8 +590,10 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
* returns a pointer to the decrypted certificate
* returns NULL on error or if no certificate available
*/
X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
EVP_PKEY *pkey)
X509
*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
OPENSSL_CTX *libctx, const char *propq,
EVP_PKEY *pkey)
{
X509 *cert = NULL; /* decrypted certificate */
EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */
@ -629,7 +627,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecer
}
cikeysize = EVP_CIPHER_key_length(cipher);
/* first the symmetric key needs to be decrypted */
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq);
if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx)) {
ASN1_BIT_STRING *encKey = ecert->encSymmKey;
size_t failure;
@ -685,10 +683,11 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecer
outlen += n;
/* convert decrypted certificate from DER to internal ASN.1 structure */
if ((cert = d2i_X509(NULL, &p, outlen)) == NULL) {
if ((cert = X509_new_with_libctx(libctx, propq)) == NULL)
goto end;
if (d2i_X509(&cert, &p, outlen) == NULL)
CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
CRMF_R_ERROR_DECODING_CERTIFICATE);
}
end:
EVP_PKEY_CTX_free(pkctx);
OPENSSL_free(outbuf);

View File

@ -122,14 +122,16 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OPENSSL_CTX *libctx, size_t slen,
* |maclen| if not NULL, will set variable to the length of the mac on success
* returns 1 on success, 0 on error
*/
int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
/* TODO try to combine with other MAC calculations in the libray */
int OSSL_CRMF_pbm_new(OPENSSL_CTX *libctx, const char *propq,
const OSSL_CRMF_PBMPARAMETER *pbmp,
const unsigned char *msg, size_t msglen,
const unsigned char *sec, size_t seclen,
unsigned char **out, size_t *outlen)
{
int mac_nid, hmac_md_nid = NID_undef;
const char *mdname = NULL;
const EVP_MD *m = NULL;
const char *mdname;
EVP_MD *owf = NULL;
EVP_MD_CTX *ctx = NULL;
unsigned char basekey[EVP_MAX_MD_SIZE];
unsigned int bklen = EVP_MAX_MD_SIZE;
@ -153,7 +155,8 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
* compute the key used in the MAC process. All implementations MUST
* support SHA-1.
*/
if ((m = EVP_get_digestbyobj(pbmp->owf->algorithm)) == NULL) {
mdname = OBJ_nid2sn(OBJ_obj2nid(pbmp->owf->algorithm));
if ((owf = EVP_MD_fetch(libctx, mdname, propq)) == NULL) {
CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM);
goto err;
}
@ -162,7 +165,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
goto err;
/* compute the basekey of the salted secret */
if (!EVP_DigestInit_ex(ctx, m, NULL))
if (!EVP_DigestInit_ex(ctx, owf, NULL))
goto err;
/* first the secret */
if (!EVP_DigestUpdate(ctx, sec, seclen))
@ -181,7 +184,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
/* the first iteration was already done above */
while (--iterations > 0) {
if (!EVP_DigestInit_ex(ctx, m, NULL))
if (!EVP_DigestInit_ex(ctx, owf, NULL))
goto err;
if (!EVP_DigestUpdate(ctx, basekey, bklen))
goto err;
@ -206,7 +209,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
(char *)mdname, 0);
macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
basekey, bklen);
if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL
if ((mac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL
|| (mctx = EVP_MAC_CTX_new(mac)) == NULL
|| !EVP_MAC_CTX_set_params(mctx, macparams)
|| !EVP_MAC_init(mctx)
@ -217,10 +220,10 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
ok = 1;
err:
/* cleanup */
OPENSSL_cleanse(basekey, bklen);
EVP_MAC_CTX_free(mctx);
EVP_MAC_free(mac);
EVP_MD_free(owf);
EVP_MD_CTX_free(ctx);
if (ok == 1) {

View File

@ -2093,7 +2093,6 @@ CMP_R_CERTREQMSG_NOT_FOUND:157:certreqmsg not found
CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found
CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match
CMP_R_CHECKAFTER_OUT_OF_RANGE:181:checkafter out of range
CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE:166:checking pbm no secret available
CMP_R_ENCOUNTERED_KEYUPDATEWARNING:176:encountered keyupdatewarning
CMP_R_ENCOUNTERED_WAITING:162:encountered waiting
CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection
@ -2124,6 +2123,7 @@ CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\
missing key input for creating protection
CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE:142:missing key usage digitalsignature
CMP_R_MISSING_P10CSR:121:missing p10csr
CMP_R_MISSING_PBM_SECRET:166:missing pbm secret
CMP_R_MISSING_PRIVATE_KEY:131:missing private key
CMP_R_MISSING_PROTECTION:143:missing protection
CMP_R_MISSING_REFERENCE_CERT:168:missing reference cert
@ -2296,6 +2296,7 @@ CRMF_R_FAILURE_OBTAINING_RANDOM:107:failure obtaining random
CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100
CRMF_R_MALFORMED_IV:101:malformed iv
CRMF_R_NULL_ARGUMENT:109:null argument
CRMF_R_POPOSKINPUT_NOT_SUPPORTED:113:poposkinput not supported
CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key
CRMF_R_POPO_MISSING:121:popo missing
CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key
@ -2304,7 +2305,6 @@ CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED:120:popo raverified not accepted
CRMF_R_SETTING_MAC_ALGOR_FAILURE:110:setting mac algor failure
CRMF_R_SETTING_OWF_ALGOR_FAILURE:111:setting owf algor failure
CRMF_R_UNSUPPORTED_ALGORITHM:112:unsupported algorithm
CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY:113:unsupported alg for popsigningkey
CRMF_R_UNSUPPORTED_CIPHER:114:unsupported cipher
CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\
unsupported method for creating popo

View File

@ -3,6 +3,7 @@
=head1 NAME
ossl_cmp_build_cert_chain,
ossl_cmp_calc_protection,
ossl_cmp_msg_protect,
ossl_cmp_msg_add_extraCerts
- functions for producing CMP message protection
@ -14,14 +15,15 @@ ossl_cmp_msg_add_extraCerts
STACK_OF(X509)
*ossl_cmp_build_cert_chain(OPENSSL_CTX *libctx, const char *propq,
STACK_OF(X509) *certs, X509 *cert);
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
const OSSL_CMP_MSG *msg);
int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
=head1 DESCRIPTION
ossl_cmp_build_cert_chain() builds up the chain of intermediate CA certificates
starting from of the given certificate B<cert> as high up as possible using
starting from the given certificate I<cert> as high up as possible using
the given list of candidate certificates, similarly to ssl_add_cert_chain().
It internally uses a B<X509_STORE_CTX> structure associated with the library
context I<libctx> and property query string I<propq>, both of which may be NULL.
@ -34,18 +36,22 @@ so when not needed any more the stack and all its elements should be freed.
In case there is more than one possibility for the chain,
OpenSSL seems to take the first one; check X509_verify_cert() for details.
ossl_cmp_msg_protect() (re-)protects the given message B<msg> using an algorithm
depending on the available context information given in the B<ctx>.
ossl_cmp_calc_protection() calculates the protection for the given I<msg>
according to the algorithm and parameters in the message header's protectionAlg
using the credentials, library context, and property criteria in the I<ctx>.
ossl_cmp_msg_protect() (re-)protects the given message I<msg> using an algorithm
depending on the available context information given in the I<ctx>.
If there is a secretValue it selects PBMAC, else if there is a protection cert
it selects Signature and uses B<ossl_cmp_msg_add_extraCerts()>.
it selects Signature and uses L<ossl_cmp_msg_add_extraCerts(3)>.
It also sets the protectionAlg field in the message header accordingly.
ossl_cmp_msg_add_extraCerts() adds elements to the extraCerts field in the given
message B<msg>. It tries to build the certificate chain of the client cert in
the B<ctx> if present by using certificates in ctx->untrusted_certs;
message I<msg>. It tries to build the certificate chain of the client cert in
the I<ctx> if present by using certificates in ctx->untrusted_certs;
if no untrusted certs are set, it will at least add the client certificate.
In any case all the certificates explicitly specified to be sent out (i.e.,
B<ctx->extraCertsOut>) are added. Note that it will NOT add the root certificate
I<ctx->extraCertsOut>) are added. Note that it will NOT add the root certificate
of the chain, i.e, the trust anchor (unless it is part of extraCertsOut).
=head1 NOTES
@ -60,6 +66,8 @@ containing the EE certificate given in the function arguments (cert)
and all intermediate certificates up the chain toward the trust anchor.
The (self-signed) trust anchor is not included.
ossl_cmp_calc_protection() returns the protection on success, else NULL.
All other functions return 1 on success, 0 on error.
=head1 HISTORY

View File

@ -2,6 +2,7 @@
=head1 NAME
ossl_cmp_certresponse_get1_cert,
ossl_cmp_pkisi_get_status,
ossl_cmp_PKIStatus_to_string,
ossl_cmp_pkisi_get0_statusString,
@ -42,6 +43,8 @@ ossl_cmp_pkisi_check_pkifailureinfo
# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26
# define OSSL_CMP_PKIFAILUREINFO_MAX 26
X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep,
const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey);
int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
const char *ossl_cmp_PKIStatus_to_string(int status);
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
@ -50,19 +53,23 @@ ossl_cmp_pkisi_check_pkifailureinfo
=head1 DESCRIPTION
ossl_cmp_pkisi_get_status() returns the PKIStatus of B<si>, or -1 on error.
ossl_cmp_certresponse_get1_cert() returns a pointer to a copy of the newly
enrolled certificate from the given certResponse I<crep>, or NULL on error.
In case of indirect POPO uses data from the I<ctx> and the private key I<pkey>.
ossl_cmp_pkisi_get_status() returns the PKIStatus of I<si>, or -1 on error.
ossl_cmp_PKIStatus_to_string() returns a human-readable string representing
the PKIStatus values as specified in RFC 4210, Appendix F.
ossl_cmp_pkisi_get0_statusString() returns a direct pointer to the statusString
field contained in B<si>.
field contained in I<si>.
ossl_cmp_pkisi_get_pkifailureinfo() returns the PKIFailureInfo bits
of B<si>, encoded as integer, or -1 on error.
of I<si>, encoded as integer, or -1 on error.
ossl_cmp_pkisi_check_pkifailureinfo() returns the state of the bit (0 or 1)
with index B<index> in the PKIFailureInfo of the B<si>, or -1 on error.
with index I<index> in the PKIFailureInfo of the I<si>, or -1 on error.
=head1 NOTES

View File

@ -26,6 +26,7 @@ OSSL_CRMF_MSG_get_certReqId
X509
*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
OPENSSL_CTX *libctx, const char *propq,
EVP_PKEY *pkey);
int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm);
@ -33,27 +34,28 @@ OSSL_CRMF_MSG_get_certReqId
=head1 DESCRIPTION
OSSL_CRMF_MSG_get0_tmpl() retrieves the certificate template of B<crm>.
OSSL_CRMF_MSG_get0_tmpl() retrieves the certificate template of I<crm>.
OSSL_CRMF_CERTTEMPLATE_get0_serialNumber() retrieves the serialNumber of the
given certificate template B<tmpl>.
given certificate template I<tmpl>.
OSSL_CRMF_CERTTEMPLATE_get0_issuer() retrieves the issuer name of the
given certificate template B<tmpl>.
given certificate template I<tmpl>.
OSSL_CRMF_CERTID_get0_serialNumber retrieves the serialNumber
of the given CertId B<cid>.
of the given CertId I<cid>.
OSSL_CRMF_CERTID_get0_issuer retrieves the issuer name
of the given CertId B<cid>, which must be of ASN.1 type GEN_DIRNAME.
of the given CertId I<cid>, which must be of ASN.1 type GEN_DIRNAME.
OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert() decrypts the certificate in the given
encryptedValue B<ecert>, using the private key B<pkey>.
This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2.
encryptedValue I<ecert>, using the private key I<pkey>, library context
I<libctx> and property query string I<propq> (see L<OPENSSL_CTX(3)>).
This is needed for the indirect POPO method as in RFC 4210 section 5.2.8.2.
The function returns the decrypted certificate as a copy, leaving its ownership
with the caller, who is responsible for freeing it.
OSSL_CRMF_MSG_get_certReqId() retrieves the certReqId of B<crm>.
OSSL_CRMF_MSG_get_certReqId() retrieves the certReqId of I<crm>.
=head1 RETURN VALUES
@ -65,7 +67,7 @@ All other functions return a pointer with the intended result or NULL on error.
=head1 SEE ALSO
B<RFC 4211>
RFC 4211
=head1 HISTORY

View File

@ -30,11 +30,13 @@ OSSL_CRMF_MSGS_verify_popo
int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext);
int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
int dgst, int ppmtd);
int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm,
EVP_PKEY *pkey, const EVP_MD *digest,
OPENSSL_CTX *libctx, const char *propq);
int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
int rid, int acceptRAVerified);
int rid, int acceptRAVerified,
OPENSSL_CTX *libctx, const char *propq);
=head1 DESCRIPTION
@ -59,11 +61,13 @@ OSSL_CRMF_MSG_push0_extension() pushes the X509 extension I<ext> to the
extensions in the certTemplate of I<crm>. Consumes I<ext>.
OSSL_CRMF_MSG_create_popo() creates and sets the Proof-of-Possession (POPO)
according to the method I<ppmtd> in I<crm>.
according to the method I<meth> in I<crm>.<
The library context I<libctx> and property query string I<propq>,
may be NULL to select the defaults.
In case the method is OSSL_CRMF_POPO_SIGNATURE the POPO is calculated
using the private I<pkey> and the digest algorithm NID I<dgst>.
using the private key I<pkey> and the digest method I<digest>.
I<ppmtd> can be one of the following:
I<meth> can be one of the following:
=over 8
@ -86,7 +90,8 @@ challenge-response exchange (challengeResp) not yet supported.
=back
OSSL_CRMF_MSGS_verify_popo verifies the Proof-of-Possession of the request with
the given I<rid> in the list of I<reqs>. Optionally accepts RAVerified.
the given I<rid> in the list of I<reqs>. Optionally accepts RAVerified. It can
make use of the library context I<libctx> and property query string I<propq>.
=head1 RETURN VALUES

View File

@ -40,42 +40,42 @@ OSSL_CRMF_CERTID_gen
=head1 DESCRIPTION
OSSL_CRMF_MSG_set1_regCtrl_regToken() sets the regToken control in the given
B<msg> copying the given B<tok> as value. See RFC 4211, section 6.1.
I<msg> copying the given I<tok> as value. See RFC 4211, section 6.1.
OSSL_CRMF_MSG_set1_regCtrl_authenticator() sets the authenticator control in
the given B<msg> copying the given B<auth> as value. See RFC 4211, section 6.2.
the given I<msg> copying the given I<auth> as value. See RFC 4211, section 6.2.
OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo() pushes the given B<spi>
to B<si>. Consumes the B<spi> pointer.
OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo() pushes the given I<spi>
to I<si>. Consumes the I<spi> pointer.
OSSL_CRMF_MSG_set0_SinglePubInfo() sets in the given SinglePubInfo B<spi>
the B<method> and publication location, in the form of a GeneralName, B<nm>.
The publication location is optional, and therefore B<nm> may be NULL.
The function consumes the B<nm> pointer if present.
OSSL_CRMF_MSG_set0_SinglePubInfo() sets in the given SinglePubInfo I<spi>
the I<method> and publication location, in the form of a GeneralName, I<nm>.
The publication location is optional, and therefore I<nm> may be NULL.
The function consumes the I<nm> pointer if present.
Available methods are:
# define OSSL_CRMF_PUB_METHOD_DONTCARE 0
# define OSSL_CRMF_PUB_METHOD_X500 1
# define OSSL_CRMF_PUB_METHOD_WEB 2
# define OSSL_CRMF_PUB_METHOD_LDAP 3
OSSL_CRMF_MSG_set_PKIPublicationInfo_action() sets the action in the given B<pi>
using the given B<action> as value. See RFC 4211, section 6.3.
OSSL_CRMF_MSG_set_PKIPublicationInfo_action() sets the action in the given I<pi>
using the given I<action> as value. See RFC 4211, section 6.3.
Available actions are:
# define OSSL_CRMF_PUB_ACTION_DONTPUBLISH 0
# define OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH 1
OSSL_CRMF_MSG_set1_regCtrl_pkiPublicationInfo() sets the pkiPublicationInfo
control in the given B<msg> copying the given B<tok> as value. See RFC 4211,
control in the given I<msg> copying the given I<tok> as value. See RFC 4211,
section 6.3.
OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey() sets the protocolEncrKey control in
the given B<msg> copying the given B<pubkey> as value. See RFC 4211 section 6.6.
the given I<msg> copying the given I<pubkey> as value. See RFC 4211 section 6.6.
OSSL_CRMF_MSG_set1_regCtrl_oldCertID() sets the oldCertID control in the given
B<msg> copying the given B<cid> as value. See RFC 4211, section 6.5.
I<msg> copying the given I<cid> as value. See RFC 4211, section 6.5.
OSSL_CRMF_CERTID_gen produces an OSSL_CRMF_CERTID_gen structure copying the
given B<issuer> name and B<serial> number.
given I<issuer> name and I<serial> number.
=head1 RETURN VALUES

View File

@ -17,11 +17,11 @@ OSSL_CRMF_MSG_set1_regInfo_certReq
=head1 DESCRIPTION
OSSL_CRMF_MSG_set1_regInfo_utf8Pairs() adds a copy of the given B<utf8pairs>
value as utf8Pairs regInfo to the given B<msg>. See RFC 4211 section 7.1.
OSSL_CRMF_MSG_set1_regInfo_utf8Pairs() adds a copy of the given I<utf8pairs>
value as utf8Pairs regInfo to the given I<msg>. See RFC 4211 section 7.1.
OSSL_CRMF_MSG_set1_regInfo_certReq() adds a copy of the given B<cr> value
as certReq regInfo to the given B<msg>. See RFC 4211 section 7.2.
OSSL_CRMF_MSG_set1_regInfo_certReq() adds a copy of the given I<cr> value
as certReq regInfo to the given I<msg>. See RFC 4211 section 7.2.
=head1 RETURN VALUES
@ -30,7 +30,7 @@ All functions return 1 on success, 0 on error.
=head1 NOTES
Calling these functions multiple times adds multiple instances of the respective
control to the regInfo structure of the given B<msg>. While RFC 4211 expects
control to the regInfo structure of the given I<msg>. While RFC 4211 expects
multiple utf8Pairs in one regInfo structure, it does not allow multiple certReq.
=head1 SEE ALSO

View File

@ -10,7 +10,8 @@ OSSL_CRMF_pbmp_new
#include <openssl/crmf.h>
int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
int OSSL_CRMF_pbm_new(OPENSSL_CTX *libctx, const char *propq,
const OSSL_CRMF_PBMPARAMETER *pbmp,
const unsigned char *msg, size_t msglen,
const unsigned char *sec, size_t seclen,
unsigned char **mac, size_t *maclen);
@ -22,22 +23,26 @@ OSSL_CRMF_pbmp_new
=head1 DESCRIPTION
OSSL_CRMF_pbm_new() generates a PBM (Password-Based MAC) based on given PBM
parameters B<pbmp>, message B<msg>, and secret B<sec>, along with the respective
lengths B<msglen> and B<seclen>. On success writes the address of the newly
allocated MAC via the B<mac> reference parameter and writes the length via the
B<maclen> reference parameter unless it its NULL.
parameters I<pbmp>, message I<msg>, and secret I<sec>, along with the respective
lengths I<msglen> and I<seclen>.
The optional library context I<libctx> and I<propq> parameters may be used
to influence the selection of the MAC algorithm referenced in the I<pbmp>;
see L<provider(7)/Fetching algorithms> for further information.
On success writes the address of the newly
allocated MAC via the I<mac> reference parameter and writes the length via the
I<maclen> reference parameter unless it its NULL.
OSSL_CRMF_pbmp_new() initializes and returns a new B<PBMParameter> structure
with a new random salt of given length B<saltlen>,
OWF (one-way function) NID B<owfnid>, OWF iteration count B<itercnt>,
and MAC NID B<macnid>.
with a new random salt of given length I<saltlen>,
OWF (one-way function) NID I<owfnid>, OWF iteration count I<itercnt>,
and MAC NID I<macnid>.
The library context I<libctx> parameter may be used to select the provider
for the random number generation (DRBG) and may be NULL for the default.
=head1 NOTES
The algorithms for the OWF (one-way function) and for the MAC (message
authentication code) may be any with a NID defined in B<openssl/objects.h>.
authentication code) may be any with a NID defined in C<openssl/objects.h>.
As specified by RFC 4210, these should include NID_hmac_sha1.
RFC 4210 recommends that the salt SHOULD be at least 8 bytes (64 bits) long,

View File

@ -45,7 +45,6 @@ int ERR_load_CMP_strings(void);
# define CMP_R_CERTRESPONSE_NOT_FOUND 113
# define CMP_R_CERT_AND_KEY_DO_NOT_MATCH 114
# define CMP_R_CHECKAFTER_OUT_OF_RANGE 181
# define CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE 166
# define CMP_R_ENCOUNTERED_KEYUPDATEWARNING 176
# define CMP_R_ENCOUNTERED_WAITING 162
# define CMP_R_ERROR_CALCULATING_PROTECTION 115
@ -75,6 +74,7 @@ int ERR_load_CMP_strings(void);
# define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION 130
# define CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE 142
# define CMP_R_MISSING_P10CSR 121
# define CMP_R_MISSING_PBM_SECRET 166
# define CMP_R_MISSING_PRIVATE_KEY 131
# define CMP_R_MISSING_PROTECTION 143
# define CMP_R_MISSING_REFERENCE_CERT 168

View File

@ -70,7 +70,8 @@ typedef struct ossl_crmf_optionalvalidity_st OSSL_CRMF_OPTIONALVALIDITY;
OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OPENSSL_CTX *libctx, size_t slen,
int owfnid, size_t itercnt,
int macnid);
int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
int OSSL_CRMF_pbm_new(OPENSSL_CTX *libctx, const char *propq,
const OSSL_CRMF_PBMPARAMETER *pbmp,
const unsigned char *msg, size_t msglen,
const unsigned char *sec, size_t seclen,
unsigned char **mac, size_t *maclen);
@ -119,10 +120,12 @@ int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext);
# define OSSL_CRMF_POPO_SIGNATURE 1
# define OSSL_CRMF_POPO_KEYENC 2
# define OSSL_CRMF_POPO_KEYAGREE 3
int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
int dgst, int ppmtd);
int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm,
EVP_PKEY *pkey, const EVP_MD *digest,
OPENSSL_CTX *libctx, const char *propq);
int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
int rid, int acceptRAVerified);
int rid, int acceptRAVerified,
OPENSSL_CTX *libctx, const char *propq);
OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm);
ASN1_INTEGER
*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl);
@ -138,6 +141,7 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
const ASN1_INTEGER *serial);
X509
*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
OPENSSL_CTX *libctx, const char *propq,
EVP_PKEY *pkey);
# ifdef __cplusplus

View File

@ -10,6 +10,7 @@
#ifndef OPENSSL_CRMFERR_H
# define OPENSSL_CRMFERR_H
# pragma once
# include <openssl/opensslconf.h>
# include <openssl/symhacks.h>
@ -62,6 +63,7 @@ int ERR_load_CRMF_strings(void);
# define CRMF_R_ITERATIONCOUNT_BELOW_100 108
# define CRMF_R_MALFORMED_IV 101
# define CRMF_R_NULL_ARGUMENT 109
# define CRMF_R_POPOSKINPUT_NOT_SUPPORTED 113
# define CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY 117
# define CRMF_R_POPO_MISSING 121
# define CRMF_R_POPO_MISSING_PUBLIC_KEY 118
@ -70,7 +72,6 @@ int ERR_load_CRMF_strings(void);
# define CRMF_R_SETTING_MAC_ALGOR_FAILURE 110
# define CRMF_R_SETTING_OWF_ALGOR_FAILURE 111
# define CRMF_R_UNSUPPORTED_ALGORITHM 112
# define CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY 113
# define CRMF_R_UNSUPPORTED_CIPHER 114
# define CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO 115
# define CRMF_R_UNSUPPORTED_POPO_METHOD 116

View File

@ -376,6 +376,7 @@ static int test_cmp_create_genm(void)
static int execute_certrep_create(CMP_MSG_TEST_FIXTURE *fixture)
{
OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
OSSL_CMP_CERTREPMESSAGE *crepmsg = OSSL_CMP_CERTREPMESSAGE_new();
OSSL_CMP_CERTRESPONSE *read_cresp, *cresp = OSSL_CMP_CERTRESPONSE_new();
EVP_PKEY *privkey;
@ -400,8 +401,8 @@ static int execute_certrep_create(CMP_MSG_TEST_FIXTURE *fixture)
goto err;
if (!TEST_ptr_null(ossl_cmp_certrepmessage_get0_certresponse(crepmsg, 88)))
goto err;
privkey = OSSL_CMP_CTX_get0_newPkey(fixture->cmp_ctx, 1); /* may be NULL */
certfromresp = ossl_cmp_certresponse_get1_certificate(privkey, read_cresp);
privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); /* may be NULL */
certfromresp = ossl_cmp_certresponse_get1_cert(read_cresp, ctx, privkey);
if (certfromresp == NULL || !TEST_int_eq(X509_cmp(cert, certfromresp), 0))
goto err;

View File

@ -23,8 +23,6 @@ typedef struct test_fixture {
/* for protection tests */
OSSL_CMP_MSG *msg;
OSSL_CMP_PKISI *si; /* for error and response messages */
ASN1_OCTET_STRING *secret;
EVP_PKEY *privkey;
EVP_PKEY *pubkey;
unsigned char *mem;
int memlen;
@ -39,7 +37,6 @@ static void tear_down(CMP_PROTECT_TEST_FIXTURE *fixture)
{
OSSL_CMP_CTX_free(fixture->cmp_ctx);
OSSL_CMP_MSG_free(fixture->msg);
ASN1_OCTET_STRING_free(fixture->secret);
OSSL_CMP_PKISI_free(fixture->si);
OPENSSL_free(fixture->mem);
@ -75,8 +72,7 @@ static X509 *endentity1 = NULL, *endentity2 = NULL,
static int execute_calc_protection_fails_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
ASN1_BIT_STRING *protection =
ossl_cmp_calc_protection(fixture->msg, fixture->secret,
fixture->privkey);
ossl_cmp_calc_protection(fixture->cmp_ctx, fixture->msg);
int res = TEST_ptr_null(protection);
ASN1_BIT_STRING_free(protection);
@ -86,7 +82,7 @@ static int execute_calc_protection_fails_test(CMP_PROTECT_TEST_FIXTURE *fixture)
static int execute_calc_protection_pbmac_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
ASN1_BIT_STRING *protection =
ossl_cmp_calc_protection(fixture->msg, fixture->secret, NULL);
ossl_cmp_calc_protection(fixture->cmp_ctx, fixture->msg);
int res = TEST_ptr(protection)
&& TEST_true(ASN1_STRING_cmp(protection,
fixture->msg->protection) == 0);
@ -101,13 +97,12 @@ static int execute_calc_protection_pbmac_test(CMP_PROTECT_TEST_FIXTURE *fixture)
*/
static int verify_signature(OSSL_CMP_MSG *msg,
ASN1_BIT_STRING *protection,
EVP_PKEY *pkey, int digest_nid)
EVP_PKEY *pkey, EVP_MD *digest)
{
OSSL_CMP_PROTECTEDPART prot_part;
unsigned char *prot_part_der = NULL;
int len;
EVP_MD_CTX *ctx = NULL;
const EVP_MD *digest = EVP_get_digestbynid(digest_nid);
int res;
prot_part.header = OSSL_CMP_MSG_get0_header(msg);
@ -131,7 +126,7 @@ static int execute_calc_protection_signature_test(CMP_PROTECT_TEST_FIXTURE *
fixture)
{
ASN1_BIT_STRING *protection =
ossl_cmp_calc_protection(fixture->msg, NULL, fixture->privkey);
ossl_cmp_calc_protection(fixture->cmp_ctx, fixture->msg);
int ret = (TEST_ptr(protection)
&& TEST_true(ASN1_STRING_cmp(protection,
fixture->msg->protection) == 0)
@ -161,8 +156,8 @@ static int test_cmp_calc_protection_pkey(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->pubkey = loadedpubkey;
fixture->privkey = loadedprivkey;
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))) {
if (!TEST_true(OSSL_CMP_CTX_set1_pkey(fixture->cmp_ctx, loadedprivkey))
|| !TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))) {
tear_down(fixture);
fixture = NULL;
}
@ -175,9 +170,8 @@ static int test_cmp_calc_protection_pbmac(void)
unsigned char sec_insta[] = { 'i', 'n', 's', 't', 'a' };
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
if (!TEST_ptr(fixture->secret = ASN1_OCTET_STRING_new())
|| !TEST_true(ASN1_OCTET_STRING_set
(fixture->secret, sec_insta, sizeof(sec_insta)))
if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx,
sec_insta, sizeof(sec_insta)))
|| !TEST_ptr(fixture->msg = load_pkimsg(ip_PBM_f))) {
tear_down(fixture);
fixture = NULL;
@ -214,8 +208,7 @@ static int test_MSG_protect_with_msg_sig_alg_protection_plus_rsa_key(void)
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->expected = 1;
if (!TEST_ptr(fixture->msg =
OSSL_CMP_MSG_dup(ir_unprotected))
if (!TEST_ptr(fixture->msg = OSSL_CMP_MSG_dup(ir_unprotected))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 0))
/*
* Use half of the 16 bytes of random input

View File

@ -98,7 +98,7 @@ static int execute_verify_popo_test(CMP_VFY_TEST_FIXTURE *fixture)
return 0;
}
return TEST_int_eq(fixture->expected,
ossl_cmp_verify_popo(fixture->msg,
ossl_cmp_verify_popo(fixture->cmp_ctx, fixture->msg,
fixture->additional_arg));
}