[mod_gnutls] detect certs marked OCSP Must-Staple

personal/stbuehler/ci-build
Glenn Strauss 3 years ago
parent f56c8e58e4
commit 8422fa4573

@ -41,6 +41,7 @@
#include <gnutls/gnutls.h>
#include <gnutls/ocsp.h>
#include <gnutls/x509.h>
#include <gnutls/x509-ext.h>
#include <gnutls/abstract.h>
#ifdef GNUTLS_SKIP_GLOBAL_INIT
@ -57,6 +58,7 @@ typedef struct {
/* SNI per host: with COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
gnutls_certificate_credentials_t ssl_cred;
char trust_inited;
char must_staple;
gnutls_datum_t *ssl_pemfile_x509;
gnutls_privkey_t ssl_pemfile_pkey;
const buffer *ssl_stapling_file;
@ -976,13 +978,19 @@ mod_gnutls_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur
struct stat st;
if (0 != stat(pc->ssl_stapling_file->ptr, &st)
|| st.st_mtime <= pc->ssl_stapling_loadts) {
#if 0
if (pc->ssl_stapling_nextts < cur_ts) {
#if 0
/* discard expired OCSP stapling response */
/* Does GnuTLS detect expired OCSP response? */
/* or must we rebuild gnutls_certificate_credentials_t ? */
#endif
if (pc->must_staple) {
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
}
#endif
return 0;
}
return mod_gnutls_reload_stapling_file(srv, pc, cur_ts);
@ -1007,6 +1015,60 @@ mod_gnutls_refresh_stapling_files (server *srv, const plugin_data *p, const time
}
static int
mod_gnutls_crt_must_staple (gnutls_x509_crt_t crt)
{
/* Look for TLS features X.509 extension with value 5
* RFC 7633 https://tools.ietf.org/html/rfc7633#appendix-A
* 5 = OCSP Must-Staple (security mechanism) */
int rc;
#if GNUTLS_VERSION_NUMBER < 0x030501
unsigned int i;
char oid[128];
size_t oidsz;
for (i = 0; ; ++i) {
oidsz = sizeof(oid);
rc = gnutls_x509_crt_get_extension_info(crt, i, oid, &oidsz, NULL);
if (rc < 0 || 0 == strcmp(oid, GNUTLS_X509EXT_OID_TLSFEATURES)) break;
}
/* ext not found if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) */
if (rc < 0) return rc;
gnutls_datum_t der = { NULL, 0 };
rc = gnutls_x509_crt_get_extension_data2(crt, i, &der);
if (rc < 0) return rc;
/* DER encoding (Tag, Length, Value (TLV)) expecting: 30:03:02:01:05
* [TL[TLV]] (30=Sequence, Len=03, (02=Integer, Len=01, Value=05))
* XXX: This is not future-proof if TLS feature list values are extended */
/*const char must_staple[] = { 0x30, 0x03, 0x02, 0x01, 0x05 };*/
/*rc = (der.size == 5 && 0 == memcmp(der.data, must_staple, 5))*/
rc = (der.size >= 5 && der.data[0] == 0x30 && der.data[1] >= 0x03
&& der.data[2] == 0x2 && der.data[3] == 0x1 && der.data[4] == 0x5)
? 1
: 0;
gnutls_free(der.data);
#else
gnutls_x509_tlsfeatures_t f;
rc = gnutls_x509_tlsfeatures_init(&f);
if (rc < 0) return rc;
rc = gnutls_x509_tlsfeatures_add(f, 5); /* 5 = OCSP Must-Staple */
if (rc < 0) return rc;
rc = (0 != gnutls_x509_tlsfeatures_check_crt(f, crt));
gnutls_x509_tlsfeatures_deinit(f);
#endif
return rc; /* 1 if OCSP Must-Staple found; 0 if not */
}
static int
mod_gnutls_construct_crt_chain (plugin_cert *pc, gnutls_datum_t *d, log_error_st *errh)
{
@ -1133,6 +1195,8 @@ network_gnutls_load_pemfile (server *srv, const buffer *pemfile, const buffer *p
pc->ssl_stapling_file= ssl_stapling_file;
pc->ssl_stapling_loadts = 0;
pc->ssl_stapling_nextts = 0;
pc->must_staple =
mod_gnutls_crt_must_staple(((gnutls_x509_crt_t *)(void *)d->data)[0]);
if (d->size > 1) { /*(certificate chain provided)*/
int rc = mod_gnutls_construct_crt_chain(pc, d, srv->errh);
@ -1149,6 +1213,11 @@ network_gnutls_load_pemfile (server *srv, const buffer *pemfile, const buffer *p
/* continue without OCSP response if there is an error */
}
}
else if (pc->must_staple) {
log_error(srv->errh, __FILE__, __LINE__,
"certificate %s marked OCSP Must-Staple, "
"but ssl.stapling-file not provided", pemfile->ptr);
}
return pc;

Loading…
Cancel
Save