|
@@ -15858,14 +15858,13 @@ hexdump2string(void *mem, int memlen, char *buf, int buflen)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-static void
|
|
|
|
-ssl_get_client_cert_info(struct mg_connection *conn)
|
|
|
|
|
|
+static int
|
|
|
|
+ssl_get_client_cert_info(const struct mg_connection *conn,
|
|
|
|
+ struct mg_client_cert *client_cert)
|
|
{
|
|
{
|
|
X509 *cert = SSL_get_peer_certificate(conn->ssl);
|
|
X509 *cert = SSL_get_peer_certificate(conn->ssl);
|
|
if (cert) {
|
|
if (cert) {
|
|
- char str_subject[1024];
|
|
|
|
- char str_issuer[1024];
|
|
|
|
- char str_finger[1024];
|
|
|
|
|
|
+ char str_buf[1024];
|
|
unsigned char buf[256];
|
|
unsigned char buf[256];
|
|
char *str_serial = NULL;
|
|
char *str_serial = NULL;
|
|
unsigned int ulen;
|
|
unsigned int ulen;
|
|
@@ -15885,12 +15884,18 @@ ssl_get_client_cert_info(struct mg_connection *conn)
|
|
|
|
|
|
/* Translate serial number to a hex string */
|
|
/* Translate serial number to a hex string */
|
|
BIGNUM *serial_bn = ASN1_INTEGER_to_BN(serial, NULL);
|
|
BIGNUM *serial_bn = ASN1_INTEGER_to_BN(serial, NULL);
|
|
- str_serial = BN_bn2hex(serial_bn);
|
|
|
|
- BN_free(serial_bn);
|
|
|
|
|
|
+ if (serial_bn) {
|
|
|
|
+ str_serial = BN_bn2hex(serial_bn);
|
|
|
|
+ BN_free(serial_bn);
|
|
|
|
+ }
|
|
|
|
+ client_cert->serial =
|
|
|
|
+ str_serial ? mg_strdup_ctx(str_serial, conn->phys_ctx) : NULL;
|
|
|
|
|
|
/* Translate subject and issuer to a string */
|
|
/* Translate subject and issuer to a string */
|
|
- (void)X509_NAME_oneline(subj, str_subject, (int)sizeof(str_subject));
|
|
|
|
- (void)X509_NAME_oneline(iss, str_issuer, (int)sizeof(str_issuer));
|
|
|
|
|
|
+ (void)X509_NAME_oneline(subj, str_buf, (int)sizeof(str_buf));
|
|
|
|
+ client_cert->subject = mg_strdup_ctx(str_buf, conn->phys_ctx);
|
|
|
|
+ (void)X509_NAME_oneline(iss, str_buf, (int)sizeof(str_buf));
|
|
|
|
+ client_cert->issuer = mg_strdup_ctx(str_buf, conn->phys_ctx);
|
|
|
|
|
|
/* Calculate SHA1 fingerprint and store as a hex string */
|
|
/* Calculate SHA1 fingerprint and store as a hex string */
|
|
ulen = 0;
|
|
ulen = 0;
|
|
@@ -15912,34 +15917,19 @@ ssl_get_client_cert_info(struct mg_connection *conn)
|
|
mg_free(tmp_buf);
|
|
mg_free(tmp_buf);
|
|
}
|
|
}
|
|
|
|
|
|
- if (!hexdump2string(
|
|
|
|
- buf, (int)ulen, str_finger, (int)sizeof(str_finger))) {
|
|
|
|
- *str_finger = 0;
|
|
|
|
|
|
+ if (!hexdump2string(buf, (int)ulen, str_buf, (int)sizeof(str_buf))) {
|
|
|
|
+ *str_buf = 0;
|
|
}
|
|
}
|
|
|
|
+ client_cert->finger = mg_strdup_ctx(str_buf, conn->phys_ctx);
|
|
|
|
|
|
- conn->request_info.client_cert = (struct mg_client_cert *)
|
|
|
|
- mg_malloc_ctx(sizeof(struct mg_client_cert), conn->phys_ctx);
|
|
|
|
- if (conn->request_info.client_cert) {
|
|
|
|
- conn->request_info.client_cert->peer_cert = (void *)cert;
|
|
|
|
- conn->request_info.client_cert->subject =
|
|
|
|
- mg_strdup_ctx(str_subject, conn->phys_ctx);
|
|
|
|
- conn->request_info.client_cert->issuer =
|
|
|
|
- mg_strdup_ctx(str_issuer, conn->phys_ctx);
|
|
|
|
- conn->request_info.client_cert->serial =
|
|
|
|
- mg_strdup_ctx(str_serial, conn->phys_ctx);
|
|
|
|
- conn->request_info.client_cert->finger =
|
|
|
|
- mg_strdup_ctx(str_finger, conn->phys_ctx);
|
|
|
|
- } else {
|
|
|
|
- mg_cry_internal(conn,
|
|
|
|
- "%s",
|
|
|
|
- "Out of memory: Cannot allocate memory for client "
|
|
|
|
- "certificate");
|
|
|
|
- }
|
|
|
|
|
|
+ client_cert->peer_cert = (void *)cert;
|
|
|
|
|
|
/* Strings returned from bn_bn2hex must be freed using OPENSSL_free,
|
|
/* Strings returned from bn_bn2hex must be freed using OPENSSL_free,
|
|
* see https://linux.die.net/man/3/bn_bn2hex */
|
|
* see https://linux.die.net/man/3/bn_bn2hex */
|
|
OPENSSL_free(str_serial);
|
|
OPENSSL_free(str_serial);
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -18920,7 +18910,10 @@ worker_thread_run(struct mg_connection *conn)
|
|
/* conn->dom_ctx is set in get_request */
|
|
/* conn->dom_ctx is set in get_request */
|
|
|
|
|
|
/* Get SSL client certificate information (if set) */
|
|
/* Get SSL client certificate information (if set) */
|
|
- ssl_get_client_cert_info(conn);
|
|
|
|
|
|
+ struct mg_client_cert client_cert;
|
|
|
|
+ if (ssl_get_client_cert_info(conn, &client_cert)) {
|
|
|
|
+ conn->request_info.client_cert = &client_cert;
|
|
|
|
+ }
|
|
|
|
|
|
/* process HTTPS connection */
|
|
/* process HTTPS connection */
|
|
#if defined(USE_HTTP2)
|
|
#if defined(USE_HTTP2)
|
|
@@ -18954,7 +18947,6 @@ worker_thread_run(struct mg_connection *conn)
|
|
conn->request_info.client_cert->issuer = 0;
|
|
conn->request_info.client_cert->issuer = 0;
|
|
conn->request_info.client_cert->serial = 0;
|
|
conn->request_info.client_cert->serial = 0;
|
|
conn->request_info.client_cert->finger = 0;
|
|
conn->request_info.client_cert->finger = 0;
|
|
- mg_free(conn->request_info.client_cert);
|
|
|
|
conn->request_info.client_cert = 0;
|
|
conn->request_info.client_cert = 0;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|