Browse code

Add minimal support for parsing SHA384-based certificates

This doesn't add support to actually verify whitelisting rules
against SHA384 signatures, but makes it so that verification
doesn't fail completely if there is a SHA384 certificate somewhere
in the signature.

Andrew authored on 2018/08/24 12:19:47
Showing 3 changed files
... ...
@@ -52,6 +52,9 @@
52 52
 #define OID_1_2_840_113549_1_1_11 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b"
53 53
 #define OID_sha256WithRSAEncryption OID_1_2_840_113549_1_1_11
54 54
 
55
+#define OID_1_2_840_113549_1_1_12 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0c"
56
+#define OID_sha384WithRSAEncryption OID_1_2_840_113549_1_1_12
57
+
55 58
 #define OID_1_2_840_113549_1_1_13 "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0d"
56 59
 #define OID_sha512WithRSAEncryption OID_1_2_840_113549_1_1_13
57 60
 
... ...
@@ -277,7 +280,19 @@ static int asn1_expect_rsa(fmap_t *map, const void **asn1data, unsigned int *asn
277 277
 
278 278
     if(asn1_expect_objtype(map, obj.content, &avail, &obj, ASN1_TYPE_OBJECT_ID))
279 279
         return 1;
280
-    if(obj.size != lenof(OID_sha1WithRSA) && obj.size != lenof(OID_sha1WithRSAEncryption)) { /* lenof(OID_sha1WithRSAEncryption) = lenof(OID_md5WithRSAEncryption) = 9 */
280
+
281
+    // Two cases to check for:
282
+    // obj.size == 5:
283
+    //  - OID_sha1WithRSA
284
+    //
285
+    // obj.size == 9:
286
+    //  - OID_md2WithRSAEncryption
287
+    //  - OID_md5WithRSAEncryption
288
+    //  - OID_sha1WithRSAEncryption
289
+    //  - OID_sha256WithRSAEncryption
290
+    //  - OID_sha384WithRSAEncryption
291
+    //  - OID_sha512WithRSAEncryption
292
+    if(obj.size != lenof(OID_sha1WithRSA) && obj.size != lenof(OID_sha1WithRSAEncryption)) {
281 293
         cli_dbgmsg("asn1_expect_rsa: expecting OID with size 5 or 9, got %02x with size %u\n", obj.type, obj.size);
282 294
         return 1;
283 295
     }
... ...
@@ -285,22 +300,33 @@ static int asn1_expect_rsa(fmap_t *map, const void **asn1data, unsigned int *asn
285 285
         cli_dbgmsg("asn1_expect_rsa: failed to read OID\n");
286 286
         return 1;
287 287
     }
288
-    if(obj.size == lenof(OID_sha1WithRSA) && !memcmp(obj.content, OID_sha1WithRSA, lenof(OID_sha1WithRSA)))
289
-        *hashtype = CLI_SHA1RSA; /* Obsolete sha1rsa 1.3.14.3.2.29 */
290
-    else if(obj.size == lenof(OID_sha1WithRSAEncryption) && !memcmp(obj.content, OID_sha1WithRSAEncryption, lenof(OID_sha1WithRSAEncryption)))
291
-        *hashtype = CLI_SHA1RSA; /* sha1withRSAEncryption 1.2.840.113549.1.1.5 */
292
-    else if(obj.size == lenof(OID_md5WithRSAEncryption) && !memcmp(obj.content, OID_md5WithRSAEncryption, lenof(OID_md5WithRSAEncryption)))
293
-        *hashtype = CLI_MD5RSA; /* md5withRSAEncryption 1.2.840.113549.1.1.4 */
294
-    else if(obj.size == lenof(OID_md2WithRSAEncryption) && !memcmp(obj.content, OID_md2WithRSAEncryption, lenof(OID_md2WithRSAEncryption))) {
295
-        cli_dbgmsg("asn1_expect_rsa: MD2 with RSA (not yet supported)\n");
296
-        return 1;
297
-    }
298
-    else if(obj.size == lenof(OID_sha256WithRSAEncryption) && !memcmp(obj.content, OID_sha256WithRSAEncryption, lenof(OID_sha256WithRSAEncryption))) {
299
-        *hashtype = CLI_SHA256RSA; /* sha256WithRSAEncryption 1.2.840.113549.1.1.11 */
300
-    }
301
-    else if(obj.size == lenof(OID_sha512WithRSAEncryption) && !memcmp(obj.content, OID_sha512WithRSAEncryption, lenof(OID_sha512WithRSAEncryption))) {
302
-        cli_dbgmsg("asn1_expect_rsa: SHA512 with RSA (not yet supported)\n");
303
-        return 1;
288
+    if(obj.size == lenof(OID_sha1WithRSA)) {
289
+
290
+        if(!memcmp(obj.content, OID_sha1WithRSA, lenof(OID_sha1WithRSA)))
291
+            *hashtype = CLI_SHA1RSA; /* Obsolete sha1rsa 1.3.14.3.2.29 */
292
+
293
+    } else if (obj.size == lenof(OID_sha1WithRSAEncryption)) {
294
+
295
+        if(!memcmp(obj.content, OID_sha1WithRSAEncryption, lenof(OID_sha1WithRSAEncryption)))
296
+            *hashtype = CLI_SHA1RSA; /* sha1withRSAEncryption 1.2.840.113549.1.1.5 */
297
+
298
+        else if(!memcmp(obj.content, OID_md5WithRSAEncryption, lenof(OID_md5WithRSAEncryption)))
299
+            *hashtype = CLI_MD5RSA; /* md5withRSAEncryption 1.2.840.113549.1.1.4 */
300
+
301
+        else if(!memcmp(obj.content, OID_md2WithRSAEncryption, lenof(OID_md2WithRSAEncryption))) {
302
+            cli_dbgmsg("asn1_expect_rsa: MD2 with RSA (not yet supported)\n");
303
+            return 1;
304
+        }
305
+        else if(!memcmp(obj.content, OID_sha256WithRSAEncryption, lenof(OID_sha256WithRSAEncryption))) {
306
+            *hashtype = CLI_SHA256RSA; /* sha256WithRSAEncryption 1.2.840.113549.1.1.11 */
307
+        }
308
+        else if(!memcmp(obj.content, OID_sha384WithRSAEncryption, lenof(OID_sha384WithRSAEncryption))) {
309
+            *hashtype = CLI_SHA384RSA; /* sha384WithRSAEncryption 1.2.840.113549.1.1.12 */
310
+        }
311
+        else if(!memcmp(obj.content, OID_sha512WithRSAEncryption, lenof(OID_sha512WithRSAEncryption))) {
312
+            cli_dbgmsg("asn1_expect_rsa: SHA512 with RSA (not yet supported)\n");
313
+            return 1;
314
+        }
304 315
     }
305 316
     else {
306 317
         cli_dbgmsg("asn1_expect_rsa: OID mismatch (size %u)\n", obj.size);
... ...
@@ -509,35 +535,47 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
509 509
         return 1;
510 510
 
511 511
     do {
512
-        if(asn1_expect_objtype(map, *asn1data, size, &crt, ASN1_TYPE_SEQUENCE)) /* SEQUENCE */
512
+        if(asn1_expect_objtype(map, *asn1data, size, &crt, ASN1_TYPE_SEQUENCE)) { /* SEQUENCE */
513
+            cli_dbgmsg("asn1_get_x509: expected SEQUENCE at the x509 start\n");
513 514
             break;
515
+        }
514 516
         *asn1data = crt.next;
515 517
 
516 518
         tbsdata = crt.content;
517
-        if(asn1_expect_objtype(map, crt.content, &crt.size, &tbs, ASN1_TYPE_SEQUENCE)) /* SEQUENCE - TBSCertificate */
519
+        if(asn1_expect_objtype(map, crt.content, &crt.size, &tbs, ASN1_TYPE_SEQUENCE)) { /* SEQUENCE - TBSCertificate */
520
+            cli_dbgmsg("asn1_get_x509: expected SEQUENCE at the TBSCertificate start\n");
518 521
             break;
522
+        }
519 523
         tbssize = (uint8_t *)tbs.next - tbsdata;
520 524
 
521
-        if(asn1_expect_objtype(map, tbs.content, &tbs.size, &obj, 0xa0)) /* [0] */
525
+        if(asn1_expect_objtype(map, tbs.content, &tbs.size, &obj, 0xa0)) { /* [0] */
526
+            cli_dbgmsg("asn1_get_x509: expected [0] version container in TBSCertificate\n");
522 527
             break;
528
+        }
523 529
         avail = obj.size;
524 530
         next = obj.next;
525
-        if(asn1_expect_obj(map, &obj.content, &avail, ASN1_TYPE_INTEGER, 1, "\x02")) /* version 3 only */
531
+        if(asn1_expect_obj(map, &obj.content, &avail, ASN1_TYPE_INTEGER, 1, "\x02")) { /* version 3 only */
532
+            cli_dbgmsg("asn1_get_x509: unexpected type or value for TBSCertificate version\n");
526 533
             break;
534
+        }
527 535
         if(avail) {
528 536
             cli_dbgmsg("asn1_get_x509: found unexpected extra data in version\n");
529 537
             break;
530 538
         }
531 539
 
532
-        if(asn1_expect_objtype(map, next, &tbs.size, &obj, ASN1_TYPE_INTEGER)) /* serialNumber */
540
+        if(asn1_expect_objtype(map, next, &tbs.size, &obj, ASN1_TYPE_INTEGER)) { /* serialNumber */
541
+            cli_dbgmsg("asn1_get_x509: expected x509 serial INTEGER\n");
533 542
             break;
543
+        }
534 544
         if(map_raw(map, obj.content, obj.size, x509.raw_serial))
535 545
             break;
536 546
         if(map_sha1(map, obj.content, obj.size, x509.serial))
537 547
             break;
538 548
 
539
-        if(asn1_expect_rsa(map, &obj.next, &tbs.size, &hashtype1)) /* algo - Ex: sha1WithRSAEncryption */
549
+        if(asn1_expect_rsa(map, &obj.next, &tbs.size, &hashtype1)) { /* algo - Ex: sha1WithRSAEncryption */
550
+            cli_dbgmsg("asn1_get_x509: unable to parse AlgorithmIdentifier\n");
540 551
             break;
552
+        }
541 553
 
542 554
         if(asn1_expect_objtype(map, obj.next, &tbs.size, &obj, ASN1_TYPE_SEQUENCE)) /* issuer */
543 555
             break;
... ...
@@ -578,6 +578,7 @@ extern int cl_scanmap_callback(cl_fmap_t *map, const char *filename, const char
578 578
 #define MD5_HASH_SIZE 16
579 579
 #define SHA1_HASH_SIZE 20
580 580
 #define SHA256_HASH_SIZE 32
581
+#define SHA384_HASH_SIZE 48
581 582
 
582 583
 /** Generate a hash of data.
583 584
  @param[in] alg The hashing algorithm to use
... ...
@@ -622,6 +623,15 @@ unsigned char *cl_hash_file_fp(FILE *fp, const char *alg, unsigned int *olen);
622 622
  */
623 623
 unsigned char *cl_sha256(const void *buf, size_t len, unsigned char *obuf, unsigned int *olen);
624 624
 
625
+/** Generate a sha384 hash of data
626
+ @param[in] buf The data to hash
627
+ @param[in] len The length of the to-be-hashed data
628
+ @param[out] obuf An optional pointer to store the generated hash. Use NULL to dynamically allocate buffer.
629
+ @param[out] olen An optional pointer that stores how long the generated hash is.
630
+ @return A pointer to the buffer that holds the generated hash
631
+ */
632
+unsigned char *cl_sha384(const void *buf, size_t len, unsigned char *obuf, unsigned int *olen);
633
+
625 634
 /** Generate a sha1 hash of data
626 635
  @param[in] buf The data to hash
627 636
  @param[in] len The length of the to-be-hashed data
... ...
@@ -26,7 +26,7 @@
26 26
 
27 27
 #include "bignum.h"
28 28
 
29
-typedef enum { CLI_SHA1RSA, CLI_MD5RSA, CLI_SHA256RSA } cli_crt_hashtype;
29
+typedef enum { CLI_SHA1RSA, CLI_MD5RSA, CLI_SHA256RSA, CLI_SHA384RSA } cli_crt_hashtype;
30 30
 typedef enum {VRFY_CODE, VRFY_TIME} cli_vrfy_type;
31 31
 
32 32
 #define CRT_RAWMAXLEN 64
... ...
@@ -41,7 +41,7 @@ typedef struct cli_crt_t {
41 41
     /* tbshash holds the hash we'll use for verification with data in the sig,
42 42
      * so it must have at least enough space for the largest hash in
43 43
      * cli_crt_hashtype */
44
-    uint8_t tbshash[SHA256_HASH_SIZE];
44
+    uint8_t tbshash[SHA384_HASH_SIZE];
45 45
     mp_int n;
46 46
     mp_int e;
47 47
     mp_int sig;