[rs-commit] r435 - in /mod_scep/trunk: README mod_scep.c

rs-commit at redwax.eu rs-commit at redwax.eu
Thu Oct 19 19:01:46 CEST 2023


Author: dirkx at redwax.eu
Date: Thu Oct 19 19:01:45 2023
New Revision: 435

Log:
Fix SCEP testcases submitted by Peter Gutmann <pgut001 at cs.auckland.ac.nz>

Modified:
    mod_scep/trunk/README
    mod_scep/trunk/mod_scep.c

Modified: mod_scep/trunk/README
==============================================================================
--- mod_scep/trunk/README	(original)
+++ mod_scep/trunk/README	Thu Oct 19 19:01:45 2023
@@ -1,24 +1,57 @@
+# AA basic configuration for SCEP issuing.
+#
+# 0. Set up some directories; The directory cert needs to be server writable.
+#
+#  mkdir ca ra issued_certs
+#  chown www:www issued_certs
+#
+# 1. Generate a CA with an issuing RA 
+#
+#  openssl req -new -x509 -subj /CN=ca-test-scep -out ca/ca-cert.pem -keyout ca/ca-key.pem -nodes
+#
+#  echo "[ra]" > config.cnf
+#  echo "keyUsage=digitalSignature,keyEncipherment" >> config.cnf
+#
+#  openssl req -new -subj /CN=ra-test-scep -keyout ra/ra-key.pem -nodes |\ 
+#            openssl x509 -req \
+#                         -CAkey ca/ca-key.pem -CA ca/ca-cert.pem \
+#                         -out ra/ra-cert.pem  \
+#                         -extfile config.cnf -extensions ra
+#
 
-A basic configuration.
+# 2. Load the right modules into httpd.conf
+#
+# (Mac/Linux style)
+LoadModule ca_module lib/apache2/modules/mod_ca.so
+LoadModule scep_module lib/apache2/modules/mod_scep.so
+LoadModule ca_simple_module lib/apache2/modules/mod_ca_simple.so
+LoadModule ca_disk_module lib/apache2/modules/mod_ca_disk.so
 
-<IfModule mod_scep.c>
+OR use
+
+# (*BSD/Debian style)
+LoadModule ca_module libexec/apache24/mod_ca.so
+LoadModule scep_module libexec/apache24/mod_scep.so
+LoadModule ca_simple_module libexec/apache24/mod_ca_simple.so
+LoadModule ca_disk_module libexec/apache24/mod_ca_disk.so
+
+# Configure a URL (in this case - /scep). We're not setting any
+# access restricitons - anyone can ask for anything.
+#
 <Location /scep>
-  SetHandler scep
-#  ScepRACertificate /tmp/ra-cert.pem
-#  ScepRAKey /tmp/ra-key.pem
-  ScepSubjectRequest O
-  ScepSubjectRequest countryName
-  ScepSubjectRequest stateOrProvinceName
-  ScepSubjectRequest commonName
-  ScepSubjectCGI OU UNIQUE_ID
-  ScepSubjectSet OU "Test Certificate"
-  CASimpleCertificate /etc/pki/certs/ca-cert.pem
-  CASimpleKey /etc/pki/certs/ca-key.pem
-  CASimpleSerialRandom on
-  CASimpleTime on
-  CADiskCertificateSignRequestPath /etc/pki/ca/
-  CADiskCertificateByTransactionPath /etc/pki/ca/
+  SetHandler 				scep
+  ScepRACertificate 			/opt/local/etc/pki/ra/ra-cert.pem
+  ScepRAKey 				/opt/local/etc/pki/ra/ra-key.pem
+  ScepSubjectRequest 			O
+  ScepSubjectRequest 			countryName
+  ScepSubjectRequest 			stateOrProvinceName
+  ScepSubjectRequest 			commonName
+  ScepSubjectSet OU 			"Test Certificate"
+  CASimpleCertificate 			/opt/local/etc/pki/ca/ca-cert.pem
+  CASimpleKey 				/opt/local/etc/pki/ca/ca-key.pem
+  CASimpleSerialRandom 			on
+  CASimpleTime 				on
+  CADiskCertificateSignRequestPath 	/opt/local/etc/pki/issued_certs/
+  CADiskCertificateByTransactionPath 	/opt/local/etc/pki/issued_certs/
 </Location>
-</IfModule>
 
-

Modified: mod_scep/trunk/mod_scep.c
==============================================================================
--- mod_scep/trunk/mod_scep.c	(original)
+++ mod_scep/trunk/mod_scep.c	Thu Oct 19 19:01:45 2023
@@ -1056,6 +1056,58 @@
     BIO_free(mem);
 }
 
+static apr_status_t sanity_check(request_rec *r, X509 *next_cert, X509* signer, const char * msg)
+{
+    X509_STORE_CTX *ctx;
+    X509_STORE *store;
+
+    ctx = X509_STORE_CTX_new();
+    if (!ctx) {
+        log_message(r, APR_SUCCESS, "could not create a X509_STORE_CTX");
+
+        return !APR_SUCCESS;
+    }
+    apr_pool_cleanup_register(r->pool, ctx, scep_X509_STORE_CTX_cleanup,
+            apr_pool_cleanup_null);
+
+    store = X509_STORE_new();
+    if (!store) {
+        log_message(r, APR_SUCCESS, "could not create a X509_STORE");
+
+        return !APR_SUCCESS;
+    }
+    apr_pool_cleanup_register(r->pool, store, scep_X509_STORE_cleanup,
+            apr_pool_cleanup_null);
+
+    if (!X509_STORE_add_cert(store, next_cert)) {
+        log_message(r, APR_SUCCESS,
+                "could not add the next CA certificate to the X509_STORE");
+
+        return !APR_SUCCESS;
+    }
+
+    if (!X509_STORE_CTX_init(ctx, store, signer, NULL)) {
+        log_message(r, APR_SUCCESS, "could not initialise the X509_STORE_CTX");
+
+        return !APR_SUCCESS;
+    }
+
+    if (!X509_verify_cert(ctx)) {
+
+        int err = X509_STORE_CTX_get_error(ctx);
+        int depth = X509_STORE_CTX_get_error_depth(ctx);
+
+        log_message(r, APR_SUCCESS,
+                apr_psprintf(r->pool,
+                        "could not verify the %s RA certificate against the %s CA certificate at depth %d in the chain: %s",
+			msg, msg, depth, X509_verify_cert_error_string(err)));
+
+        return !APR_SUCCESS;
+    }
+
+    return APR_SUCCESS;
+}
+
 /**
  * 5.2.1.  GetCACert
  *
@@ -1101,10 +1153,10 @@
     apr_off_t offset;
 
     PKCS7 *p7 = NULL;
+    PKCS7_SIGNED *p7s=NULL;
+
     BIO *b;
     X509 *cert = NULL;
-    X509_STORE_CTX *ctx;
-    X509_STORE *store;
     const unsigned char *der, *tmp;
 
     apr_bucket_brigade *bb = apr_brigade_create(r->pool,
@@ -1116,24 +1168,6 @@
     char *etag;
     apr_time_t validity;
 
-    ap_set_content_type(r, "application/x-x509-ca-ra-cert");
-
-    /* create a new signed data PKCS#7 */
-    p7 = PKCS7_new();
-    if (!p7) {
-        log_message(r, APR_SUCCESS,
-                "could not create a PKCS7 degenerate response");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-    else {
-        apr_pool_cleanup_register(r->pool, p7, scep_PKCS7_cleanup,
-                apr_pool_cleanup_null);
-    }
-
-    PKCS7_set_type(p7, NID_pkcs7_signed);
-    PKCS7_content_new(p7, NID_pkcs7_data);
-
     /* get the CA certificate */
     rv = ap_run_ca_getca(r, &der, &len, &validity);
     if (rv == DECLINED) {
@@ -1155,63 +1189,53 @@
     apr_pool_cleanup_register(r->pool, cert, scep_X509_cleanup,
             apr_pool_cleanup_null);
 
-    if (!PKCS7_add_certificate(p7, cert)) {
+    if (sanity_check(r,cert, conf->signer,"") != APR_SUCCESS) 
+        return HTTP_INTERNAL_SERVER_ERROR;
+
+    ap_set_content_type(r, "application/x-x509-ca-ra-cert");
+
+    /* RFC 8894, 3.4: For SCEP, the content field of the ContentInfo value of 
+     * a degenerate certificates-only SignedData MUST be omitted. 
+     */
+    p7 = PKCS7_new();
+    if (!p7) {
         log_message(r, APR_SUCCESS,
-                "could not add the CA certificate to the degenerate PKCS7 response");
+                "could not create a PKCS7 degenerate response");
 
         return HTTP_INTERNAL_SERVER_ERROR;
     }
-    if (!PKCS7_add_certificate(p7, conf->signer)) {
+    else {
+        apr_pool_cleanup_register(r->pool, p7, scep_PKCS7_cleanup,
+                apr_pool_cleanup_null);
+    };
+
+    p7s = PKCS7_SIGNED_new();
+    if (!p7s) {
         log_message(r, APR_SUCCESS,
-                "could not add the RA certificate to the degenerate PKCS7 response");
+                "could not create a PKCS7 signed degenerate response");
 
         return HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    /* sanity checks */
-    ctx = X509_STORE_CTX_new();
-    if (!ctx) {
-        log_message(r, APR_SUCCESS, "could not create a X509_STORE_CTX");
+    PKCS7_set_type(p7, NID_pkcs7_signed);
+    p7->d.sign = p7s;
+
+    if (!(p7s->cert = sk_X509_new_null()) || !(p7s->crl = sk_X509_CRL_new_null())) {
+        log_message(r, APR_SUCCESS,
+                "could not create a PKCS7 signed crt/crl stacks");
 
         return HTTP_INTERNAL_SERVER_ERROR;
     }
-    apr_pool_cleanup_register(r->pool, ctx, scep_X509_STORE_CTX_cleanup,
-            apr_pool_cleanup_null);
-
-    store = X509_STORE_new();
-    if (!store) {
-        log_message(r, APR_SUCCESS, "could not create a X509_STORE");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-    apr_pool_cleanup_register(r->pool, store, scep_X509_STORE_cleanup,
-            apr_pool_cleanup_null);
-
-    if (!X509_STORE_add_cert(store, cert)) {
-        log_message(r, APR_SUCCESS,
-                "could not add the CA certificate to the X509_STORE");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    if (!X509_STORE_CTX_init(ctx, store, conf->signer, NULL)) {
-        log_message(r, APR_SUCCESS, "could not initialise the X509_STORE_CTX");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    if (!X509_verify_cert(ctx)) {
-
-        int err = X509_STORE_CTX_get_error(ctx);
-        int depth = X509_STORE_CTX_get_error_depth(ctx);
-
-        log_message(r, APR_SUCCESS,
-                apr_psprintf(r->pool,
-                        "could not verify the RA certificate against the CA certificate at depth %d in the chain: %s",
-                        depth, X509_verify_cert_error_string(err)));
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
+
+    ASN1_INTEGER_set(p7s->version,1);
+    p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);
+
+    sk_X509_push(p7s->cert, cert);
+    sk_X509_push(p7s->cert, conf->signer);
+
+    // cleanup of p7->p7s affect ->signer; see equivalent
+    // in PKCS7_add_certificate()
+    X509_up_ref(conf->signer); 
 
     b = BIO_new(BIO_s_mem());
     apr_pool_cleanup_register(r->pool, b, scep_BIO_cleanup,
@@ -1220,10 +1244,17 @@
     i2d_PKCS7_bio(b, p7);
 
     apr_sha1_init(&sha1);
+    len = 0;
     while ((offset = BIO_read(b, buf, sizeof(buf))) > 0) {
         apr_sha1_update(&sha1, buf, offset);
         apr_brigade_write(bb, NULL, NULL, buf, offset);
-    }
+        len += offset;
+    }
+    if (len == 0) {
+        log_message(r, APR_SUCCESS, "Failed to create PKCS7 response");
+
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }  
 
     apr_sha1_final(digest, &sha1);
     etag = apr_palloc(r->pool, 31);
@@ -1305,8 +1336,6 @@
     PKCS7_SIGNER_INFO *si;
     BIO *b;
     X509 *next_cert = NULL;
-    X509_STORE_CTX *ctx;
-    X509_STORE *store;
     const unsigned char *der, *tmp;
 
     apr_bucket_brigade *bb = apr_brigade_create(r->pool,
@@ -1351,10 +1380,10 @@
 
         return HTTP_INTERNAL_SERVER_ERROR;
     }
-    else {
-        apr_pool_cleanup_register(r->pool, p7, scep_PKCS7_cleanup,
+
+    apr_pool_cleanup_register(r->pool, p7, scep_PKCS7_cleanup,
                 apr_pool_cleanup_null);
-    }
+
     PKCS7_set_type(p7, NID_pkcs7_signed);
     PKCS7_content_new(p7, NID_pkcs7_data);
 
@@ -1389,50 +1418,9 @@
         return HTTP_BAD_REQUEST;
     }
 
-    /* sanity checks */
-    ctx = X509_STORE_CTX_new();
-    if (!ctx) {
-        log_message(r, APR_SUCCESS, "could not create a X509_STORE_CTX");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-    apr_pool_cleanup_register(r->pool, ctx, scep_X509_STORE_CTX_cleanup,
-            apr_pool_cleanup_null);
-
-    store = X509_STORE_new();
-    if (!store) {
-        log_message(r, APR_SUCCESS, "could not create a X509_STORE");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-    apr_pool_cleanup_register(r->pool, store, scep_X509_STORE_cleanup,
-            apr_pool_cleanup_null);
-
-    if (!X509_STORE_add_cert(store, next_cert)) {
-        log_message(r, APR_SUCCESS,
-                "could not add the next CA certificate to the X509_STORE");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    if (!X509_STORE_CTX_init(ctx, store, conf->next_signer, NULL)) {
-        log_message(r, APR_SUCCESS, "could not initialise the X509_STORE_CTX");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    if (!X509_verify_cert(ctx)) {
-
-        int err = X509_STORE_CTX_get_error(ctx);
-        int depth = X509_STORE_CTX_get_error_depth(ctx);
-
-        log_message(r, APR_SUCCESS,
-                apr_psprintf(r->pool,
-                        "could not verify the next RA certificate against the next CA certificate at depth %d in the chain: %s",
-                        depth, X509_verify_cert_error_string(err)));
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
+    if (sanity_check(r, next_cert, conf->next_signer,"next") != APR_SUCCESS)
+	        return HTTP_INTERNAL_SERVER_ERROR;
+
 
     b = BIO_new(BIO_s_mem());
     apr_pool_cleanup_register(r->pool, b, scep_BIO_cleanup,



More information about the rs-commit mailing list