Explorar o código

Read client certificate information (Step 2/3)

bel %!s(int64=9) %!d(string=hai) anos
pai
achega
a84aa1b5ac
Modificáronse 1 ficheiros con 55 adicións e 2 borrados
  1. 55 2
      src/civetweb.c

+ 55 - 2
src/civetweb.c

@@ -1026,6 +1026,15 @@ typedef struct ssl_ctx_st SSL_CTX;
 typedef struct x509_store_ctx_st X509_STORE_CTX;
 typedef struct x509 X509;
 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_CLEAR_OPTIONS (77)
@@ -1128,6 +1137,8 @@ struct ssl_func {
 #define X509_get_issuer_name (*(X509_NAME * (*)(X509 *))crypto_sw[13].ptr)
 #define X509_NAME_oneline                                                      \
 	(*(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.
@@ -1186,6 +1197,8 @@ static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL},
                                       {"X509_get_subject_name", NULL},
                                       {"X509_get_issuer_name", NULL},
                                       {"X509_NAME_oneline", NULL},
+                                      {"X509_get_serialNumber", NULL},
+                                      {"i2c_ASN1_INTEGER", NULL},
                                       {NULL, NULL}};
 #endif /* NO_SSL_DL */
 #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
 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);
 		char buf1[1024];
 		char buf2[1024];
+		char buf3[1024];
+        unsigned char intbuf[256];
 		char *ret1 = X509_NAME_oneline(subj, buf1, (int)sizeof(buf1));
 		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)ret2;