diff --git a/doc/reference.conf b/doc/reference.conf index 731eadf8..d0720a57 100644 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -1407,7 +1407,8 @@ general { * * The spki_* variants operate on the SubjectPublicKeyInfo of the certificate, which does * not change unless the private key is changed. This allows the fingerprint to stay - * constant even if the certificate is reissued. + * constant even if the certificate is reissued. These fingerprints will be prefixed with + * "SPKI:SHA2-256:" or "SPKI:SHA2-512:" depending on the hash type. */ certfp_method = sha1; diff --git a/ircd/sslproc.c b/ircd/sslproc.c index efe3d764..51e594a9 100644 --- a/ircd/sslproc.c +++ b/ircd/sslproc.c @@ -482,23 +482,48 @@ ssl_process_certfp(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf) { struct Client *client_p; uint32_t fd; + uint32_t certfp_method; uint32_t len; uint8_t *certfp; char *certfp_string; + const char *method_string; + int method_len; - if(ctl_buf->buflen > 9 + RB_SSL_CERTFP_LEN) + if(ctl_buf->buflen > 13 + RB_SSL_CERTFP_LEN) return; /* bogus message..drop it.. XXX should warn here */ fd = buf_to_uint32(&ctl_buf->buf[1]); - len = buf_to_uint32(&ctl_buf->buf[5]); - certfp = (uint8_t *)&ctl_buf->buf[9]; + certfp_method = buf_to_uint32(&ctl_buf->buf[5]); + len = buf_to_uint32(&ctl_buf->buf[9]); + certfp = (uint8_t *)&ctl_buf->buf[13]; client_p = find_cli_connid_hash(fd); if(client_p == NULL) return; + + switch (certfp_method) { + case RB_SSL_CERTFP_METH_CERT_SHA1: + case RB_SSL_CERTFP_METH_CERT_SHA256: + case RB_SSL_CERTFP_METH_CERT_SHA512: + method_string = ""; + break; + + /* These names are copied from RFC 7218 */ + case RB_SSL_CERTFP_METH_SPKI_SHA256: + method_string = "SPKI:SHA2-256:"; + break; + case RB_SSL_CERTFP_METH_SPKI_SHA512: + method_string = "SPKI:SHA2-512:"; + break; + default: + return; + } + method_len = strlen(method_string); + rb_free(client_p->certfp); - certfp_string = rb_malloc(len * 2 + 1); + certfp_string = rb_malloc(method_len + len * 2 + 1); + strcpy(certfp_string, method_string); for(uint32_t i = 0; i < len; i++) - snprintf(certfp_string + 2 * i, 3, "%02x", + snprintf(certfp_string + method_len + 2 * i, 3, "%02x", certfp[i]); client_p->certfp = certfp_string; } diff --git a/ssld/ssld.c b/ssld/ssld.c index e8fb5adf..1bf90771 100644 --- a/ssld/ssld.c +++ b/ssld/ssld.c @@ -686,17 +686,18 @@ ssl_send_cipher(conn_t *conn) static void ssl_send_certfp(conn_t *conn) { - uint8_t buf[9 + RB_SSL_CERTFP_LEN]; + uint8_t buf[13 + RB_SSL_CERTFP_LEN]; - int len = rb_get_ssl_certfp(conn->mod_fd, &buf[9], certfp_method); + int len = rb_get_ssl_certfp(conn->mod_fd, &buf[13], certfp_method); if (!len) return; lrb_assert(len <= RB_SSL_CERTFP_LEN); buf[0] = 'F'; uint32_to_buf(&buf[1], conn->id); - uint32_to_buf(&buf[5], len); - mod_cmd_write_queue(conn->ctl, buf, 9 + len); + uint32_to_buf(&buf[5], certfp_method); + uint32_to_buf(&buf[9], len); + mod_cmd_write_queue(conn->ctl, buf, 13 + len); } static void