1
0
forked from aniani/gmnisrv

Support TLS_CLIENT_SERIAL_NUMBER in CGI

This commit is contained in:
dece 2021-06-17 13:25:26 +02:00 committed by Drew DeVault
parent 0bf3cde2a0
commit d7bd3c6a0d
2 changed files with 18 additions and 2 deletions

View File

@ -181,6 +181,9 @@ The following environment variables will be set:
| *TLS_CLIENT_HASH* | *TLS_CLIENT_HASH*
: SHA256:BD3A388021A92017B781504A3D24F324BF9DE11CE72606AB445D98A8EB00C5A8 : SHA256:BD3A388021A92017B781504A3D24F324BF9DE11CE72606AB445D98A8EB00C5A8
: Unique fingerprint of the client certificate. : Unique fingerprint of the client certificate.
| *TLS_CLIENT_SERIAL_NUMBER*
: 717823108622037499122666796829184010024179612962
: Serial number (decimal) of the client certificate.
\[1]: gemini://example.org/cgi-bin/foo.sh/bar?hello=world \[1]: gemini://example.org/cgi-bin/foo.sh/bar?hello=world

View File

@ -200,8 +200,7 @@ serve_cgi(struct gmnisrv_client *client, const char *path,
// barebones client cert implementation // barebones client cert implementation
// adapted from openssl(1)'s implementation // adapted from openssl(1)'s implementation
// TODO: support REMOTE_USER, TLS_CLIENT_NOT_{BEFORE,AFTER}, // TODO: support REMOTE_USER, TLS_CLIENT_NOT_{BEFORE,AFTER}
// TLS_CLIENT_SERIAL_NUMBER
X509 *client_cert = SSL_get_peer_certificate(client->ssl); X509 *client_cert = SSL_get_peer_certificate(client->ssl);
if (client_cert != NULL) { if (client_cert != NULL) {
// 32 bytes because we're always using SHA256, but // 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"; const char *error = "Out of memory";
client_submit_response(client, client_submit_response(client,
GEMINI_STATUS_TEMPORARY_FAILURE, error, NULL); 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);
} }
} }