[openssl] master update

dev at ddvo.net dev at ddvo.net
Tue Jan 4 16:05:20 UTC 2022


The branch master has been updated
       via  b971d4198def0b29654e8fbf7987f7157741aed2 (commit)
       via  acef3b2f84b22c7cdb3cbc02fc8fc7b76cbb6ea7 (commit)
      from  97b8c859c64bc60fcf5bb27ed51489c81fde41b3 (commit)


- Log -----------------------------------------------------------------
commit b971d4198def0b29654e8fbf7987f7157741aed2
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Jul 12 15:34:20 2021 +0200

    CMP mock server: add -ref_cert option and corresponding ossl_cmp_mock_srv_set1_refCert()
    
    Fixes #16041
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16050)

commit acef3b2f84b22c7cdb3cbc02fc8fc7b76cbb6ea7
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Jul 12 15:32:49 2021 +0200

    X509_cmp.pod: Point out that the X509_NAME_cmp() arguments may be NULL
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16050)

-----------------------------------------------------------------------

Summary of changes:
 apps/cmp.c                                         | 23 ++++++--
 apps/include/cmp_mock_srv.h                        |  1 +
 apps/lib/cmp_mock_srv.c                            | 63 +++++++++++++++-------
 doc/internal/man3/ossl_cmp_mock_srv_new.pod        | 10 +++-
 doc/man1/openssl-cmp.pod.in                        |  5 ++
 doc/man3/X509_cmp.pod                              |  3 +-
 test/cmp_client_test.c                             |  1 +
 test/recipes/80-test_cmp_http_data/Mock/server.cnf |  1 +
 8 files changed, 82 insertions(+), 25 deletions(-)

diff --git a/apps/cmp.c b/apps/cmp.c
index 5167446cde..2e4867b0db 100644
--- a/apps/cmp.c
+++ b/apps/cmp.c
@@ -174,6 +174,7 @@ static char *opt_srv_keypass = NULL;
 
 static char *opt_srv_trusted = NULL;
 static char *opt_srv_untrusted = NULL;
+static char *opt_ref_cert = NULL;
 static char *opt_rsp_cert = NULL;
 static char *opt_rsp_extracerts = NULL;
 static char *opt_rsp_capubs = NULL;
@@ -249,7 +250,7 @@ typedef enum OPTION_choice {
     OPT_SRV_REF, OPT_SRV_SECRET,
     OPT_SRV_CERT, OPT_SRV_KEY, OPT_SRV_KEYPASS,
     OPT_SRV_TRUSTED, OPT_SRV_UNTRUSTED,
-    OPT_RSP_CERT, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS,
+    OPT_REF_CERT, OPT_RSP_CERT, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS,
     OPT_POLL_COUNT, OPT_CHECK_AFTER,
     OPT_GRANT_IMPLICITCONF,
     OPT_PKISTATUS, OPT_FAILURE,
@@ -498,6 +499,8 @@ const OPTIONS cmp_options[] = {
      "Trusted certificates for client authentication"},
     {"srv_untrusted", OPT_SRV_UNTRUSTED, 's',
      "Intermediate certs that may be useful for verifying CMP protection"},
+    {"ref_cert", OPT_RSP_CERT, 's',
+     "Certificate to be expected for rr and any oldCertID in kur messages"},
     {"rsp_cert", OPT_RSP_CERT, 's',
      "Certificate to be returned as mock enrollment result"},
     {"rsp_extracerts", OPT_RSP_EXTRACERTS, 's',
@@ -600,7 +603,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
     {&opt_srv_ref}, {&opt_srv_secret},
     {&opt_srv_cert}, {&opt_srv_key}, {&opt_srv_keypass},
     {&opt_srv_trusted}, {&opt_srv_untrusted},
-    {&opt_rsp_cert}, {&opt_rsp_extracerts}, {&opt_rsp_capubs},
+    {&opt_ref_cert}, {&opt_rsp_cert}, {&opt_rsp_extracerts}, {&opt_rsp_capubs},
     {(char **)&opt_poll_count}, {(char **)&opt_check_after},
     {(char **)&opt_grant_implicitconf},
     {(char **)&opt_pkistatus}, {(char **)&opt_failure},
@@ -1074,6 +1077,18 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
                      (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted))
         goto err;
 
+    if (opt_ref_cert != NULL) {
+        X509 *cert = load_cert_pwd(opt_ref_cert, opt_keypass,
+                                   "reference cert to be expected by the mock server");
+
+        if (cert == NULL)
+            goto err;
+        if (!ossl_cmp_mock_srv_set1_refCert(srv_ctx, cert)) {
+            X509_free(cert);
+            goto err;
+        }
+        X509_free(cert);
+    }
     if (opt_rsp_cert == NULL) {
         CMP_warn("no -rsp_cert given for mock server");
     } else {
@@ -1082,7 +1097,6 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
 
         if (cert == NULL)
             goto err;
-        /* from server perspective the server is the client */
         if (!ossl_cmp_mock_srv_set1_certOut(srv_ctx, cert)) {
             X509_free(cert);
             goto err;
@@ -2573,6 +2587,9 @@ static int get_opts(int argc, char **argv)
         case OPT_SRV_UNTRUSTED:
             opt_srv_untrusted = opt_str();
             break;
+        case OPT_REF_CERT:
+            opt_ref_cert = opt_str();
+            break;
         case OPT_RSP_CERT:
             opt_rsp_cert = opt_str();
             break;
diff --git a/apps/include/cmp_mock_srv.h b/apps/include/cmp_mock_srv.h
index 6beba14735..f3edc1b01b 100644
--- a/apps/include/cmp_mock_srv.h
+++ b/apps/include/cmp_mock_srv.h
@@ -20,6 +20,7 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx,
                                         const char *propq);
 void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
 
+int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
 int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
 int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
                                     STACK_OF(X509) *chain);
diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c
index 5cd2b23737..dcd3123733 100644
--- a/apps/lib/cmp_mock_srv.c
+++ b/apps/lib/cmp_mock_srv.c
@@ -18,6 +18,7 @@
 /* the context for the CMP mock server */
 typedef struct
 {
+    X509 *refCert;             /* cert to expect for oldCertID in kur/rr msg */
     X509 *certOut;             /* certificate to be returned in cp/ip/kup msg */
     STACK_OF(X509) *chainOut;  /* chain of certOut to add to extraCerts field */
     STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */
@@ -37,6 +38,7 @@ static void mock_srv_ctx_free(mock_srv_ctx *ctx)
         return;
 
     OSSL_CMP_PKISI_free(ctx->statusOut);
+    X509_free(ctx->refCert);
     X509_free(ctx->certOut);
     OSSL_STACK_OF_X509_free(ctx->chainOut);
     OSSL_STACK_OF_X509_free(ctx->caPubsOut);
@@ -63,6 +65,22 @@ static mock_srv_ctx *mock_srv_ctx_new(void)
     return NULL;
 }
 
+int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
+{
+    mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+        return 0;
+    }
+    if (cert == NULL || X509_up_ref(cert)) {
+        X509_free(ctx->refCert);
+        ctx->refCert = cert;
+        return 1;
+    }
+    return 0;
+}
+
 int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
 {
     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
@@ -170,6 +188,21 @@ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
     return 1;
 }
 
+/* check for matching reference cert components, as far as given */
+static int refcert_cmp(const X509 *refcert,
+                       const X509_NAME *issuer, const ASN1_INTEGER *serial)
+{
+    const X509_NAME *ref_issuer;
+    const ASN1_INTEGER *ref_serial;
+
+    if (refcert == NULL)
+        return 1;
+    ref_issuer = X509_get_issuer_name(refcert);
+    ref_serial = X509_get0_serialNumber(refcert);
+    return (ref_issuer == NULL || X509_NAME_cmp(issuer, ref_issuer) == 0)
+        && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0);
+}
+
 static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                             const OSSL_CMP_MSG *cert_req,
                                             int certReqId,
@@ -212,24 +245,18 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
         /* give final response after polling */
         ctx->curr_pollCount = 0;
 
+    /* accept cert update request only for the reference cert, if given */
     if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR
-            && crm != NULL && ctx->certOut != NULL) {
+            && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) {
         const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm);
-        const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut);
-        const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut);
 
         if (cid == NULL) {
             ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID);
             return NULL;
         }
-        if (issuer != NULL
-            && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
-            ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
-            return NULL;
-        }
-        if (serial != NULL
-            && ASN1_INTEGER_cmp(serial,
-                                OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) {
+        if (!refcert_cmp(ctx->refCert,
+                         OSSL_CRMF_CERTID_get0_issuer(cid),
+                         OSSL_CRMF_CERTID_get0_serialNumber(cid))) {
             ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
             return NULL;
         }
@@ -270,19 +297,15 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return NULL;
     }
-    if (ctx->sendError || ctx->certOut == NULL) {
+    if (ctx->sendError) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return NULL;
     }
 
-    /* Allow any RR derived from CSR, which may include subject and serial */
-    if (issuer == NULL || serial == NULL)
-        return OSSL_CMP_PKISI_dup(ctx->statusOut);
-
-    /* accept revocation only for the certificate we sent in ir/cr/kur */
-    if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0
-            || ASN1_INTEGER_cmp(serial,
-                                X509_get0_serialNumber(ctx->certOut)) != 0) {
+    /* allow any RR derived from CSR which does not include issuer and serial */
+    if ((issuer != NULL || serial != NULL)
+        /* accept revocation only for the reference cert, if given */
+            && !refcert_cmp(ctx->refCert, issuer, serial)) {
         ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED,
                        "wrong certificate to revoke");
         return NULL;
diff --git a/doc/internal/man3/ossl_cmp_mock_srv_new.pod b/doc/internal/man3/ossl_cmp_mock_srv_new.pod
index 837ca06bb3..cf85139e0a 100644
--- a/doc/internal/man3/ossl_cmp_mock_srv_new.pod
+++ b/doc/internal/man3/ossl_cmp_mock_srv_new.pod
@@ -4,6 +4,7 @@
 
 ossl_cmp_mock_srv_new,
 ossl_cmp_mock_srv_free,
+ossl_cmp_mock_srv_set1_refCert,
 ossl_cmp_mock_srv_set1_certOut,
 ossl_cmp_mock_srv_set1_chainOut,
 ossl_cmp_mock_srv_set1_caPubsOut,
@@ -20,6 +21,7 @@ ossl_cmp_mock_srv_set_checkAfterTime
  OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq);
  void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
 
+ int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
  int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
  int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
                                      STACK_OF(X509) *chain);
@@ -39,12 +41,18 @@ I<propq>, both of which may be NULL to select the defaults.
 
 ossl_cmp_mock_srv_free() deallocates the contexts for the CMP mock server.
 
+OSSL_CMP_SRV_CTX_set1_refCert() sets the reference certificate to be expected
+for rr messages and for any oldCertID included in kur messages.
+
 OSSL_CMP_SRV_CTX_set1_certOut() sets the certificate to be returned in
 cp/ip/kup.
+Note that on each certificate request the mock server does not produce
+a fresh certificate but just returns the same pre-existing certificate.
 
 OSSL_CMP_SRV_CTX_set1_chainOut() sets the certificate chain to be added to
 the extraCerts in a cp/ip/kup.
-It should to useful to validate B<certOut>.
+It should be useful for the validation of the certificate given via
+OSSL_CMP_SRV_CTX_set1_certOut().
 
 OSSL_CMP_SRV_CTX_set1_caPubsOut() sets the caPubs to be returned in an ip.
 
diff --git a/doc/man1/openssl-cmp.pod.in b/doc/man1/openssl-cmp.pod.in
index 84241a3197..3bae43cc35 100644
--- a/doc/man1/openssl-cmp.pod.in
+++ b/doc/man1/openssl-cmp.pod.in
@@ -123,6 +123,7 @@ Mock server options:
 [B<-srv_keypass> I<arg>]
 [B<-srv_trusted> I<filenames>|I<uris>]
 [B<-srv_untrusted> I<filenames>|I<uris>]
+[B<-ref_cert> I<filename>|I<uri>]
 [B<-rsp_cert> I<filename>|I<uri>]
 [B<-rsp_extracerts> I<filenames>|I<uris>]
 [B<-rsp_capubs> I<filenames>|I<uris>]
@@ -959,6 +960,10 @@ have no effect on the certificate verification enabled via this option.
 
 Intermediate CA certs that may be useful when validating client certificates.
 
+=item B<-ref_cert> I<filename>|I<uri>
+
+Certificate to be expected for RR messages and any oldCertID in KUR messages.
+
 =item B<-rsp_cert> I<filename>|I<uri>
 
 Certificate to be returned as mock enrollment result.
diff --git a/doc/man3/X509_cmp.pod b/doc/man3/X509_cmp.pod
index 272a9d259e..6294314abb 100644
--- a/doc/man3/X509_cmp.pod
+++ b/doc/man3/X509_cmp.pod
@@ -29,7 +29,8 @@ I<a> and I<b>. The comparison is based on the B<memcmp> result of the hash
 values of two B<X509> objects and the canonical (DER) encoding values.
 
 The X509_NAME_cmp() function compares two B<X509_NAME> objects indicated by
-parameters I<a> and I<b>. The comparison is based on the B<memcmp> result of the
+parameters I<a> and I<b>, any of which may be NULL.
+The comparison is based on the B<memcmp> result of the
 canonical (DER) encoding values of the two objects using L<i2d_X509_NAME(3)>.
 This procedure adheres to the matching rules for Distinguished Names (DN)
 given in RFC 4517 section 4.2.15 and RFC 5280 section 7.1.
diff --git a/test/cmp_client_test.c b/test/cmp_client_test.c
index 70543b3b01..4e7b26c220 100644
--- a/test/cmp_client_test.c
+++ b/test/cmp_client_test.c
@@ -62,6 +62,7 @@ static CMP_SES_TEST_FIXTURE *set_up(const char *const test_case_name)
     fixture->test_case_name = test_case_name;
     if (!TEST_ptr(fixture->srv_ctx = ossl_cmp_mock_srv_new(libctx, NULL))
             || !OSSL_CMP_SRV_CTX_set_accept_unprotected(fixture->srv_ctx, 1)
+            || !ossl_cmp_mock_srv_set1_refCert(fixture->srv_ctx, client_cert)
             || !ossl_cmp_mock_srv_set1_certOut(fixture->srv_ctx, client_cert)
             || (srv_cmp_ctx =
                 OSSL_CMP_SRV_CTX_get0_cmp_ctx(fixture->srv_ctx)) == NULL
diff --git a/test/recipes/80-test_cmp_http_data/Mock/server.cnf b/test/recipes/80-test_cmp_http_data/Mock/server.cnf
index 774b34a7f5..991c1cf525 100644
--- a/test/recipes/80-test_cmp_http_data/Mock/server.cnf
+++ b/test/recipes/80-test_cmp_http_data/Mock/server.cnf
@@ -9,6 +9,7 @@ srv_secret = pass:test
 no_check_time = 1
 srv_trusted = signer_root.crt
 
+ref_cert = signer_only.crt
 rsp_cert = signer_only.crt
 rsp_capubs = signer_root.crt
 rsp_extracerts = signer_issuing.crt


More information about the openssl-commits mailing list