Browse code

[WIP] Add support for SHA256 signatures

Everything should be working, but I'm having a hard time finding a binary
to test with that doesn't encounter other parsing issues (no countersignature,
extra data in the unauthenticatedAttributes section, etc.)

Andrew authored on 2018/08/24 00:37:40
Showing 3 changed files
... ...
@@ -127,6 +127,14 @@ static int map_raw(fmap_t *map, const void *data, unsigned int len, uint8_t raw[
127 127
     return 0;
128 128
 }
129 129
 
130
+static int map_sha256(fmap_t *map, const void *data, unsigned int len, uint8_t sha256[SHA256_HASH_SIZE]) {
131
+    if(!fmap_need_ptr_once(map, data, len)) {
132
+        cli_dbgmsg("map_sha256: failed to read hash data\n");
133
+        return 1;
134
+    }
135
+    return (cl_sha256(data, len, sha256, NULL) == NULL);
136
+}
137
+
130 138
 static int map_sha1(fmap_t *map, const void *data, unsigned int len, uint8_t sha1[SHA1_HASH_SIZE]) {
131 139
     if(!fmap_need_ptr_once(map, data, len)) {
132 140
         cli_dbgmsg("map_sha1: failed to read hash data\n");
... ...
@@ -282,8 +290,7 @@ static int asn1_expect_rsa(fmap_t *map, const void **asn1data, unsigned int *asn
282 282
         return 1;
283 283
     }
284 284
     else if(obj.size == lenof(OID_sha256WithRSAEncryption) && !memcmp(obj.content, OID_sha256WithRSAEncryption, lenof(OID_sha256WithRSAEncryption))) {
285
-        cli_dbgmsg("asn1_expect_rsa: SHA256 with RSA (not yet supported)\n");
286
-        return 1;
285
+        *hashtype = CLI_SHA256RSA; /* sha256WithRSAEncryption 1.2.840.113549.1.1.11 */
287 286
     }
288 287
     else if(obj.size == lenof(OID_sha512WithRSAEncryption) && !memcmp(obj.content, OID_sha512WithRSAEncryption, lenof(OID_sha512WithRSAEncryption))) {
289 288
         cli_dbgmsg("asn1_expect_rsa: SHA512 with RSA (not yet supported)\n");
... ...
@@ -759,7 +766,9 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
759 759
             break;
760 760
         }
761 761
 
762
-        if((x509.hashtype == CLI_SHA1RSA && map_sha1(map, tbsdata, tbssize, x509.tbshash)) || (x509.hashtype == CLI_MD5RSA && (map_md5(map, tbsdata, tbssize, x509.tbshash))))
762
+        if((x509.hashtype == CLI_SHA1RSA && map_sha1(map, tbsdata, tbssize, x509.tbshash)) || \
763
+           (x509.hashtype == CLI_MD5RSA && map_md5(map, tbsdata, tbssize, x509.tbshash)) || \
764
+           (x509.hashtype == CLI_SHA256RSA && map_sha256(map, tbsdata, tbssize, x509.tbshash)))
763 765
             break;
764 766
 
765 767
         if(crtmgr_add(other, &x509))
... ...
@@ -1508,6 +1517,8 @@ static int asn1_parse_mscat(fmap_t *map, size_t offset, unsigned int size, crtmg
1508 1508
             ctx = cl_hash_init("sha1");
1509 1509
         } else if (hashtype == CLI_MD5RSA) {
1510 1510
             ctx = cl_hash_init("md5");
1511
+        } else {
1512
+            break;
1511 1513
         }
1512 1514
 
1513 1515
         if (!(ctx))
... ...
@@ -27,6 +27,15 @@
27 27
 #include "others.h"
28 28
 #include "crtmgr.h"
29 29
 
30
+#define OID_1_2_840_113549_2_5 "\x2a\x86\x48\x86\xf7\x0d\x02\x05"
31
+#define OID_md5 OID_1_2_840_113549_2_5
32
+
33
+#define OID_1_3_14_3_2_26 "\x2b\x0e\x03\x02\x1a"
34
+#define OID_sha1 OID_1_3_14_3_2_26
35
+
36
+#define OID_2_16_840_1_101_3_4_2_1 "\x60\x86\x48\x01\x65\x03\x04\x02\x01"
37
+#define OID_sha256 OID_2_16_840_1_101_3_4_2_1
38
+
30 39
 int cli_crt_init(cli_crt *x509) {
31 40
     int ret;
32 41
     if((ret = mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))) {
... ...
@@ -132,7 +141,6 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) {
132 132
 
133 133
     memcpy(i->raw_subject, x509->raw_subject, sizeof(i->raw_subject));
134 134
     memcpy(i->raw_issuer, x509->raw_issuer, sizeof(i->raw_issuer));
135
-    memcpy(i->raw_tbshash, x509->raw_tbshash, sizeof(i->raw_tbshash));
136 135
     memcpy(i->raw_serial, x509->raw_serial, sizeof(i->raw_serial));
137 136
     memcpy(i->subject, x509->subject, sizeof(i->subject));
138 137
     memcpy(i->serial, x509->serial, sizeof(i->serial));
... ...
@@ -187,10 +195,21 @@ void crtmgr_free(crtmgr *m) {
187 187
 
188 188
 static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashtype, const uint8_t *refhash) {
189 189
     int keylen = mp_unsigned_bin_size(&x509->n), siglen = mp_unsigned_bin_size(sig);
190
-    int ret, j, objlen, hashlen = (hashtype == CLI_SHA1RSA) ? SHA1_HASH_SIZE : 16;
190
+    int ret, j, objlen, hashlen;
191 191
     uint8_t d[513];
192 192
     mp_int x;
193 193
 
194
+    if (hashtype == CLI_SHA1RSA) {
195
+        hashlen = SHA1_HASH_SIZE;
196
+    } else if (hashtype == CLI_MD5RSA) {
197
+        hashlen = MD5_HASH_SIZE;
198
+    } else if (hashtype == CLI_SHA256RSA) {
199
+        hashlen = SHA256_HASH_SIZE;
200
+    } else {
201
+        cli_errmsg("crtmgr_rsa_verify: Unsupported hashtype\n");
202
+        return 1;
203
+    }
204
+
194 205
     if((ret = mp_init(&x))) {
195 206
 	cli_errmsg("crtmgr_rsa_verify: mp_init failed with %d\n", ret);
196 207
 	return 1;
... ...
@@ -244,12 +263,20 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty
244 244
 	    if(keylen < objlen)
245 245
 		break;
246 246
 	    if(objlen == 9) {
247
-		if(hashtype != CLI_SHA1RSA || memcmp(&d[j], "\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00", 9)) {
247
+                // Check for OID type indicating a length of 5, OID_sha1, and the NULL type/value
248
+		if(hashtype != CLI_SHA1RSA || memcmp(&d[j], "\x06\x05" OID_sha1 "\x05\x00", 9)) {
248 249
 		    cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n");
249 250
 		    break;
250 251
 		}
251 252
 	    } else if(objlen == 12) {
252
-		if(hashtype != CLI_MD5RSA || memcmp(&d[j], "\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00", 12)) {
253
+                // Check for OID type indicating a length of 8, OID_md5, and the NULL type/value
254
+		if(hashtype != CLI_MD5RSA || memcmp(&d[j], "\x06\x08" OID_md5 "\x05\x00", 12)) {
255
+		    cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n");
256
+		    break;
257
+		}
258
+	    } else if(objlen == 13) {
259
+                // Check for OID type indicating a length of 9, OID_sha256, and the NULL type/value
260
+		if(hashtype != CLI_SHA256RSA || memcmp(&d[j], "\x06\x09" OID_sha256 "\x05\x00", 13)) {
253 261
 		    cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n");
254 262
 		    break;
255 263
 		}
... ...
@@ -26,7 +26,7 @@
26 26
 
27 27
 #include "bignum.h"
28 28
 
29
-typedef enum { CLI_SHA1RSA, CLI_MD5RSA } cli_crt_hashtype;
29
+typedef enum { CLI_SHA1RSA, CLI_MD5RSA, CLI_SHA256RSA } cli_crt_hashtype;
30 30
 typedef enum {VRFY_CODE, VRFY_TIME} cli_vrfy_type;
31 31
 
32 32
 #define CRT_RAWMAXLEN 64
... ...
@@ -34,12 +34,14 @@ typedef struct cli_crt_t {
34 34
     char *name;
35 35
     uint8_t raw_subject[CRT_RAWMAXLEN];
36 36
     uint8_t raw_issuer[CRT_RAWMAXLEN];
37
-    uint8_t raw_tbshash[CRT_RAWMAXLEN];
38 37
     uint8_t raw_serial[CRT_RAWMAXLEN];
39 38
     uint8_t subject[SHA1_HASH_SIZE];
40 39
     uint8_t issuer[SHA1_HASH_SIZE];
41
-    uint8_t tbshash[SHA1_HASH_SIZE];
42 40
     uint8_t serial[SHA1_HASH_SIZE];
41
+    /* tbshash holds the hash we'll use for verification with data in the sig,
42
+     * so it must have at least enough space for the largest hash in
43
+     * cli_crt_hashtype */
44
+    uint8_t tbshash[SHA256_HASH_SIZE];
43 45
     mp_int n;
44 46
     mp_int e;
45 47
     mp_int sig;