[rs-commit] r279 - in /mod_scep/trunk: ChangeLog mod_scep.c

rs-commit at redwax.eu rs-commit at redwax.eu
Sat Feb 15 20:03:57 CET 2020


Author: minfrin at redwax.eu
Date: Sat Feb 15 20:03:56 2020
New Revision: 279

Log:
Change the order of processing PKIOPeration requests so that PKCS7
POST bodies are parsed first before interpreting a message parameter.
This works around clients that send bogus message values along with
POST bodies.

Modified:
    mod_scep/trunk/ChangeLog
    mod_scep/trunk/mod_scep.c

Modified: mod_scep/trunk/ChangeLog
==============================================================================
--- mod_scep/trunk/ChangeLog	(original)
+++ mod_scep/trunk/ChangeLog	Sat Feb 15 20:03:56 2020
@@ -1,3 +1,10 @@
+
+Changes with v0.2.4
+
+ *) Change the order of processing PKIOPeration requests so that PKCS7
+    POST bodies are parsed first before interpreting a message parameter.
+    This works around clients that send bogus message values along with
+    POST bodies. [Graham Leggett]
 
 Changes with v0.2.3
 

Modified: mod_scep/trunk/mod_scep.c
==============================================================================
--- mod_scep/trunk/mod_scep.c	(original)
+++ mod_scep/trunk/mod_scep.c	Sat Feb 15 20:03:56 2020
@@ -910,7 +910,7 @@
         asn1_type = X509_ATTRIBUTE_get0_type(attr, 0);
 #else
         asn1_type = sk_ASN1_TYPE_value(attr->value.set, 0);
-	attr_obj = attr->object;
+        attr_obj = attr->object;
 #endif
         if (!OBJ_cmp(attr_obj, transactionId)) {
             switch (ASN1_TYPE_get(asn1_type)) {
@@ -2461,7 +2461,80 @@
     scep_t *scep;
     BIO *outbio;
 
-    if (message) {
+    /*
+     * If the incoming body has a non zero content length, and is not an HTML
+     * form (application/x-www-form-urlencoded), interpret the body as a
+     * PKCS7 message.
+     *
+     * "At a minimum, all SCEP implementations compliant with this
+     * specification MUST support [..] communication of binary data via HTTP
+     * POST..."
+     */
+    if (!ct || strcmp(ct, "application/x-www-form-urlencoded")) {
+        apr_size_t size = 0;
+        int seen_eos = 0;
+        BIO *b = BIO_new(BIO_s_mem());
+        apr_pool_cleanup_register(r->pool, b, scep_BIO_cleanup,
+                apr_pool_cleanup_null);
+        apr_bucket_brigade *bb = apr_brigade_create(r->pool,
+                r->connection->bucket_alloc);
+
+        do {
+            apr_bucket *bucket = NULL, *last = NULL;
+
+            int rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+                    APR_BLOCK_READ, HUGE_STRING_LEN);
+            if (rv != APR_SUCCESS) {
+                apr_brigade_destroy(bb);
+                return (rv == AP_FILTER_ERROR) ? rv : HTTP_BAD_REQUEST;
+            }
+
+            for (bucket = APR_BRIGADE_FIRST(bb);
+                    bucket != APR_BRIGADE_SENTINEL(bb); last = bucket, bucket =
+                            APR_BUCKET_NEXT(bucket)) {
+                const char *data;
+                apr_size_t len;
+
+                if (last) {
+                    apr_bucket_delete(last);
+                }
+                if (APR_BUCKET_IS_EOS(bucket)) {
+                    seen_eos = 1;
+                    break;
+                }
+                if (bucket->length == 0) {
+                    continue;
+                }
+
+                rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+                if (rv != APR_SUCCESS) {
+                    apr_brigade_destroy(bb);
+                    return HTTP_BAD_REQUEST;
+                }
+                BIO_write(b, data, len);
+                size += len;
+
+            }
+
+            apr_brigade_cleanup(bb);
+        } while (!seen_eos);
+
+        if (size) {
+            p7 = d2i_PKCS7_bio(b, NULL);
+            apr_pool_cleanup_register(r->pool, p7, scep_PKCS7_cleanup,
+                    apr_pool_cleanup_null);
+        }
+
+    }
+
+    /*
+     * Otherwise legacy behaviour. If message has been set, base64 decode the
+     * message and use the PKCS7 that results.
+     *
+     * "For historical reasons implementations MAY support communications of
+     *  binary data via HTTP GET".
+     */
+    if (!p7 && message) {
         unsigned char *buffer;
         char *str;
         int len;
@@ -2479,57 +2552,10 @@
         memset(buffer, 0, len);
         BIO_free(b);
     }
-    else if (ct && strcmp(ct, "application/x-www-form-urlencoded")) {
-        int seen_eos = 0;
-        BIO *b = BIO_new(BIO_s_mem());
-        apr_pool_cleanup_register(r->pool, b, scep_BIO_cleanup,
-                apr_pool_cleanup_null);
-        apr_bucket_brigade *bb = apr_brigade_create(r->pool,
-                r->connection->bucket_alloc);
-
-        do {
-            apr_bucket *bucket = NULL, *last = NULL;
-
-            int rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
-                    APR_BLOCK_READ, HUGE_STRING_LEN);
-            if (rv != APR_SUCCESS) {
-                apr_brigade_destroy(bb);
-                return (rv == AP_FILTER_ERROR) ? rv : HTTP_BAD_REQUEST;
-            }
-
-            for (bucket = APR_BRIGADE_FIRST(bb);
-                    bucket != APR_BRIGADE_SENTINEL(bb); last = bucket, bucket =
-                            APR_BUCKET_NEXT(bucket)) {
-                const char *data;
-                apr_size_t len;
-
-                if (last) {
-                    apr_bucket_delete(last);
-                }
-                if (APR_BUCKET_IS_EOS(bucket)) {
-                    seen_eos = 1;
-                    break;
-                }
-                if (bucket->length == 0) {
-                    continue;
-                }
-
-                rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
-                if (rv != APR_SUCCESS) {
-                    apr_brigade_destroy(bb);
-                    return HTTP_BAD_REQUEST;
-                }
-                BIO_write(b, data, len);
-
-            }
-
-            apr_brigade_cleanup(bb);
-        } while (!seen_eos);
-
-        p7 = d2i_PKCS7_bio(b, NULL);
-        apr_pool_cleanup_register(r->pool, p7, scep_PKCS7_cleanup,
-                apr_pool_cleanup_null);
-    }
+
+    /*
+     * No body, no message, we have nothing to work with.
+     */
     else {
         log_message(r, APR_SUCCESS,
                 "PKIOperation failed: No content body, and no 'message' parameter");



More information about the rs-commit mailing list