]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Use in CMP+CRMF libctx and propq param added to sign/verify/HMAC/decrypt
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Thu, 13 Aug 2020 15:44:54 +0000 (17:44 +0200)
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>
Fri, 21 Aug 2020 07:04:13 +0000 (09:04 +0200)
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11808)

28 files changed:
apps/cmp.c
crypto/cmp/cmp_client.c
crypto/cmp/cmp_ctx.c
crypto/cmp/cmp_err.c
crypto/cmp/cmp_hdr.c
crypto/cmp/cmp_local.h
crypto/cmp/cmp_msg.c
crypto/cmp/cmp_protect.c
crypto/cmp/cmp_server.c
crypto/cmp/cmp_util.c
crypto/cmp/cmp_vfy.c
crypto/crmf/crmf_err.c
crypto/crmf/crmf_lib.c
crypto/crmf/crmf_pbm.c
crypto/err/openssl.txt
doc/internal/man3/ossl_cmp_msg_protect.pod
doc/internal/man3/ossl_cmp_pkisi_get_status.pod
doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod
doc/man3/OSSL_CRMF_MSG_set0_validity.pod
doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod
doc/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod
doc/man3/OSSL_CRMF_pbmp_new.pod
include/openssl/cmperr.h
include/openssl/crmf.h
include/openssl/crmferr.h
test/cmp_msg_test.c
test/cmp_protect_test.c
test/cmp_vfy_test.c

index 8565dc62aa1eb5d93eb5dd37ee8babf20a839555..97fa322b1153bf87350d9b2032a704f173ee09f5 100644 (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) {
index 37473c7a6c4c97c7caa98ae40b9572a3fab3619d..b7319372e633822cab7c854a5021d039ac7424f1 100644 (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);
 
index 0d15551e35777a915b2e638b5d6894eef02b901c..e731f159588211764aad72b695071d9341985113 100644 (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:
index 87d0f0f1b0908093cab151fd3ecfc287f9f20912..19d155642622d56f25356790a82a1c6bf5cfc9d9 100644 (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"},
index e27a67262ac391359d56a83236753f089d88fa75..6bd1e581af57cb59f2c8d309ccef232361ca67a5 100644 (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);
index 8d21fa0b82aad6fe258ffa8999123a66f304cb0d..41c10b22c128486a5379a4dd75b94545ebfff66c 100644 (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,
index 9e402c51a515acc5716ee79db2b3b389ba1c2f74..64e00fc884b334c88bfa99bf23a39757affa72db 100644 (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);
index ccb4516cded0a847a7e2607c8561b6a1f68756ac..212ef92f50b2b541715fc88765879aec342951af 100644 (file)
 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);
-            goto end;
+            return NULL;
         }
-        if (NID_id_PasswordBasedMAC != OBJ_obj2nid(algorOID)) {
-            CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
+
+        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;
+
         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)
-            goto err;
-        if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
-                                    EVP_PKEY_id(ctx->pkey))) {
-            CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
-            goto err;
-        }
-        if ((alg = OBJ_nid2obj(algNID)) == NULL)
+        if (!set_sig_algor(ctx, &msg->header->protectionAlg))
             goto err;
-        if (!X509_ALGOR_set0(msg->header->protectionAlg, alg,
-                             V_ASN1_UNDEF, NULL)) {
-            ASN1_OBJECT_free(alg);
+        /* 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;
-        }
 
         /*
-         * 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;
 
     /*
index eb98b50383f4027e565faa0f606bac0d5070578b..2ba6cb79843c7bf7880a876056f9495e63567655 100644 (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,
index 318314771e31adfb344d551c1917b620c6706fe4..c4797f169172d0f9dc5b59c79e53e6ffa59b6cea 100644 (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
index d4cececd614f51b200eadcc71ee5e53e123bcd23..b50a3fe83a4abf74df19700716987de3dbdacec3 100644 (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(msg, ctx->secretValue))
+        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 (!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
index 159d5b2c91e2e404609bc2382aa189e80f2b5e65..61a14888385db353644bd353c0662ca42fd47d0d 100644 (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),
index 7530120ff3cc09c3b99223b2a9927832cd4e7aa3..3202f357c1a8f8d607483846bc1838ed1da2b092 100644 (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 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);
+    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;
     }
 
-    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);
index 77ef6e0a3760357c84c68ac9f98b79fa67324d1f..3aedf8b57f6d8a3e9fb97ca80aa559a7431072d2 100644 (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) {
index 892501045b02a2f053a91f01ed81db392353c438..10531ead7a4357bc8c3e1783229a2647c9b73438 100644 (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
index 484d76e5c41d9bf590d545d6e72467fea7f9f0f0..6c33db695403e98ecab8430aa405d2a48f05d040 100644 (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
index cd32c9015d4fd89150241b55dd1e0dd3ceaa24b2..21f6f90b39d3de1e925f50d57d4729c7bdfa64da 100644 (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
 
index 8e8bd7263ffb9722e6c3f9c3d46c7d8825c3331a..e71cc52422060afacbcfb4d97b662f8a0f4a107b 100644 (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
 
index 54ebe0f856c5bac30169fdf281f70ef229175c3f..8612049d730ee892098269da0330ec22cb827a21 100644 (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
 
index 78423c70017a6798dd9f2a81dca73844eba68b4d..9a76567a10725313f6b1d85102b3f7543df19e40 100644 (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
 
index 32a4933e7d940174720ff3faee98ed452353a700..a9309bbf29de008a655a0cacc962d01525395af6 100644 (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
index 566775394437804ad08b02dd285b40a08bf77cff..b4fd62a2968210617ad5377621f2f0afba2b9674 100644 (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,
index f18ba386bc4a652d0a3185cc25a45acb7ff05cf0..2ae82974a990fdfa522084dd9748236b9b664767 100644 (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
index 8107d26d5c685ac436eca3a1d0e80f7afba3f21a..022f0bb9d21175f41fc3e0462686d8ed8f59c204 100644 (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
index 17e5c85cc24c350a6eeb7427ee942a50d853d3d7..a4c194e0943d5875a82195d689de22ed8caa139d 100644 (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
index 2d96596520fabc5822b299abb09259b1f6f25310..1a090a6a0296d8c4063d73a01208db6d4f4bbffe 100644 (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;
 
index 2a2a6970514041c980394118f75a57d8f7551971..1be29cd7a3190dfb07c08bdbc135f2a8de1547a4 100644 (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
index 8d654c6ab46f0e61b222caa827c58100d8d7b0be..b14398a2a2c9a06dcd8fdb66352ecdc83382f97a 100644 (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));
 }