[rs-dev] Wildcards on SCEP

Dirk-Willem van Gulik dirkx at webweaving.org
Wed Aug 23 19:16:13 CEST 2023


Looking at Peter Gutman his test cases - I think that our configuration approach is a bit `hard' for the '*' sort of use cases.

So I am thinking about a change along the lines below:

-	If the config is a '*' and there is no limit/count specified - allow any number of them.

	We could make this still a 1 -- but then make the count by default per NID.

-	Fix/change this to work the same for subjects and altsubjects

Working draft below ( http://scep redwax.webweaving.org/scep) with a pass on anything. Not sure how useful this is in actual practice.

Dw.


Index: mod_scep/trunk/mod_scep.c
===================================================================
--- mod_scep/trunk/mod_scep.c (revision 432)
+++ mod_scep/trunk/mod_scep.c (working copy)
@@ -63,6 +63,7 @@
 #define DEFAULT_FRESHNESS 2
 #define DEFAULT_FRESHNESS_MAX 3600*24
  +#define DN_UNLIMITED (-1)
   module AP_MODULE_DECLARE_DATA scep_module;
  @@ -457,16 +458,6 @@
     scep_config_rec *conf = dconf;
     name_rec *name = apr_array_push(conf->subject);
  -    if (strcmp(arg1, "*")) {
-        name->name = arg1;
-        name->nid = OBJ_txt2nid(arg1);
-        if (name->nid == NID_undef) {
-            return apr_psprintf(cmd->pool,
-                    "Argument '%s' must be a valid subject identifier recognised by openssl",
-                    arg1);
-        }
-    }
-
     if (arg2) {
         char *end;
         name->limit = (int) apr_strtoi64(arg2, &end, 10);
@@ -479,6 +470,19 @@
         name->limit = 1;
     }
  +    if (strcmp(arg1, "*")) {
+        name->name = arg1;
+        name->nid = OBJ_txt2nid(arg1);
+        if (name->nid == NID_undef) {
+            return apr_psprintf(cmd->pool,
+                    "Argument '%s' must be a valid subject identifier recognised by openssl",
+                    arg1);
+        }
+    } else {
+ name->nid = DN_UNLIMITED;
+ if (!name->limit) name->limit = DN_UNLIMITED;
+    };
+
     conf->subject_set = 1;
       return NULL;
@@ -557,6 +561,18 @@
     scep_config_rec *conf = dconf;
     name_rec *name = apr_array_push(conf->subjectaltname);
  +    if (arg2) {
+        char *end;
+        name->limit = (int) apr_strtoi64(arg2, &end, 10);
+        if (*end || name->limit < 1) {
+            return apr_psprintf(cmd->pool,
+                    "Argument '%s' must be a positive integer", arg2);
+        }
+    }
+    else {
+        name->limit = 1;
+    }
+
     if (strcmp(arg1, "*")) {
         name->name = arg1;
         name->nid = type_from_subjectaltname(arg1);
@@ -567,21 +583,10 @@
         }
     }
     else {
-        name->nid = -1;
+        name->nid = DN_UNLIMITED; /* wildcard */
+ if (!name->limit) name->limit = DN_UNLIMITED;
     }
  -    if (arg2) {
-        char *end;
-        name->limit = (int) apr_strtoi64(arg2, &end, 10);
-        if (*end || name->limit < 1) {
-            return apr_psprintf(cmd->pool,
-                    "Argument '%s' must be a positive integer", arg2);
-        }
-    }
-    else {
-        name->limit = 1;
-    }
-
     conf->subjectaltname_set = 1;
       return NULL;
@@ -762,6 +767,25 @@
     }
 }
  +static void log_request(request_rec *r, X509_REQ *req, const char * msg)
+{
+    BIO * debug = BIO_new(BIO_s_mem());
+    char buf[HUGE_STRING_LEN];
+    int len;
+
+    apr_pool_cleanup_register(r->pool, debug, scep_BIO_cleanup,
+             apr_pool_cleanup_null);
+
+    X509_REQ_print_ex(debug, req, 0, XN_FLAG_ONELINE);
+    while ((len = BIO_gets(debug, buf, sizeof(buf))) > 0) {
+        /* Remove any LF/CR - as the logging subsystem will do this */
+        while(len && (buf[len-1] == '\n' || buf[len-1] == '\r'))
+            len --;
+        ap_log_rerror(
+                    APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, "%s: %.*s", msg, len, buf);
+    }
+}
+
 static void make_sender_nonce(request_rec *r, scep_t *rscep)
 {
     rscep->senderNonceLength = 16;
@@ -1101,10 +1177,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 +1192,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) {
@@ -1770,8 +1782,8 @@
                 X509_NAME_ENTRY *tne = X509_NAME_get_entry(reqsubject, j);
                 int nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(tne));
  -                if (!name->nid || name->nid == nid) {
-                    if (count <= 0) {
+                if (name->nid == DN_UNLIMITED || name->nid == nid) {
+                    if (name->limit != DN_UNLIMITED && count <= 0) {
                         log_message(r, APR_SUCCESS,
                                 apr_psprintf(r->pool,
                                         "Subject name '%s' cannot be inserted into certificate more than %d times.",
@@ -1809,6 +1821,8 @@
             &scep_module);
       exts = X509_REQ_get_extensions(req);
+    // test XXX X509_REQ_add_extensions(creq, exts);
+
     if (exts) {
         int idx = -1;
         gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, &idx);
@@ -1849,8 +1863,8 @@
             for (j = 0; gens && j < sk_GENERAL_NAME_num(gens); j++) {
                 GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, j);
  -                if (!name->nid || name->nid == gen->type) {
-                    if (count <= 0) {
+                if (name->nid == DN_UNLIMITED || name->nid == gen->type) {
+                    if (name->limit != DN_UNLIMITED && count <= 0) {
                         log_message(r, APR_SUCCESS,
                                 apr_psprintf(r->pool,
                                         "SubjectAltName element '%s' cannot be inserted into certificate more than %d times.",
@@ -1901,17 +1915,8 @@
     apr_hash_t *params = apr_hash_make(r->pool);
       /* print the request, if necessary */
-    if (APLOGrdebug(r)) {
-        int len;
-        debug = BIO_new(BIO_s_mem());
-        apr_pool_cleanup_register(r->pool, debug, scep_BIO_cleanup,
-                apr_pool_cleanup_null);
-        X509_REQ_print_ex(debug, req, 0, XN_FLAG_ONELINE);
-        while ((len = BIO_gets(debug, buf, sizeof(buf))) > 0) {
-            ap_log_rerror(
-                    APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, "Certificate Request: %.*s", len, buf);
-        }
-    }
+    if (APLOGrdebug(r))  + log_request(r, req, "Certificate Request");
       /**
      * Create a CSR for signing.
@@ -2038,6 +2043,9 @@
         return rv;
     }
+    if (APLOGrdebug(r))  
+ 		log_request(r, creq, "Request to Sign");
+
     /* do the signing */
     rv = ap_run_ca_sign(r, params, &buffer, &len);
     if (rv == DECLINED) {
@@ -2065,6 +2073,7 @@
               return HTTP_BAD_REQUEST;
         }
+
         apr_pool_cleanup_register(r->pool, certs, scep_PKCS7_cleanup,
                 apr_pool_cleanup_null);


More information about the rs-dev mailing list