[rs-commit] r422 - in /mod_cms_verify/trunk: README mod_cms_verify.c
rs-commit at redwax.eu
rs-commit at redwax.eu
Sat Aug 7 21:34:07 CEST 2021
Author: dirkx at redwax.eu
Date: Sat Aug 7 21:34:06 2021
New Revision: 422
Log:
Fix pool cleanup registration of state; add JSON variant support for detached sigs.
Modified:
mod_cms_verify/trunk/README
mod_cms_verify/trunk/mod_cms_verify.c
Modified: mod_cms_verify/trunk/README
==============================================================================
--- mod_cms_verify/trunk/README (original)
+++ mod_cms_verify/trunk/README Sat Aug 7 21:34:06 2021
@@ -28,5 +28,10 @@
fi
exit 0
-to confirm that this worked.
+to confirm that this worked. Besides DER PKCS#7 the JSOn format:
+ { "payload": "... base64 string ..", "signature": "... base64 string .." }
+
+is also accepted/detected; with signature a detached signature on the decoded payload string. And the signature
+again a PKCS#7 DER once decoded.
+
Modified: mod_cms_verify/trunk/mod_cms_verify.c
==============================================================================
--- mod_cms_verify/trunk/mod_cms_verify.c (original)
+++ mod_cms_verify/trunk/mod_cms_verify.c Sat Aug 7 21:34:06 2021
@@ -205,6 +205,67 @@
return NULL;
}
+static char * _extract_json(apr_pool_t *p, const char * data, apr_size_t len,
+ const unsigned char ** signature, apr_size_t * signature_len,
+ const unsigned char ** payload, apr_size_t * payload_len
+) {
+ const unsigned char ** dst = NULL;
+ const char * ptr = data;
+ const char * end = data + len;
+ apr_size_t n, *dst_len;
+
+ *signature = NULL;
+ *payload = NULL;
+ *signature_len = 0;
+ *payload_len = 0;
+
+ for(;ptr < end && isspace(*ptr); ptr++) {};
+ if (*ptr++ != '{')
+ return "No starting {";
+
+ while(!*signature || !*payload)
+ {
+ for(;ptr < end && (isspace(*ptr) || *ptr ==','); ptr++,len--) {};
+
+ if (end - ptr < 12)
+ return "Not enough data";
+
+ if (strncmp("\"signature\"",ptr,11) == 0) {
+ ptr += 11;
+ dst = signature;
+ dst_len = signature_len;
+ }
+ else
+ if (strncmp("\"payload\"",ptr,9) == 0) {
+ ptr += 9;
+ dst = payload;
+ dst_len = payload_len;
+ }
+ else {
+ return "Not some dict we know about";
+ };
+
+ for(;ptr < end && isspace(*ptr); ptr++,len--) {};
+ if (*ptr++ != ':')
+ return "No value for dict entry";
+
+ for(;ptr < end && isspace(*ptr); ptr++,len--) {};
+ if (*ptr++ != '"')
+ return "No start to the value";
+
+ for(n=0;ptr+n < end && ptr[n] != '"'; n++) {};
+ if (ptr >= end)
+ return "No end to the value";
+
+ if (((*dst = apr_palloc(p, apr_base64_decode_len(ptr))) == NULL) ||
+ ((*dst_len = apr_base64_decode_binary ((unsigned char *)*dst,ptr)) <= 0)
+ ) return "Could not decode base64";
+
+ ptr += n + 1;
+ };
+ return NULL;
+}
+
static apr_bucket *_verify(request_rec *r, BIO * in)
{
verify_config_rec *conf = ap_get_module_config(r->per_dir_config,
@@ -216,16 +277,40 @@
X509 *signer = NULL;
char *dn = NULL;
BIO *out = NULL;
-
+ const char *ptr = NULL;
+ const unsigned char * sig, *pay;
+ apr_size_t lsig, lpay;
+ long len = 0;
+ int flags = 0;
+ const char * err = NULL;
+
+ len = BIO_get_mem_data(in, &ptr);
+ if (NULL == (err = _extract_json(r->pool, ptr, len, &sig, &lsig, &pay, &lpay))) {
+ if (!(ci = d2i_CMS_ContentInfo(NULL, &sig, lsig))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, HANDLER ": could not decode: %s",
+ ERR_reason_error_string(ERR_get_error()));
+ goto exit;
+ };
+ len = lpay;
+ ptr = (const char *)pay;
+ ptr = apr_pmemdup(r->pool, ptr, len);
+ flags |= CMS_DETACHED;
+
+ BIO_reset(in);
+ BIO_write(in, ptr, len);
+ out = NULL;
+ } else
if (!(out = BIO_new(BIO_s_mem())) ||
!(ci = d2i_CMS_bio(in, NULL))) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, HANDLER ": could not decode: %s",
ERR_reason_error_string(ERR_get_error()));
goto exit;
- };
- BIO_reset(in);
-
- if (1 != CMS_verify(ci, conf->other_certs, conf->trusted_certs, NULL, out, 0)) {
+ } else {
+ ptr = NULL;
+ BIO_reset(in);
+ };
+
+ if (1 != CMS_verify(ci, conf->other_certs, conf->trusted_certs, (out == NULL) ? in : NULL, out, flags)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, HANDLER ": signature check failed: %s",
ERR_reason_error_string(ERR_get_error()));
goto exit;
@@ -242,10 +327,10 @@
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, HANDLER ": valid signature, subject=<%s>.", dn);
- const char *ptr = NULL;
- long len = BIO_get_mem_data(out, &ptr);
-
- ptr = apr_pmemdup(r->pool, ptr, len);
+ if (ptr == NULL) {
+ len = BIO_get_mem_data(out, &ptr);
+ ptr = apr_pmemdup(r->pool, ptr, len);
+ };
ret = apr_bucket_pool_create(ptr, len, r->pool, r->connection->bucket_alloc);
exit:
@@ -283,7 +368,7 @@
if (state == NULL) {
f->ctx = state = apr_palloc(r->pool, sizeof *state);
state->pbb_tmp = apr_brigade_create(r->pool, c->bucket_alloc);
- apr_pool_cleanup_register(r->pool, state->pbb_tmp, state_cleanup, apr_pool_cleanup_null);
+ apr_pool_cleanup_register(r->pool, state, state_cleanup, apr_pool_cleanup_null);
state->in = BIO_new(BIO_s_mem());
state->lenin = 0;
};
More information about the rs-commit
mailing list