summaryrefslogtreecommitdiffstats
path: root/src/serve.c
diff options
context:
space:
mode:
authordece <shgck@pistache.land>2021-06-17 13:25:26 +0200
committerDrew DeVault <sir@cmpwn.com>2021-06-17 09:52:50 -0400
commitd7bd3c6a0db4c79f244d8880d86a899eb0f8ca01 (patch)
tree093109034d5cc24473112d0f37e9cb46e9a9ec7a /src/serve.c
parent0bf3cde2a0a5554651867ade37daafcea49c9409 (diff)
downloadgmnisrv-d7bd3c6a0db4c79f244d8880d86a899eb0f8ca01.tar.gz
gmnisrv-d7bd3c6a0db4c79f244d8880d86a899eb0f8ca01.tar.xz
gmnisrv-d7bd3c6a0db4c79f244d8880d86a899eb0f8ca01.zip
Support TLS_CLIENT_SERIAL_NUMBER in CGI
Diffstat (limited to 'src/serve.c')
-rw-r--r--src/serve.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/serve.c b/src/serve.c
index da17f96..aa9a743 100644
--- a/src/serve.c
+++ b/src/serve.c
@@ -200,8 +200,7 @@ serve_cgi(struct gmnisrv_client *client, const char *path,
// barebones client cert implementation
// adapted from openssl(1)'s implementation
- // TODO: support REMOTE_USER, TLS_CLIENT_NOT_{BEFORE,AFTER},
- // TLS_CLIENT_SERIAL_NUMBER
+ // TODO: support REMOTE_USER, TLS_CLIENT_NOT_{BEFORE,AFTER}
X509 *client_cert = SSL_get_peer_certificate(client->ssl);
if (client_cert != NULL) {
// 32 bytes because we're always using SHA256, but
@@ -226,6 +225,20 @@ serve_cgi(struct gmnisrv_client *client, const char *path,
const char *error = "Out of memory";
client_submit_response(client,
GEMINI_STATUS_TEMPORARY_FAILURE, error, NULL);
+ goto post_client_cert_parsing;
+ }
+
+ const ASN1_INTEGER *sn_asn = X509_get0_serialNumber(client_cert);
+ BIGNUM *sn_bn = ASN1_INTEGER_to_BN(sn_asn, NULL);
+ char *sn_dec = BN_bn2dec(sn_bn);
+ BN_free(sn_bn);
+ if (sn_dec != NULL) {
+ setenv("TLS_CLIENT_SERIAL_NUMBER", sn_dec, 1);
+ OPENSSL_free(sn_dec);
+ } else {
+ const char *error = "Invalid certificate serial number";
+ client_submit_response(client,
+ GEMINI_STATUS_CERTIFICATE_NOT_VALID, error, NULL);
}
}