Procházet zdrojové kódy

[crypto] Parse OCSP responder URI from X.509 certificate

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown před 12 roky
rodič
revize
601cb3610f
4 změnil soubory, kde provedl 194 přidání a 11 odebrání
  1. 142
    6
      src/crypto/x509.c
  2. 17
    0
      src/include/ipxe/asn1.h
  3. 34
    4
      src/include/ipxe/x509.h
  4. 1
    1
      src/net/tls.c

+ 142
- 6
src/crypto/x509.c Zobrazit soubor

@@ -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
 /**

+ 17
- 0
src/include/ipxe/asn1.h Zobrazit soubor

@@ -53,6 +53,9 @@ struct asn1_cursor {
53 53
 /** ASN.1 set */
54 54
 #define ASN1_SET 0x31
55 55
 
56
+/** ASN.1 implicit tag */
57
+#define ASN1_IMPLICIT_TAG( number) ( 0x80 | (number) )
58
+
56 59
 /** ASN.1 explicit tag */
57 60
 #define ASN1_EXPLICIT_TAG( number) ( 0xa0 | (number) )
58 61
 
@@ -158,6 +161,20 @@ struct asn1_cursor {
158 161
 	ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ),	\
159 162
 	ASN1_OID_SINGLE ( 7 ), ASN1_OID_SINGLE ( 2 )
160 163
 
164
+/** ASN.1 OID for id-pe-authorityInfoAccess (1.3.6.1.5.5.7.1.1) */
165
+#define ASN1_OID_AUTHORITYINFOACCESS				\
166
+	ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 6 ),	\
167
+	ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 5 ),		\
168
+	ASN1_OID_SINGLE ( 5 ), ASN1_OID_SINGLE ( 7 ),		\
169
+	ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 1 )
170
+
171
+/** ASN.1 OID for id-ad-ocsp (1.3.6.1.5.5.7.48.1) */
172
+#define ASN1_OID_OCSP						\
173
+	ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 6 ),	\
174
+	ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 5 ),		\
175
+	ASN1_OID_SINGLE ( 5 ), ASN1_OID_SINGLE ( 7 ),		\
176
+	ASN1_OID_SINGLE ( 48 ), ASN1_OID_SINGLE ( 1 )
177
+
161 178
 /** Define an ASN.1 cursor containing an OID */
162 179
 #define ASN1_OID_CURSOR( oid_value ) {				\
163 180
 		.data = oid_value,				\

+ 34
- 4
src/include/ipxe/x509.h Zobrazit soubor

@@ -50,9 +50,9 @@ struct x509_validity {
50 50
 	struct x509_time not_after;
51 51
 };
52 52
 
53
-/** An X.509 name */
54
-struct x509_name {
55
-	/** Name (not NUL-terminated) */
53
+/** An X.509 string */
54
+struct x509_string {
55
+	/** String (not NUL-terminated) */
56 56
 	const void *data;
57 57
 	/** Length of name */
58 58
 	size_t len;
@@ -71,7 +71,7 @@ struct x509_subject {
71 71
 	/** Raw subject */
72 72
 	struct asn1_cursor raw;
73 73
 	/** Common name */
74
-	struct x509_name name;
74
+	struct x509_string name;
75 75
 	/** Public key information */
76 76
 	struct x509_public_key public_key;
77 77
 };
@@ -128,6 +128,18 @@ enum x509_extended_key_usage_bits {
128 128
 	X509_CODE_SIGNING = 0x0001,
129 129
 };
130 130
 
131
+/** X.509 certificate OCSP responder */
132
+struct x509_ocsp_responder {
133
+	/** URI */
134
+	struct x509_string uri;
135
+};
136
+
137
+/** X.509 certificate authority information access */
138
+struct x509_authority_info_access {
139
+	/** OCSP responder */
140
+	struct x509_ocsp_responder ocsp;
141
+};
142
+
131 143
 /** An X.509 certificate extensions set */
132 144
 struct x509_extensions {
133 145
 	/** Basic constraints */
@@ -136,6 +148,8 @@ struct x509_extensions {
136 148
 	struct x509_key_usage usage;
137 149
 	/** Extended key usage */
138 150
 	struct x509_extended_key_usage ext_usage;
151
+	/** Authority information access */
152
+	struct x509_authority_info_access auth_info;
139 153
 };
140 154
 
141 155
 /** An X.509 certificate */
@@ -188,6 +202,22 @@ struct x509_key_purpose {
188 202
 	unsigned int bits;
189 203
 };
190 204
 
205
+/** An X.509 access method */
206
+struct x509_access_method {
207
+	/** Name */
208
+	const char *name;
209
+	/** Object identifier */
210
+	struct asn1_cursor oid;
211
+	/** Parse access method
212
+	 *
213
+	 * @v cert		X.509 certificate
214
+	 * @v raw		ASN.1 cursor
215
+	 * @ret rc		Return status code
216
+	 */
217
+	int ( * parse ) ( struct x509_certificate *cert,
218
+			  const struct asn1_cursor *raw );
219
+};
220
+
191 221
 /** An X.509 root certificate store */
192 222
 struct x509_root {
193 223
 	/** Fingerprint digest algorithm */

+ 1
- 1
src/net/tls.c Zobrazit soubor

@@ -1347,7 +1347,7 @@ static int tls_new_certificate ( struct tls_session *tls,
1347 1347
 	struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1348 1348
 	struct tls_certificate_context context;
1349 1349
 	struct x509_certificate cert;
1350
-	struct x509_name *name = &cert.subject.name;
1350
+	struct x509_string *name = &cert.subject.name;
1351 1351
 	struct x509_public_key *key = &cert.subject.public_key;
1352 1352
 	time_t now;
1353 1353
 	int rc;

Načítá se…
Zrušit
Uložit