Browse code

root CAs, draft of rsa verification

aCaB authored on 2011/12/23 04:57:43
Showing 4 changed files
... ...
@@ -1,4 +1,5 @@
1 1
 #include "asn1.h"
2
+#include "md5.h"
2 3
 #include "others.h"
3 4
 #include "bignum.h"
4 5
 
... ...
@@ -14,6 +15,18 @@ static int map_sha1(fmap_t *map, void *data, unsigned int len, uint8_t sha1[SHA1
14 14
     return 0;
15 15
 }
16 16
 
17
+static int map_md5(fmap_t *map, void *data, unsigned int len, uint8_t *md5) {
18
+    cli_md5_ctx ctx;
19
+    if(!fmap_need_ptr_once(map, data, len)) {
20
+	cli_dbgmsg("map_md5: failed to read hash data\n");
21
+	return 1;
22
+    }
23
+    cli_md5_init(&ctx);
24
+    cli_md5_update(&ctx, data, len);
25
+    cli_md5_final(md5, &ctx);
26
+    return 0;
27
+}
28
+
17 29
 
18 30
 int asn1_get_obj(fmap_t *map, void *asn1data, unsigned int *asn1len, struct cli_asn1 *obj) {
19 31
     unsigned int asn1_sz = *asn1len;
... ...
@@ -422,15 +435,18 @@ int asn1_get_rsa_pubkey(fmap_t *map, void **asn1data, unsigned int *size, cli_cr
422 422
 
423 423
 int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, cli_crt *x509) {
424 424
     struct cli_asn1 crt, tbs, obj;
425
-    unsigned int avail;
425
+    unsigned int avail, tbssize;
426 426
     cli_crt_hashtype hashtype1, hashtype2;
427
+    uint8_t *tbsdata;
427 428
     void *next;
428 429
 
429 430
     if(asn1_expect_objtype(map, *asn1data, size, &crt, 0x30)) /* SEQUENCE */
430 431
 	return 1;
431 432
 
433
+    tbsdata = crt.content;
432 434
     if(asn1_expect_objtype(map, crt.content, &crt.size, &tbs, 0x30)) /* SEQUENCE - TBSCertificate */
433 435
 	return 1;
436
+    tbssize = (uint8_t *)tbs.next - tbsdata;
434 437
 
435 438
     if(asn1_expect_objtype(map, tbs.content, &tbs.size, &obj, 0xa0)) /* [0] */
436 439
 	return 1;
... ...
@@ -494,6 +510,7 @@ int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, cli_crt *x50
494 494
 	cli_dbgmsg("asn1_get_x509: found conglicting rsa hash types\n");
495 495
 	return 1;
496 496
     }
497
+    x509->hashtype = hashtype1;
497 498
 
498 499
     if(asn1_expect_objtype(map, tbs.next, &crt.size, &obj, 0x03)) /* signature */
499 500
 	return 1;
... ...
@@ -509,12 +526,14 @@ int asn1_get_x509(fmap_t *map, void **asn1data, unsigned int *size, cli_crt *x50
509 509
 	cli_dbgmsg("asn1_get_x509: cannot convert signature to big number\n");
510 510
 	return 1;
511 511
     }
512
-
513 512
     if(crt.size) {
514 513
 	cli_dbgmsg("asn1_get_x509: found unexpected extra data in signature\n");
515 514
 	return 1;
516 515
     }
517 516
 
517
+    if((x509->hashtype == CLI_SHA1RSA && map_sha1(map, tbsdata, tbssize, x509->tbshash)) || (x509->hashtype == CLI_MD5RSA && (map_md5(map, tbsdata, tbssize, x509->tbshash))))
518
+	return 1;
519
+
518 520
     *asn1data = crt.next;
519 521
     return 0;
520 522
 }
... ...
@@ -697,6 +716,7 @@ int asn1_parse_mscat(FILE *f, crtmgr *cmgr) {
697 697
 		break;
698 698
 	    }
699 699
 	    crtmgr_add(cmgr, &x509);
700
+	    crtmgr_verify(cmgr, &x509);
700 701
 	    cli_crt_clear(&x509);
701 702
 	}
702 703
 	if(dsize)
... ...
@@ -6,8 +6,11 @@
6 6
 #include "others.h"
7 7
 
8 8
 int cli_crt_init(cli_crt *x509) {
9
-    if(mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))
9
+    int ret;
10
+    if((ret = mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))) {
11
+	cli_errmsg("cli_crt_init: mp_init_multi failed with %d\n", ret);
10 12
 	return 1;
13
+    }
11 14
     x509->not_before = x509->not_after = 0;
12 15
     x509->prev = x509->next = NULL;
13 16
     return 0;
... ...
@@ -17,16 +20,24 @@ void cli_crt_clear(cli_crt *x509) {
17 17
     mp_clear_multi(&x509->n, &x509->e, &x509->sig, NULL);
18 18
 }
19 19
 
20
-int crtmgr_add(crtmgr *m, cli_crt *x509) {
20
+static cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509) {
21 21
     cli_crt *i = m->crts;
22 22
     while(i) {
23 23
 	if(x509->not_before == i->not_before && x509->not_after == i->not_after && !memcmp(x509->subject, i->subject, sizeof(i->subject))) {
24 24
 	    if(mp_cmp(&x509->n, &i->n) || mp_cmp(&x509->e, &i->e))
25 25
 		cli_dbgmsg("crtmgr_add: conflicting pk for the same cert\n");
26
-	    return 0;
26
+	    return i;
27 27
 	}
28 28
 	i = i->next;
29 29
     }
30
+    return NULL;
31
+}
32
+
33
+int crtmgr_add(crtmgr *m, cli_crt *x509) {
34
+    cli_crt *i = crtmgr_lookup(m, x509);
35
+
36
+    if(i)
37
+	return 0;
30 38
     i = cli_malloc(sizeof(*i));
31 39
     if(!i)
32 40
 	return 1;
... ...
@@ -50,10 +61,152 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) {
50 50
     if(m->crts)
51 51
 	m->crts->prev = i;
52 52
     m->crts = i;
53
-    cli_dbgmsg("crtmgr_add: added cert\n");
53
+
54
+    {
55
+	char issuer[SHA1_HASH_SIZE*2+1], subject[SHA1_HASH_SIZE*2+1], mod[1024], exp[1024];
56
+	int j;
57
+	mp_toradix_n(&i->n, mod, 16, sizeof(mod));
58
+	mp_toradix_n(&i->e, exp, 16, sizeof(exp));
59
+	for(j=0; j<SHA1_HASH_SIZE; j++) {
60
+	    sprintf(&issuer[j*2], "%02x", i->issuer[j]);
61
+	    sprintf(&subject[j*2], "%02x", i->subject[j]);
62
+	}
63
+	cli_dbgmsg("crtmgr_add: added cert s:%s i:%s n:%s e:%s\n", subject, issuer, mod, exp);
64
+    }
54 65
     return 0;
55 66
 }
56 67
 
68
+
69
+int crtmgr_verify(crtmgr *m, cli_crt *x509) {
70
+    uint8_t d[513];
71
+    cli_crt *i = m->crts;
72
+    mp_int x;
73
+    int ret, j, siglen = mp_unsigned_bin_size(&x509->sig), hashlen;
74
+
75
+    if((ret = mp_init(&x))) {
76
+	cli_errmsg("crtmgr_verify: mp_init failed with %d\n", ret);
77
+	return 1;
78
+    }
79
+    for(i = m->crts; i; i = i->next) {
80
+	if(!memcmp(x509->issuer, i->subject, sizeof(i->subject)) && siglen == mp_unsigned_bin_size(&i->n)) {
81
+	    if((ret = mp_exptmod(&x509->sig, &i->e, &i->n, &x))) {
82
+		cli_warnmsg("crtmgr_verify: verification failed: mp_exptmod failed with %d\n", ret);
83
+		continue;
84
+	    }
85
+	    if(mp_unsigned_bin_size(&x) != siglen - 1)
86
+		continue;
87
+	    if((ret = mp_to_unsigned_bin(&x, d))) {
88
+		cli_warnmsg("crtmgr_verify: mp_unsigned_bin_size failed with %d\n", ret);
89
+		continue;
90
+	    }
91
+	    if(*d != 1) /* block type 1 */
92
+		continue;
93
+
94
+	    siglen -= 1; /* sizeof(x) */
95
+	    for(j=1; j<siglen-2; j++) /* upto sizeof(x) - 2 */
96
+		if(d[j] != 0xff)
97
+		    break;
98
+	    if(j == siglen - 2)
99
+		continue;
100
+	    if(d[j] != 0)
101
+		continue;
102
+
103
+	    j++;
104
+	    siglen -= j; /* asn1 size */
105
+
106
+	    if(siglen < 2 || d[j] != 0x30 || d[j+1] + 2 != siglen)
107
+		continue;
108
+	    siglen -= 2;
109
+	    j+=2;
110
+
111
+	    if(siglen <2 || d[j] != 0x30 || (hashlen = d[j+1]) != 9) {/* FIXME - md5 */
112
+		cli_errmsg("crtmgr_verify: ACAB HERE MD5 MISSING!!!\n");
113
+		continue;
114
+	    }
115
+	    siglen -= 2;
116
+	    j+=2;
117
+	    if(siglen < hashlen || memcmp(&d[j], "\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00", hashlen)) {
118
+		cli_errmsg("crtmgr_verify: ACAB HERE MD5 MISSING!!!\n");
119
+		continue;
120
+	    }
121
+	    siglen -= hashlen;
122
+	    j += hashlen;
123
+	    hashlen = x509->hashtype == CLI_SHA1RSA ? SHA1_HASH_SIZE : 16;
124
+	    if(siglen < 2 || d[j] != 0x04 || d[j+1] != hashlen)
125
+		continue;
126
+	    siglen -= 2;
127
+	    j+=2;
128
+	    if(siglen != hashlen)
129
+		continue;
130
+	    if(memcmp(&d[j], x509->tbshash, hashlen))
131
+		continue;
132
+	    /* SEQ { SEQ { OID, NULL }, OCTET STRING */
133
+	    {
134
+		char buf[1024];
135
+		mp_toradix_n(&x, buf, 16, sizeof(buf));
136
+		cli_dbgmsg("crtmgr_verify: %u, %u, %u, %s\n", siglen, d[j+1], hashlen, buf);
137
+	    }
138
+	    return 0;
139
+	}
140
+    }
141
+    return 1;
142
+}
143
+
144
+
145
+const uint8_t MSCA_SUBJECT[] = "\x11\x3b\xd8\x6b\xed\xde\xbc\xd4\xc5\xf1\x0a\xa0\x7a\xb2\x02\x6b\x98\x2f\x4b\x92";
146
+const uint8_t MSCA_MOD[] = "\
147
+\x00\xf3\x5d\xfa\x80\x67\xd4\x5a\xa7\xa9\x0c\x2c\x90\x20\xd0\
148
+\x35\x08\x3c\x75\x84\xcd\xb7\x07\x89\x9c\x89\xda\xde\xce\xc3\
149
+\x60\xfa\x91\x68\x5a\x9e\x94\x71\x29\x18\x76\x7c\xc2\xe0\xc8\
150
+\x25\x76\x94\x0e\x58\xfa\x04\x34\x36\xe6\xdf\xaf\xf7\x80\xba\
151
+\xe9\x58\x0b\x2b\x93\xe5\x9d\x05\xe3\x77\x22\x91\xf7\x34\x64\
152
+\x3c\x22\x91\x1d\x5e\xe1\x09\x90\xbc\x14\xfe\xfc\x75\x58\x19\
153
+\xe1\x79\xb7\x07\x92\xa3\xae\x88\x59\x08\xd8\x9f\x07\xca\x03\
154
+\x58\xfc\x68\x29\x6d\x32\xd7\xd2\xa8\xcb\x4b\xfc\xe1\x0b\x48\
155
+\x32\x4f\xe6\xeb\xb8\xad\x4f\xe4\x5c\x6f\x13\x94\x99\xdb\x95\
156
+\xd5\x75\xdb\xa8\x1a\xb7\x94\x91\xb4\x77\x5b\xf5\x48\x0c\x8f\
157
+\x6a\x79\x7d\x14\x70\x04\x7d\x6d\xaf\x90\xf5\xda\x70\xd8\x47\
158
+\xb7\xbf\x9b\x2f\x6c\xe7\x05\xb7\xe1\x11\x60\xac\x79\x91\x14\
159
+\x7c\xc5\xd6\xa6\xe4\xe1\x7e\xd5\xc3\x7e\xe5\x92\xd2\x3c\x00\
160
+\xb5\x36\x82\xde\x79\xe1\x6d\xf3\xb5\x6e\xf8\x9f\x33\xc9\xcb\
161
+\x52\x7d\x73\x98\x36\xdb\x8b\xa1\x6b\xa2\x95\x97\x9b\xa3\xde\
162
+\xc2\x4d\x26\xff\x06\x96\x67\x25\x06\xc8\xe7\xac\xe4\xee\x12\
163
+\x33\x95\x31\x99\xc8\x35\x08\x4e\x34\xca\x79\x53\xd5\xb5\xbe\
164
+\x63\x32\x59\x40\x36\xc0\xa5\x4e\x04\x4d\x3d\xdb\x5b\x07\x33\
165
+\xe4\x58\xbf\xef\x3f\x53\x64\xd8\x42\x59\x35\x57\xfd\x0f\x45\
166
+\x7c\x24\x04\x4d\x9e\xd6\x38\x74\x11\x97\x22\x90\xce\x68\x44\
167
+\x74\x92\x6f\xd5\x4b\x6f\xb0\x86\xe3\xc7\x36\x42\xa0\xd0\xfc\
168
+\xc1\xc0\x5a\xf9\xa3\x61\xb9\x30\x47\x71\x96\x0a\x16\xb0\x91\
169
+\xc0\x42\x95\xef\x10\x7f\x28\x6a\xe3\x2a\x1f\xb1\xe4\xcd\x03\
170
+\x3f\x77\x71\x04\xc7\x20\xfc\x49\x0f\x1d\x45\x88\xa4\xd7\xcb\
171
+\x7e\x88\xad\x8e\x2d\xec\x45\xdb\xc4\x51\x04\xc9\x2a\xfc\xec\
172
+\x86\x9e\x9a\x11\x97\x5b\xde\xce\x53\x88\xe6\xe2\xb7\xfd\xac\
173
+\x95\xc2\x28\x40\xdb\xef\x04\x90\xdf\x81\x33\x39\xd9\xb2\x45\
174
+\xa5\x23\x87\x06\xa5\x55\x89\x31\xbb\x06\x2d\x60\x0e\x41\x18\
175
+\x7d\x1f\x2e\xb5\x97\xcb\x11\xeb\x15\xd5\x24\xa5\x94\xef\x15\
176
+\x14\x89\xfd\x4b\x73\xfa\x32\x5b\xfc\xd1\x33\x00\xf9\x59\x62\
177
+\x70\x07\x32\xea\x2e\xab\x40\x2d\x7b\xca\xdd\x21\x67\x1b\x30\
178
+\x99\x8f\x16\xaa\x23\xa8\x41\xd1\xb0\x6e\x11\x9b\x36\xc4\xde\
179
+\x40\x74\x9c\xe1\x58\x65\xc1\x60\x1e\x7a\x5b\x38\xc8\x8f\xbb\
180
+\x04\x26\x7c\xd4\x16\x40\xe5\xb6\x6b\x6c\xaa\x86\xfd\x00\xbf\
181
+\xce\xc1\x35";
182
+const uint8_t MSCA_EXP[] = "\x01\x00\x01";
183
+
184
+int crtmgr_add_roots(crtmgr *m) {
185
+    cli_crt msca;
186
+    if(cli_crt_init(&msca))
187
+	return 1;
188
+    memset(msca.issuer, '\xca', sizeof(msca.issuer));
189
+    memcpy(msca.subject, MSCA_SUBJECT, sizeof(msca.subject));
190
+    if(mp_read_unsigned_bin(&msca.n, MSCA_MOD, sizeof(MSCA_MOD)-1) || mp_read_unsigned_bin(&msca.e, MSCA_EXP, sizeof(MSCA_EXP)-1)) {
191
+	cli_crt_clear(&msca);
192
+	return 1;
193
+    }
194
+    msca.not_before = 989450362; /* May  9 23:19:22 2001 GMT */
195
+    msca.not_after = 1620602293; /* May  9 23:28:13 2021 GMT */
196
+    return crtmgr_add(m, &msca);
197
+}
198
+
57 199
 /* typedef struct { */
58 200
 /*     cli_crt *certs; */
59 201
 /*     unsigned int ncerts; */
... ...
@@ -12,6 +12,7 @@ typedef enum { CLI_SHA1RSA, CLI_MD5RSA } cli_crt_hashtype;
12 12
 typedef struct cli_crt_t {
13 13
     uint8_t subject[SHA1_HASH_SIZE];
14 14
     uint8_t issuer[SHA1_HASH_SIZE];
15
+    uint8_t tbshash[SHA1_HASH_SIZE];
15 16
     mp_int n;
16 17
     mp_int e;
17 18
     mp_int sig;
... ...
@@ -29,7 +30,8 @@ typedef struct {
29 29
 
30 30
 int cli_crt_init(cli_crt *x509);
31 31
 void cli_crt_clear(cli_crt *x509);
32
-
33 32
 int crtmgr_add(crtmgr *m, cli_crt *x509);
33
+int crtmgr_verify(crtmgr *m, cli_crt *x509);
34
+int crtmgr_add_roots(crtmgr *m);
34 35
 
35 36
 #endif
... ...
@@ -2353,6 +2353,7 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
2353 2353
 }
2354 2354
 
2355 2355
 static int cli_loadmscat(FILE *fs, struct cl_engine *engine, unsigned int options, struct cli_dbio *dbio) {
2356
+    crtmgr_add_roots(&engine->cmgr);
2356 2357
     asn1_parse_mscat(fs, &engine->cmgr);
2357 2358
     return 0;
2358 2359
 }