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.
... | ... |
@@ -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; |