Browse code

Set the certSign flag for certificates without a KeyUsage The MS MD5 root cert doesn't have the KeyUsage set and appears to validate just fine

Andrew authored on 2018/09/12 23:04:35
Showing 1 changed files
... ...
@@ -850,6 +850,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
850 850
             avail = obj.type - 0xa0;
851 851
             if(obj.type == 0xa3) {
852 852
                 struct cli_asn1 exts;
853
+                int have_key_usage = 0;
853 854
                 int have_ext_key = 0;
854 855
                 if(asn1_expect_objtype(map, obj.content, &obj.size, &exts, ASN1_TYPE_SEQUENCE)) {
855 856
                     tbs.size = 1;
... ...
@@ -907,6 +908,7 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
907 907
                         /* KeyUsage 2.5.29.15 */
908 908
                         const uint8_t *keyusage = value.content;
909 909
                         uint8_t usage;
910
+                        have_key_usage = 1;
910 911
                         if(value.size < 4 || value.size > 5) {
911 912
                             cli_dbgmsg("asn1_get_x509: bad KeyUsage\n");
912 913
                             exts.size = 1;
... ...
@@ -992,8 +994,29 @@ static int asn1_get_x509(fmap_t *map, const void **asn1data, unsigned int *size,
992 992
                     tbs.size = 1;
993 993
                     break;
994 994
                 }
995
+
996
+                /* The 2008 spec doc says that for a certificate to be used for
997
+                 * code signing, it must either have an EKU indicating code
998
+                 * signing or the entire certificate chain must not have any
999
+                 * EKUs.
1000
+                 * TODO We should actually enforce that last check.
1001
+                 * For time stamping, the doc says the EKU must be present, and
1002
+                 * makes no exception for EKUs being missing.
1003
+                 * TODO Should we not set timeSign = 1 in this case, then? */
995 1004
                 if(!have_ext_key)
996 1005
                     x509.codeSign = x509.timeSign = 1;
1006
+
1007
+                /* RFC 3280 section 4.2.1.3 says that if a certificate is
1008
+                 * used to validate digital signatures on other public key
1009
+                 * certificates, it MUST have a key usage extension with the
1010
+                 * appropriate bits set.  However, the MS MD5 root authority
1011
+                 * certificate (A43489159A520F0D93D032CCAF37E7FE20A8B419)
1012
+                 * doesn't have a KU or any EKUs, and PEs with it in the
1013
+                 * chain validate successfully.
1014
+                 * TODO Flip the certSign bit for now, but revisit if
1015
+                 * a clarification on this becomes available */
1016
+                if(!have_key_usage)
1017
+                    x509.certSign = 1;
997 1018
             }
998 1019
         }
999 1020
         if(tbs.size) {