|
@@ -1026,6 +1026,15 @@ typedef struct ssl_ctx_st SSL_CTX;
|
|
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
|
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
|
typedef struct x509 X509;
|
|
typedef struct x509 X509;
|
|
typedef struct x509_name X509_NAME;
|
|
typedef struct x509_name X509_NAME;
|
|
|
|
+typedef struct asn1_integer ASN1_INTEGER;
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+typedef struct asn1_bit_string_st {
|
|
|
|
+ int length;
|
|
|
|
+ int type;
|
|
|
|
+ unsigned char *data;
|
|
|
|
+} ASN1_BIT_STRING;
|
|
|
|
+*/
|
|
|
|
|
|
#define SSL_CTRL_OPTIONS (32)
|
|
#define SSL_CTRL_OPTIONS (32)
|
|
#define SSL_CTRL_CLEAR_OPTIONS (77)
|
|
#define SSL_CTRL_CLEAR_OPTIONS (77)
|
|
@@ -1128,6 +1137,8 @@ struct ssl_func {
|
|
#define X509_get_issuer_name (*(X509_NAME * (*)(X509 *))crypto_sw[13].ptr)
|
|
#define X509_get_issuer_name (*(X509_NAME * (*)(X509 *))crypto_sw[13].ptr)
|
|
#define X509_NAME_oneline \
|
|
#define X509_NAME_oneline \
|
|
(*(char *(*)(X509_NAME *, char *, int))crypto_sw[14].ptr)
|
|
(*(char *(*)(X509_NAME *, char *, int))crypto_sw[14].ptr)
|
|
|
|
+#define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *))crypto_sw[15].ptr)
|
|
|
|
+#define i2c_ASN1_INTEGER (*(int (*)(ASN1_INTEGER *, unsigned char **))crypto_sw[16].ptr)
|
|
|
|
|
|
|
|
|
|
/* set_ssl_option() function updates this array.
|
|
/* set_ssl_option() function updates this array.
|
|
@@ -1186,6 +1197,8 @@ static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL},
|
|
{"X509_get_subject_name", NULL},
|
|
{"X509_get_subject_name", NULL},
|
|
{"X509_get_issuer_name", NULL},
|
|
{"X509_get_issuer_name", NULL},
|
|
{"X509_NAME_oneline", NULL},
|
|
{"X509_NAME_oneline", NULL},
|
|
|
|
+ {"X509_get_serialNumber", NULL},
|
|
|
|
+ {"i2c_ASN1_INTEGER", NULL},
|
|
{NULL, NULL}};
|
|
{NULL, NULL}};
|
|
#endif /* NO_SSL_DL */
|
|
#endif /* NO_SSL_DL */
|
|
#endif /* NO_SSL */
|
|
#endif /* NO_SSL */
|
|
@@ -11295,6 +11308,32 @@ ssl_error(void)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+hexdump2string(void *mem, int memlen, char *buf, int buflen)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ const char hexdigit[] = "0123456789abcdef";
|
|
|
|
+
|
|
|
|
+ if (memlen <= 0 || buflen <= 0) {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ if (buflen < (3*memlen)) {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < memlen; i++) {
|
|
|
|
+ if (i > 0) {
|
|
|
|
+ buf[3 * i - 1] = ' ';
|
|
|
|
+ }
|
|
|
|
+ buf[3 * i] = hexdigit[(((uint8_t *)mem)[i] >> 4)&0xF];
|
|
|
|
+ buf[3 * i + 1] = hexdigit[((uint8_t *)mem)[i] & 0xF];
|
|
|
|
+ }
|
|
|
|
+ buf[3*memlen-1] = 0;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
static void
|
|
static void
|
|
ssl_get_client_cert_info(struct mg_connection *conn)
|
|
ssl_get_client_cert_info(struct mg_connection *conn)
|
|
{
|
|
{
|
|
@@ -11304,10 +11343,24 @@ ssl_get_client_cert_info(struct mg_connection *conn)
|
|
X509_NAME *iss = X509_get_issuer_name(cert);
|
|
X509_NAME *iss = X509_get_issuer_name(cert);
|
|
char buf1[1024];
|
|
char buf1[1024];
|
|
char buf2[1024];
|
|
char buf2[1024];
|
|
|
|
+ char buf3[1024];
|
|
|
|
+ unsigned char intbuf[256];
|
|
char *ret1 = X509_NAME_oneline(subj, buf1, (int)sizeof(buf1));
|
|
char *ret1 = X509_NAME_oneline(subj, buf1, (int)sizeof(buf1));
|
|
char *ret2 = X509_NAME_oneline(iss, buf2, (int)sizeof(buf2));
|
|
char *ret2 = X509_NAME_oneline(iss, buf2, (int)sizeof(buf2));
|
|
-
|
|
|
|
- /* TODO: store this information somewhere */
|
|
|
|
|
|
+ ASN1_INTEGER *serial = X509_get_serialNumber(cert);
|
|
|
|
+ int len = i2c_ASN1_INTEGER(serial, NULL);
|
|
|
|
+ if (len < sizeof(intbuf)) {
|
|
|
|
+ unsigned char *pbuf = intbuf;
|
|
|
|
+ int len2 = i2c_ASN1_INTEGER(serial, &pbuf);
|
|
|
|
+
|
|
|
|
+ if (!hexdump2string(intbuf, len2, buf3, (int)sizeof(buf3))) {
|
|
|
|
+ *buf3 = 0;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ *buf3 = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* TODO: store the information in buf1-3 somewhere */
|
|
(void)ret1;
|
|
(void)ret1;
|
|
(void)ret2;
|
|
(void)ret2;
|
|
|
|
|