|
@@ -683,12 +683,92 @@ static int x509_parse_key_usage ( struct x509_certificate *cert,
|
683
|
683
|
return 0;
|
684
|
684
|
}
|
685
|
685
|
|
|
686
|
+/** "id-kp-codeSigning" object identifier */
|
|
687
|
+static uint8_t oid_code_signing[] = { ASN1_OID_CODESIGNING };
|
|
688
|
+
|
|
689
|
+/** Supported key purposes */
|
|
690
|
+static struct x509_key_purpose x509_key_purposes[] = {
|
|
691
|
+ {
|
|
692
|
+ .name = "codeSigning",
|
|
693
|
+ .bits = X509_CODE_SIGNING,
|
|
694
|
+ .oid = ASN1_OID_CURSOR ( oid_code_signing ),
|
|
695
|
+ },
|
|
696
|
+};
|
|
697
|
+
|
|
698
|
+/**
|
|
699
|
+ * Parse X.509 certificate key purpose identifier
|
|
700
|
+ *
|
|
701
|
+ * @v cert X.509 certificate
|
|
702
|
+ * @v raw ASN.1 cursor
|
|
703
|
+ * @ret rc Return status code
|
|
704
|
+ */
|
|
705
|
+static int x509_parse_key_purpose ( struct x509_certificate *cert,
|
|
706
|
+ const struct asn1_cursor *raw ) {
|
|
707
|
+ struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
|
|
708
|
+ struct x509_key_purpose *purpose;
|
|
709
|
+ struct asn1_cursor cursor;
|
|
710
|
+ unsigned int i;
|
|
711
|
+ int rc;
|
|
712
|
+
|
|
713
|
+ /* Enter keyPurposeId */
|
|
714
|
+ memcpy ( &cursor, raw, sizeof ( cursor ) );
|
|
715
|
+ if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
|
|
716
|
+ DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
|
|
717
|
+ DBGC_HDA ( cert, 0, raw->data, raw->len );
|
|
718
|
+ return rc;
|
|
719
|
+ }
|
|
720
|
+
|
|
721
|
+ /* Identify key purpose */
|
|
722
|
+ for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
|
|
723
|
+ sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
|
|
724
|
+ purpose = &x509_key_purposes[i];
|
|
725
|
+ if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
|
|
726
|
+ DBGC ( cert, "X509 %p has key purpose %s\n",
|
|
727
|
+ cert, purpose->name );
|
|
728
|
+ ext_usage->bits |= purpose->bits;
|
|
729
|
+ return 0;
|
|
730
|
+ }
|
|
731
|
+ }
|
|
732
|
+
|
|
733
|
+ /* Ignore unrecognised key purposes */
|
|
734
|
+ return 0;
|
|
735
|
+}
|
|
736
|
+
|
|
737
|
+/**
|
|
738
|
+ * Parse X.509 certificate extended key usage
|
|
739
|
+ *
|
|
740
|
+ * @v cert X.509 certificate
|
|
741
|
+ * @v raw ASN.1 cursor
|
|
742
|
+ * @ret rc Return status code
|
|
743
|
+ */
|
|
744
|
+static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
|
|
745
|
+ const struct asn1_cursor *raw ) {
|
|
746
|
+ struct asn1_cursor cursor;
|
|
747
|
+ int rc;
|
|
748
|
+
|
|
749
|
+ /* Enter extKeyUsage */
|
|
750
|
+ memcpy ( &cursor, raw, sizeof ( cursor ) );
|
|
751
|
+ asn1_enter ( &cursor, ASN1_SEQUENCE );
|
|
752
|
+
|
|
753
|
+ /* Parse each extension in turn */
|
|
754
|
+ while ( cursor.len ) {
|
|
755
|
+ if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
|
|
756
|
+ return rc;
|
|
757
|
+ asn1_skip_any ( &cursor );
|
|
758
|
+ }
|
|
759
|
+
|
|
760
|
+ return 0;
|
|
761
|
+}
|
|
762
|
+
|
686
|
763
|
/** "id-ce-basicConstraints" object identifier */
|
687
|
764
|
static uint8_t oid_ce_basic_constraints[] = { ASN1_OID_BASICCONSTRAINTS };
|
688
|
765
|
|
689
|
766
|
/** "id-ce-keyUsage" object identifier */
|
690
|
767
|
static uint8_t oid_ce_key_usage[] = { ASN1_OID_KEYUSAGE };
|
691
|
768
|
|
|
769
|
+/** "id-ce-extKeyUsage" object identifier */
|
|
770
|
+static uint8_t oid_ce_ext_key_usage[] = { ASN1_OID_EXTKEYUSAGE };
|
|
771
|
+
|
692
|
772
|
/** Supported certificate extensions */
|
693
|
773
|
static struct x509_extension x509_extensions[] = {
|
694
|
774
|
{
|
|
@@ -701,6 +781,11 @@ static struct x509_extension x509_extensions[] = {
|
701
|
781
|
.oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
|
702
|
782
|
.parse = x509_parse_key_usage,
|
703
|
783
|
},
|
|
784
|
+ {
|
|
785
|
+ .name = "extKeyUsage",
|
|
786
|
+ .oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
|
|
787
|
+ .parse = x509_parse_extended_key_usage,
|
|
788
|
+ },
|
704
|
789
|
};
|
705
|
790
|
|
706
|
791
|
/**
|