[rs-commit] r415 - in /mod_sign/trunk: README mod_sign.c

rs-commit at redwax.eu rs-commit at redwax.eu
Sun Aug 2 13:53:34 CEST 2020


Author: dirkx at redwax.eu
Date: Sun Aug  2 13:53:34 2020
New Revision: 415

Log:
First functional version; cursory tested against google/apple GAEN

Modified:
    mod_sign/trunk/README
    mod_sign/trunk/mod_sign.c

Modified: mod_sign/trunk/README
==============================================================================
--- mod_sign/trunk/README	(original)
+++ mod_sign/trunk/README	Sun Aug  2 13:53:34 2020
@@ -15,16 +15,35 @@
       </Location>
    </IfModule>
  
-3) Test by doing
+3) Test by doing:
 
+	# Generate a payload and calculat the digest.
 	echo my payload > payload.txt
         openssl sha256 payload.txt
-        curl http://localhost/sign?digest=0d2a2ba99cb99e1ecc60154c49a1a56c1e67d43473709ff8e89cea6ac3d01010
 
-Or more properly
+	# Offer this digest for signing - request a binary blob back.
+	#
+        curl 'http://localhost/signdigest?digest=0d2a2ba99cb99e1ecc60154c49a1a56c1e67d43473709ff8e89cea6ac3d01010&digest_encoding=hex&signature_encoding=binary'  > sig.bin
 
-        curl 'http://localhost/sign?digest=0d2a2ba99cb99e1ecc60154c49a1a56c1e67d43473709ff8e89cea6ac3d01010&digest_type=SHA256&digest_encoding=HEX'
+	# Verify that the signature is correct. You should see 'Verified OK'
+        openssl dgst -sha256 -verify ec.pub -hex -signature sig.bin payload.txt
+ 
+Parameters
 
+	digest
+		digest itself. Accepts HEX and Base64.
+		Hex can be of the 0d2a or the 02:2a and '02 2a ..' variety.
 
+	digest_encoding	
+		HEX or base64
 
+	signature_encoding
+		HEX or base64 or Binary
 
+	digest_type
+		any type openssl support. See
+
+			openssl list  -digest-algorithms 
+
+		for a few list.
+

Modified: mod_sign/trunk/mod_sign.c
==============================================================================
--- mod_sign/trunk/mod_sign.c	(original)
+++ mod_sign/trunk/mod_sign.c	Sun Aug  2 13:53:34 2020
@@ -16,8 +16,8 @@
 
 /*
  * Sign a digest passed as a base64 value with a
- * private key. Originaly created as part of the 
- * Dutch CoronaApp effort to deal with the very 
+ * private key. Originaly created as part of the
+ * Dutch CoronaApp effort to deal with the very
  * peculiar google/apple unmanaged X9.62 DER blob.
  *
  */
@@ -27,6 +27,7 @@
 #include <apr_hash.h>
 #include <apr_uuid.h>
 #include <apr_base64.h>
+#include <assert.h>
 
 #include <openssl/err.h>
 #include <openssl/evp.h>
@@ -43,7 +44,7 @@
 #define HANDLER "sign"
 
 #define STRINGIFY(x) #x
-#define TOSTRING(x) STRINGIFY(x) 
+#define TOSTRING(x) STRINGIFY(x)
 
 
 module AP_MODULE_DECLARE_DATA sign_module;
@@ -53,14 +54,22 @@
 }    encoding_t;
 
 typedef struct {
-    const char * location;
+    const char *location;
     encoding_t encoding;
+    encoding_t outencoding;
+    const EVP_MD *md_type;
     EVP_PKEY *key;
-}  sign_config_rec;
+}      sign_config_rec;
 
 static apr_status_t sign_EVP_PKEY_cleanup(void *data)
 {
     EVP_PKEY_free((EVP_PKEY *) data);
+    return APR_SUCCESS;
+}
+
+static apr_status_t sign_ctx_cleanup(void *data)
+{
+    EVP_PKEY_CTX_free((EVP_PKEY_CTX *) data);
     return APR_SUCCESS;
 }
 
@@ -69,6 +78,8 @@
     sign_config_rec *conf = apr_pcalloc(p, sizeof(sign_config_rec));
     conf->location = d;
     conf->encoding = ENCODING_UNSET;
+    conf->outencoding = ENCODING_UNSET;
+    conf->md_type = NULL;
     conf->key = NULL;
 
     return conf;
@@ -82,26 +93,64 @@
     sign_config_rec *base = (sign_config_rec *) basev;
 
     new->encoding = (add->encoding == ENCODING_UNSET) ? base->encoding : add->encoding;
+    new->outencoding = (add->outencoding == ENCODING_UNSET) ? base->outencoding : add->outencoding;
+    new->md_type = (add->md_type == 0) ? base->md_type : add->md_type;
     new->key = (add->key == 0) ? base->key : add->key;
 
     return new;
+}
+
+static encoding_t str2enc(const char *arg)
+{
+    if (!strcasecmp(arg, "base64"))
+	return ENCODING_BASE64;
+
+    if (!strcasecmp(arg, "hex"))
+	return ENCODING_HEX;
+
+    if (!strcasecmp(arg, "binary"))
+	return ENCODING_BINARY;
+
+    return ENCODING_UNSET;
 }
 
 static const char *set_sign_encoding(cmd_parms *cmd, void *dconf,
 				          const char *arg)
 {
     sign_config_rec *conf = dconf;
-
-    if (!strcmp(arg, "base64")) {
-	conf->encoding = ENCODING_BASE64;
-    }
-    else if (!strcmp(arg, "hex")) {
-	conf->encoding = ENCODING_HEX;
-    }
-    else {
+    conf->encoding = str2enc(arg);
+
+    if (conf->encoding == ENCODING_UNSET)
 	return apr_psprintf(cmd->pool,
-		       "The encoding '%s' wasn't 'hex', or 'base64'.", arg);
-    }
+	      "The encoding '%s' wasn't 'hex', 'binary' or 'base64'.", arg);
+
+    return NULL;
+}
+
+static const char *set_sign_digest_encoding(cmd_parms *cmd, void *dconf,
+					         const char *arg)
+{
+    sign_config_rec *conf = dconf;
+    conf->outencoding = str2enc(arg);
+
+    if (conf->outencoding == ENCODING_BINARY)
+	return "Binary encoding not supported on input (we've not yet implemented POST)";
+
+    if (conf->outencoding == ENCODING_UNSET)
+	return apr_psprintf(cmd->pool,
+			"The encoding '%s' wasn't 'hex' or 'base64'.", arg);
+
+    return NULL;
+}
+
+static const char *set_sign_digest(cmd_parms *cmd, void *dconf,
+				        const char *arg)
+{
+    sign_config_rec *conf = dconf;
+
+    if ((conf->md_type = EVP_get_digestbyname(arg)) == NULL)
+	return "Unknown digest";
+
     return NULL;
 }
 
@@ -140,15 +189,6 @@
     return NULL;
 }
 
-static const command_rec sign_cmds[] =
-{
-    AP_INIT_TAKE1("SignEncoding",
-		  set_sign_encoding, NULL, RSRC_CONF | ACCESS_CONF,
-		  "Set to the default encoding to be returned if not specified. Must be \"hex\", or \"base64\". Defaults to \"base64\"."),
-    AP_INIT_TAKE1("SignKey",
-		  set_sign_key, NULL, RSRC_CONF | ACCESS_CONF,
-		  "Set the key to use to sign (mandatory, no default)"),
-{NULL}};
 
 static void log_message(request_rec *r, apr_status_t status,
 			     const char *message)
@@ -200,7 +240,8 @@
 
     query_string = apr_pstrdup(r->pool, input);
 
-    while ((key = apr_strtok(query_string, "&", &strtok_state))) {
+    key = apr_strtok(query_string, "&", &strtok_state);
+    while (key) {
 	value = strchr(key, '=');
 	if (value) {
 	    *value = '\0';	/* Split the string in two */
@@ -211,7 +252,10 @@
 	}
 	ap_unescape_url(key);
 	ap_unescape_url(value);
+
 	apr_table_set(params, key, value);
+
+	key = apr_strtok(NULL, "&", &strtok_state);
     }
     return params;
 }
@@ -224,19 +268,19 @@
     register unsigned char digit;
 
 #if !APR_CHARSET_EBCDIC
-    digit  = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
+    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
     digit *= 16;
     digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0'));
-#else /*APR_CHARSET_EBCDIC*/
+#else				/* APR_CHARSET_EBCDIC */
     char xstr[5];
-    xstr[0]='0';
-    xstr[1]='x';
-    xstr[2]=what[0];
-    xstr[3]=what[1];
-    xstr[4]='\0';
+    xstr[0] = '0';
+    xstr[1] = 'x';
+    xstr[2] = what[0];
+    xstr[3] = what[1];
+    xstr[4] = '\0';
     digit = apr_xlate_conv_byte(ap_hdrs_from_ascii, 0xFF & strtol(xstr, NULL, 16
-));
-#endif /*APR_CHARSET_EBCDIC*/
+								  ));
+#endif				/* APR_CHARSET_EBCDIC */
     return (digit);
 }
 
@@ -256,13 +300,14 @@
     return p - hexstr;
 }
 
-static encoding_t str2encoding(const char * str) {
-    if (strcasecmp(str,"hex") == 0)
-        return ENCODING_HEX;
-    if (strcasecmp(str,"base64") == 0)
-        return ENCODING_BASE64;
-    if (strcasecmp(str,"binary") == 0)
-        return ENCODING_BINARY;
+static encoding_t str2encoding(const char *str)
+{
+    if (strcasecmp(str, "hex") == 0)
+	return ENCODING_HEX;
+    if (strcasecmp(str, "base64") == 0)
+	return ENCODING_BASE64;
+    if (strcasecmp(str, "binary") == 0)
+	return ENCODING_BINARY;
     return ENCODING_UNSET;
 }
 
@@ -271,7 +316,7 @@
     apr_size_t len;
     apr_off_t offset;
     const unsigned char *der;
-    encoding_t encoding = conf->encoding == ENCODING_UNSET ? ENCODING_BASE64 : conf->encoding;
+    encoding_t encoding = conf->encoding;
     encoding_t outencoding = encoding;
     int rv;
     apr_bucket_brigade *bb = apr_brigade_create(r->pool,
@@ -279,9 +324,9 @@
     apr_bucket *e;
     apr_status_t status;
     const char *q, *qq;
-    apr_byte_t * digest;
+    apr_byte_t *digest;
     apr_size_t digest_len = 0;
-    const EVP_MD * md = NULL;
+    const EVP_MD *md;
 
     const char *accept_encoding = apr_table_get(r->headers_in,
 						"Accept-Encoding");
@@ -292,68 +337,97 @@
 	return rv;
     }
 
-    if (r->args == NULL || strlen(r->args) == 0 || strlen(r->args) > 256) {
+    if (r->args == NULL || strlen(r->args) == 0 || strlen(r->args) > 510) {
 	ap_log_rerror(
-		      APLOG_MARK, APLOG_NOTICE, status, r, "sign_handler: digest argument missing or wrong size");
+		      APLOG_MARK, APLOG_NOTICE, 0, r, "sign_handler: digest argument missing or odd sized arguments");
 	return HTTP_BAD_REQUEST;
     };
 
     apr_table_t *args = apr_querystring_to_table(r);
-    q = apr_table_get(args, "digest");
-
-    if (q == NULL || strlen(q) < 25) {
-	ap_log_rerror(
-		      APLOG_MARK, APLOG_NOTICE, status, r, "sign_handler: digest argument wrong size");
-	return HTTP_BAD_REQUEST;
-    };
-
-    if (encoding == ENCODING_HEX) {
-	digest = (apr_byte_t *)apr_pstrdup(r->pool, q); /* replacing in situ */
-	digest_len = apr_hex2bin((char *)digest);
-    }
-    else {
-	digest_len = apr_base64_decode_len(q);
-	digest = (apr_byte_t *)ap_pbase64decode(r->pool, q);
-    }
-
-    if ((q = apr_table_get(args, "digest_type")) == NULL) {
-	if (digest_len == 20)
-	    q = "SHA1";
-	else if (digest_len == 224 / 8)
-	    q = "SHA224";
-	else if (digest_len == 256 / 8)
-	    q = "SHA256";
-	else if (digest_len == 384 / 8)
-	    q = "SHA384";
-	else if (digest_len == 512 / 8)
-	    q = "SHA512";
-	else {
+
+    q = apr_table_get(args, "digest_encoding");
+    if (q) {
+	encoding_t e = str2encoding(q);
+	if (encoding != ENCODING_UNSET && e != encoding) {
 	    ap_log_rerror(
-			  APLOG_MARK, APLOG_NOTICE, status, r, "sign_handler: cannot guess digest from length.");
+			  APLOG_MARK, APLOG_NOTICE, 0, r, "sign_handler: specified digest encoding not permitted by server configuration.");
 	    return HTTP_BAD_REQUEST;
 	};
-    };
-
-    if ((md = EVP_get_digestbyname(q)) == NULL) {
+	encoding = e;
+    };
+
+    if (encoding == ENCODING_UNSET) {
 	ap_log_rerror(
-		      APLOG_MARK, APLOG_NOTICE, status, r, "sign_handler: unknown digest type");
+		      APLOG_MARK, APLOG_DEBUG, 0, r, "sign_handler: falling back to default base64 input encoding.");
+	encoding = ENCODING_BASE64;
+    };
+
+    q = apr_table_get(args, "digest");
+    if (q == NULL || strlen(q) < 25 || strlen(q) > 256) {
+	ap_log_rerror(
+		      APLOG_MARK, APLOG_NOTICE, 0, r, "sign_handler: digest missing or far too small/large.");
 	return HTTP_BAD_REQUEST;
     };
 
-    // If the server has not set an encoding; ok to
-    // to override it.
-    //
+    if (encoding == ENCODING_HEX) {
+	digest = (apr_byte_t *) apr_pstrdup(r->pool, q);	/* replacing in situ */
+	digest_len = apr_hex2bin((char *)digest);
+    }
+    else {
+	digest = apr_palloc(r->pool, apr_base64_decode_len(q));
+	digest_len = apr_base64_decode_binary(digest, q);
+    }
+
+    if (conf->md_type == NULL) {
+	if ((q = apr_table_get(args, "digest_type")) == NULL) {
+	    if (digest_len == 20)
+		q = "SHA1";
+	    else if (digest_len == 224 / 8)
+		q = "SHA224";
+	    else if (digest_len == 256 / 8)
+		q = "SHA256";
+	    else if (digest_len == 384 / 8)
+		q = "SHA384";
+	    else if (digest_len == 512 / 8)
+		q = "SHA512";
+	    else {
+		ap_log_rerror(
+			      APLOG_MARK, APLOG_NOTICE, status, r, "sign_handler: cannot guess digest from length");
+		return HTTP_BAD_REQUEST;
+	    };
+	};
+
+	if ((md = EVP_get_digestbyname(q)) == NULL) {
+	    ap_log_rerror(
+			  APLOG_MARK, APLOG_NOTICE, status, r, "sign_handler: unknown digest type");
+	    return HTTP_BAD_REQUEST;
+	};
+    };
+
+    if (EVP_MD_size(md) != digest_len) {
+	ap_log_rerror(
+		      APLOG_MARK, APLOG_NOTICE, status, r, "sign_handler: %s digest needs %d bytes, recieved %d",
+	     OBJ_nid2ln(EVP_MD_type(md)), EVP_MD_size(md), (int)digest_len);
+	return HTTP_BAD_REQUEST;
+    };
+
+    /*
+     * If the server has not set an encoding; ok to override it.
+     */
     if ((q = apr_table_get(args, "signature_encoding"))) {
-        encoding_t e = str2encoding(q);
-        if (e != outencoding && outencoding != ENCODING_UNSET) {
-	    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, status, r, 
-		"sign_handler: signature encoding type not allowed by server config");
+	encoding_t e = str2encoding(q);
+	if (e != outencoding && outencoding != ENCODING_UNSET) {
+	    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, status, r,
+			  "sign_handler: signature encoding type not allowed by server config");
 	    return HTTP_BAD_REQUEST;
-        };
-        outencoding = e;
-    };
-
-    /* what content encoding have we been asked for? */
+	};
+	outencoding = e;
+    };
+
+    /*
+     * what content encoding have we been asked for? Only looked at if none
+     * is set.
+     */
     if (accept_encoding && outencoding == ENCODING_UNSET) {
 	char *last, *token, *value;
 	if (!vary) {
@@ -377,32 +451,41 @@
 	    else {
 		value = token;
 	    }
-            encoding_t e = str2encoding(value);
-            if (e != ENCODING_UNSET) 
+	    encoding_t e = str2encoding(value);
+	    if (e != ENCODING_UNSET)
 		outencoding = e;
 
 	    token = apr_strtok(NULL, ",", &last);
 	}
     }
 
+    if (outencoding == ENCODING_UNSET) {
+	outencoding = ENCODING_BASE64;
+	ap_log_rerror(
+		      APLOG_MARK, APLOG_DEBUG, 0, r, "sign_handler: falling back to default base64 output encoding.");
+    };
+
     EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(conf->key, NULL /* no engine */ );
+    apr_pool_cleanup_register(r->pool, NULL, sign_ctx_cleanup, apr_pool_cleanup_null);
+
     size_t siglen;
 
     if ((ctx == NULL) ||
-	(EVP_PKEY_sign_init(ctx) != 1) ||
-	(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) != 1) ||
-	(EVP_PKEY_CTX_set_signature_md(ctx, md)) ||
-     ((siglen = EVP_PKEY_sign(ctx, NULL, &siglen, digest, digest_len)) <= 0)
+	(EVP_PKEY_sign_init(ctx) <= 0) ||
+    /* (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <=0 ) || */
+	(EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
 	) {
-	EVP_PKEY_CTX_free(ctx);
 	log_message(r, APR_SUCCESS, "EVP Signing context could not me initialized");
 	return HTTP_INTERNAL_SERVER_ERROR;
     };
 
+    if ((EVP_PKEY_sign(ctx, NULL, &siglen, digest, digest_len) <= 0)) {
+	log_message(r, APR_SUCCESS, "EVP Signature length check failed.");
+	return HTTP_INTERNAL_SERVER_ERROR;
+    };
     unsigned char *sig = apr_pcalloc(r->pool, siglen);
 
     int err = EVP_PKEY_sign(ctx, sig, &siglen, digest, digest_len);
-    EVP_PKEY_CTX_free(ctx);
 
     if (err != 1) {
 	log_message(r, APR_SUCCESS, "EVP Signing failed");
@@ -421,19 +504,19 @@
     if (outencoding == ENCODING_BASE64) {
 	len = apr_base64_encode_len(siglen);
 	q = (char *)apr_palloc(r->pool, 1 + len);
-	len = apr_base64_encode((char *)q, (const char *)sig, siglen);
+	len = apr_base64_encode_binary((char *)q, sig, siglen);
 	apr_brigade_write(bb, NULL, NULL, q, len);
 	//add a CR ? ?
     }
     else if (outencoding == ENCODING_HEX) {
-	q = apr_palloc(r->pool,2 * siglen + 1);
+	q = apr_palloc(r->pool, 2 * siglen + 1);
 	ap_bin2hex(sig, siglen, (char *)q);
-        len = 2*siglen;
-	apr_brigade_write(bb, NULL, NULL, q,len);
+	len = 2 * siglen;
+	apr_brigade_write(bb, NULL, NULL, q, len);
 	//add a CR ? ?
     }
     else {
-        len = siglen;
+	len = siglen;
 	apr_brigade_write(bb, NULL, NULL, (const char *)sig, len);
     };
     ap_set_content_length(r, len);
@@ -454,7 +537,7 @@
 
 static int options_wadl(request_rec *r, sign_config_rec * conf)
 {
-static const char str[] = "XXXX " TOSTRING(MODULE_MAGIC_COOKIE) " XXXX";
+    static const char str[] = "XXXX " TOSTRING(MODULE_MAGIC_COOKIE) " XXXX";
 
     int rv;
 
@@ -465,10 +548,10 @@
 
     ap_set_content_type(r, "application/vnd.sun.wadl+xml");
 
-    ap_rprintf(r,"%s",str);
+    ap_rprintf(r, "%s", str);
 
     ap_rprintf(r,
-	       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 
+	       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<wadl:application xmlns:wadl=\"http://wadl.dev.java.net/2009/02\"\n"
 	       "                  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
 	       "                  xsi:schemaLocation=\"http://wadl.dev.java.net/2009/02 file:wadl.xsd\">\n"
@@ -476,23 +559,23 @@
 	       "  <wadl:resource path=\"/\">\n"
 	       "   <wadl:method name=\"GET\" id=\"sign\">\n"
 	       "    <wadl:request>\n"
-               "     <param name=\"digest\" type=\"xsd:string\" style=\"query\" required=\"true\"/>\n" 
-               "     <param name=\"digest_type\" style=\"query\" default=\"SHA256\">\n" 
-               "             <option value=\"SHA1\"/>\n" 
-               "             <option value=\"SHA224\"/>\n" 
-               "             <option value=\"SHA256\"/>\n" 
-               "             <option value=\"SHA384\"/>\n" 
-               "             <option value=\"SHA512\"/>\n" 
-               "           </param>\n" 
-               "     <param name=\"digest_encoding\" style=\"query\" default=\"base64\">\n" 
-               "             <option value=\"hex\"/>\n" 
-               "             <option value=\"base64\"/>\n" 
-               "           </param>\n" 
-               "     <param name=\"signature_encoding\" style=\"query\" default=\"base64\">\n" 
-               "             <option value=\"hex\"/>\n" 
-               "             <option value=\"base64\"/>\n" 
-               "           </param>\n" 
-	       "    </wadl:request>\n" 
+	       "     <param name=\"digest\" type=\"xsd:string\" style=\"query\" required=\"true\"/>\n"
+    "     <param name=\"digest_type\" style=\"query\" default=\"SHA256\">\n"
+	       "             <option value=\"SHA1\"/>\n"
+	       "             <option value=\"SHA224\"/>\n"
+	       "             <option value=\"SHA256\"/>\n"
+	       "             <option value=\"SHA384\"/>\n"
+	       "             <option value=\"SHA512\"/>\n"
+	       "           </param>\n"
+	       "     <param name=\"digest_encoding\" style=\"query\" default=\"base64\">\n"
+	       "             <option value=\"hex\"/>\n"
+	       "             <option value=\"base64\"/>\n"
+	       "           </param>\n"
+	       "     <param name=\"signature_encoding\" style=\"query\" default=\"base64\">\n"
+	       "             <option value=\"hex\"/>\n"
+	       "             <option value=\"base64\"/>\n"
+	       "           </param>\n"
+	       "    </wadl:request>\n"
 	       "    <wadl:response status=\"500\">\n"
 	       "     <wadl:representation mediaType=\"text/html\">\n"
 	       "      <wadl:doc>On a configuration error, 500 Internal Server Error will be returned,\n"
@@ -500,14 +583,8 @@
 	       "                error.</wadl:doc>\n"
 	       "     </wadl:representation>\n"
 	       "    </wadl:response>\n"
-	       "    <wadl:response status=\"304\">\n"
-	   "     <wadl:representation mediaType=\"application/pkix-crl\">\n"
-	       "      <wadl:doc>If the ETag specified within the If-None-Match header is unmodified\n"
-	       "                compared to the current ETag, 304 Not Modified is returned with no body..</wadl:doc>\n"
-	       "     </wadl:representation>\n"
-	       "    </wadl:response>\n"
 	       "    <wadl:response status=\"200\">\n"
-	   "     <wadl:representation mediaType=\"application/pkix-crl\">\n"
+	       "     <wadl:representation mediaType=\"text/plain\">\n"
 	       "      <wadl:doc>After a successful signing of the digest, 200 OK will be returned\n"
 	       "                with the body containing the ASN.1 DER-encoded signature as hex, binary or base64.</wadl:doc>\n"
 	       "     </wadl:representation>\n"
@@ -516,7 +593,7 @@
 	       "  </wadl:resource>\n"
 	       " </wadl:resources>\n"
 	       "</wadl:application>\n",
-		conf->location ? conf->location :
+	       conf->location ? conf->location :
 	       apr_pstrcat(r->pool, ap_http_scheme(r), "://",
 			   r->server->server_hostname, r->uri, NULL));
 
@@ -574,7 +651,23 @@
     ap_hook_handler(sign_handler, NULL, NULL, APR_HOOK_MIDDLE);
 }
 
-AP_DECLARE_MODULE(crl) =
+static const command_rec sign_cmds[] =
+{
+    AP_INIT_TAKE1("SignEncoding",
+		  set_sign_encoding, NULL, RSRC_CONF | ACCESS_CONF,
+		  "Set to the default encoding to be returned if not specified. Must be \"hex\", or \"base64\". Defaults to \"base64\"."),
+    AP_INIT_TAKE1("SignDigestEncoding",
+		  set_sign_digest_encoding, NULL, RSRC_CONF | ACCESS_CONF,
+		  "Set to the encoding for the digest supplied. Must be \"hex\", or \"base64\". Defaults to \"base64\"."),
+    AP_INIT_TAKE1("SignDigest",
+		  set_sign_digest, NULL, RSRC_CONF | ACCESS_CONF,
+		  "Set to the digest type used. Can be any digeste supported by openssl, defaults to SHA256"),
+    AP_INIT_TAKE1("SignKey",
+		  set_sign_key, NULL, RSRC_CONF | ACCESS_CONF,
+		  "Set the key to use to sign (mandatory, no default)"),
+{NULL}};
+
+AP_DECLARE_MODULE(sign) =
 {
     STANDARD20_MODULE_STUFF,
 	create_sign_dir_config,	/* dir config creater */



More information about the rs-commit mailing list