|
@@ -487,7 +487,7 @@ static int x509_parse_validity ( struct x509_certificate *cert,
|
487
|
487
|
* @ret rc Return status code
|
488
|
488
|
*/
|
489
|
489
|
static int x509_parse_common_name ( struct x509_certificate *cert,
|
490
|
|
- struct x509_name *name,
|
|
490
|
+ struct x509_string *name,
|
491
|
491
|
const struct asn1_cursor *raw ) {
|
492
|
492
|
struct asn1_cursor cursor;
|
493
|
493
|
struct asn1_cursor oid_cursor;
|
|
@@ -533,7 +533,7 @@ static int x509_parse_common_name ( struct x509_certificate *cert,
|
533
|
533
|
static int x509_parse_subject ( struct x509_certificate *cert,
|
534
|
534
|
const struct asn1_cursor *raw ) {
|
535
|
535
|
struct x509_subject *subject = &cert->subject;
|
536
|
|
- struct x509_name *name = &subject->name;
|
|
536
|
+ struct x509_string *name = &subject->name;
|
537
|
537
|
int rc;
|
538
|
538
|
|
539
|
539
|
/* Record raw subject */
|
|
@@ -750,7 +750,7 @@ static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
|
750
|
750
|
memcpy ( &cursor, raw, sizeof ( cursor ) );
|
751
|
751
|
asn1_enter ( &cursor, ASN1_SEQUENCE );
|
752
|
752
|
|
753
|
|
- /* Parse each extension in turn */
|
|
753
|
+ /* Parse each extended key usage in turn */
|
754
|
754
|
while ( cursor.len ) {
|
755
|
755
|
if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
|
756
|
756
|
return rc;
|
|
@@ -760,14 +760,145 @@ static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
|
760
|
760
|
return 0;
|
761
|
761
|
}
|
762
|
762
|
|
|
763
|
+/**
|
|
764
|
+ * Parse X.509 certificate OCSP access method
|
|
765
|
+ *
|
|
766
|
+ * @v cert X.509 certificate
|
|
767
|
+ * @v raw ASN.1 cursor
|
|
768
|
+ * @ret rc Return status code
|
|
769
|
+ */
|
|
770
|
+static int x509_parse_ocsp ( struct x509_certificate *cert,
|
|
771
|
+ const struct asn1_cursor *raw ) {
|
|
772
|
+ struct x509_ocsp_responder *ocsp = &cert->extensions.auth_info.ocsp;
|
|
773
|
+ struct asn1_cursor cursor;
|
|
774
|
+ int rc;
|
|
775
|
+
|
|
776
|
+ /* Enter accessLocation */
|
|
777
|
+ memcpy ( &cursor, raw, sizeof ( cursor ) );
|
|
778
|
+ if ( ( rc = asn1_enter ( &cursor, ASN1_IMPLICIT_TAG ( 6 ) ) ) != 0 ) {
|
|
779
|
+ DBGC ( cert, "X509 %p OCSP does not contain "
|
|
780
|
+ "uniformResourceIdentifier:\n", cert );
|
|
781
|
+ DBGC_HDA ( cert, 0, raw->data, raw->len );
|
|
782
|
+ return rc;
|
|
783
|
+ }
|
|
784
|
+
|
|
785
|
+ /* Record URI */
|
|
786
|
+ ocsp->uri.data = cursor.data;
|
|
787
|
+ ocsp->uri.len = cursor.len;
|
|
788
|
+ DBGC ( cert, "X509 %p OCSP URI is:\n", cert );
|
|
789
|
+ DBGC_HDA ( cert, 0, ocsp->uri.data, ocsp->uri.len );
|
|
790
|
+
|
|
791
|
+ return 0;
|
|
792
|
+}
|
|
793
|
+
|
|
794
|
+/** "id-ad-ocsp" object identifier */
|
|
795
|
+static uint8_t oid_ad_ocsp[] = { ASN1_OID_OCSP };
|
|
796
|
+
|
|
797
|
+/** Supported access methods */
|
|
798
|
+static struct x509_access_method x509_access_methods[] = {
|
|
799
|
+ {
|
|
800
|
+ .name = "OCSP",
|
|
801
|
+ .oid = ASN1_OID_CURSOR ( oid_ad_ocsp ),
|
|
802
|
+ .parse = x509_parse_ocsp,
|
|
803
|
+ },
|
|
804
|
+};
|
|
805
|
+
|
|
806
|
+/**
|
|
807
|
+ * Identify X.509 access method by OID
|
|
808
|
+ *
|
|
809
|
+ * @v oid OID
|
|
810
|
+ * @ret method Access method, or NULL
|
|
811
|
+ */
|
|
812
|
+static struct x509_access_method *
|
|
813
|
+x509_find_access_method ( const struct asn1_cursor *oid ) {
|
|
814
|
+ struct x509_access_method *method;
|
|
815
|
+ unsigned int i;
|
|
816
|
+
|
|
817
|
+ for ( i = 0 ; i < ( sizeof ( x509_access_methods ) /
|
|
818
|
+ sizeof ( x509_access_methods[0] ) ) ; i++ ) {
|
|
819
|
+ method = &x509_access_methods[i];
|
|
820
|
+ if ( asn1_compare ( &method->oid, oid ) == 0 )
|
|
821
|
+ return method;
|
|
822
|
+ }
|
|
823
|
+
|
|
824
|
+ return NULL;
|
|
825
|
+}
|
|
826
|
+
|
|
827
|
+/**
|
|
828
|
+ * Parse X.509 certificate access description
|
|
829
|
+ *
|
|
830
|
+ * @v cert X.509 certificate
|
|
831
|
+ * @v raw ASN.1 cursor
|
|
832
|
+ * @ret rc Return status code
|
|
833
|
+ */
|
|
834
|
+static int x509_parse_access_description ( struct x509_certificate *cert,
|
|
835
|
+ const struct asn1_cursor *raw ) {
|
|
836
|
+ struct asn1_cursor cursor;
|
|
837
|
+ struct asn1_cursor subcursor;
|
|
838
|
+ struct x509_access_method *method;
|
|
839
|
+ int rc;
|
|
840
|
+
|
|
841
|
+ /* Enter keyPurposeId */
|
|
842
|
+ memcpy ( &cursor, raw, sizeof ( cursor ) );
|
|
843
|
+ asn1_enter ( &cursor, ASN1_SEQUENCE );
|
|
844
|
+
|
|
845
|
+ /* Try to identify access method */
|
|
846
|
+ memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
|
|
847
|
+ asn1_enter ( &subcursor, ASN1_OID );
|
|
848
|
+ method = x509_find_access_method ( &subcursor );
|
|
849
|
+ asn1_skip_any ( &cursor );
|
|
850
|
+ DBGC ( cert, "X509 %p found access method %s\n",
|
|
851
|
+ cert, ( method ? method->name : "<unknown>" ) );
|
|
852
|
+
|
|
853
|
+ /* Parse access location, if applicable */
|
|
854
|
+ if ( method && ( ( rc = method->parse ( cert, &cursor ) ) != 0 ) )
|
|
855
|
+ return rc;
|
|
856
|
+
|
|
857
|
+ return 0;
|
|
858
|
+}
|
|
859
|
+
|
|
860
|
+/**
|
|
861
|
+ * Parse X.509 certificate authority information access
|
|
862
|
+ *
|
|
863
|
+ * @v cert X.509 certificate
|
|
864
|
+ * @v raw ASN.1 cursor
|
|
865
|
+ * @ret rc Return status code
|
|
866
|
+ */
|
|
867
|
+static int x509_parse_authority_info_access ( struct x509_certificate *cert,
|
|
868
|
+ const struct asn1_cursor *raw ) {
|
|
869
|
+ struct asn1_cursor cursor;
|
|
870
|
+ int rc;
|
|
871
|
+
|
|
872
|
+ /* Enter authorityInfoAccess */
|
|
873
|
+ memcpy ( &cursor, raw, sizeof ( cursor ) );
|
|
874
|
+ asn1_enter ( &cursor, ASN1_SEQUENCE );
|
|
875
|
+
|
|
876
|
+ /* Parse each access description in turn */
|
|
877
|
+ while ( cursor.len ) {
|
|
878
|
+ if ( ( rc = x509_parse_access_description ( cert,
|
|
879
|
+ &cursor ) ) != 0 )
|
|
880
|
+ return rc;
|
|
881
|
+ asn1_skip_any ( &cursor );
|
|
882
|
+ }
|
|
883
|
+
|
|
884
|
+ return 0;
|
|
885
|
+}
|
|
886
|
+
|
763
|
887
|
/** "id-ce-basicConstraints" object identifier */
|
764
|
|
-static uint8_t oid_ce_basic_constraints[] = { ASN1_OID_BASICCONSTRAINTS };
|
|
888
|
+static uint8_t oid_ce_basic_constraints[] =
|
|
889
|
+ { ASN1_OID_BASICCONSTRAINTS };
|
765
|
890
|
|
766
|
891
|
/** "id-ce-keyUsage" object identifier */
|
767
|
|
-static uint8_t oid_ce_key_usage[] = { ASN1_OID_KEYUSAGE };
|
|
892
|
+static uint8_t oid_ce_key_usage[] =
|
|
893
|
+ { ASN1_OID_KEYUSAGE };
|
768
|
894
|
|
769
|
895
|
/** "id-ce-extKeyUsage" object identifier */
|
770
|
|
-static uint8_t oid_ce_ext_key_usage[] = { ASN1_OID_EXTKEYUSAGE };
|
|
896
|
+static uint8_t oid_ce_ext_key_usage[] =
|
|
897
|
+ { ASN1_OID_EXTKEYUSAGE };
|
|
898
|
+
|
|
899
|
+/** "id-pe-authorityInfoAccess" object identifier */
|
|
900
|
+static uint8_t oid_pe_authority_info_access[] =
|
|
901
|
+ { ASN1_OID_AUTHORITYINFOACCESS };
|
771
|
902
|
|
772
|
903
|
/** Supported certificate extensions */
|
773
|
904
|
static struct x509_extension x509_extensions[] = {
|
|
@@ -786,6 +917,11 @@ static struct x509_extension x509_extensions[] = {
|
786
|
917
|
.oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
|
787
|
918
|
.parse = x509_parse_extended_key_usage,
|
788
|
919
|
},
|
|
920
|
+ {
|
|
921
|
+ .name = "authorityInfoAccess",
|
|
922
|
+ .oid = ASN1_OID_CURSOR ( oid_pe_authority_info_access ),
|
|
923
|
+ .parse = x509_parse_authority_info_access,
|
|
924
|
+ },
|
789
|
925
|
};
|
790
|
926
|
|
791
|
927
|
/**
|