瀏覽代碼

[crypto] Parse X.509 extended key usage extension

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 年之前
父節點
當前提交
fe6e741c62
共有 3 個檔案被更改,包括 124 行新增0 行删除
  1. 85
    0
      src/crypto/x509.c
  2. 12
    0
      src/include/ipxe/asn1.h
  3. 27
    0
      src/include/ipxe/x509.h

+ 85
- 0
src/crypto/x509.c 查看文件

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

+ 12
- 0
src/include/ipxe/asn1.h 查看文件

@@ -140,6 +140,18 @@ struct asn1_cursor {
140 140
 	ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 29 ),	\
141 141
 	ASN1_OID_SINGLE ( 19 )
142 142
 
143
+/** ASN.1 OID for id-ce-extKeyUsage (2.5.29.37) */
144
+#define ASN1_OID_EXTKEYUSAGE					\
145
+	ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 29 ),	\
146
+	ASN1_OID_SINGLE ( 37 )
147
+
148
+/** ASN.1 OID for id-kp-codeSigning (1.3.6.1.5.5.7.3.3) */
149
+#define ASN1_OID_CODESIGNING					\
150
+	ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 6 ),	\
151
+	ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 5 ),		\
152
+	ASN1_OID_SINGLE ( 5 ), ASN1_OID_SINGLE ( 7 ),		\
153
+	ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 3 )
154
+
143 155
 /** Define an ASN.1 cursor containing an OID */
144 156
 #define ASN1_OID_CURSOR( oid_value ) {				\
145 157
 		.data = oid_value,				\

+ 27
- 0
src/include/ipxe/x509.h 查看文件

@@ -113,12 +113,29 @@ enum x509_key_usage_bits {
113 113
 	X509_DECIPHER_ONLY = 0x8000,
114 114
 };
115 115
 
116
+/** An X.509 certificate extended key usage */
117
+struct x509_extended_key_usage {
118
+	/** Usage bits */
119
+	unsigned int bits;
120
+};
121
+
122
+/** X.509 certificate extended key usage bits
123
+ *
124
+ * Extended key usages are identified by OID; these bits are purely an
125
+ * internal definition.
126
+ */
127
+enum x509_extended_key_usage_bits {
128
+	X509_CODE_SIGNING = 0x0001,
129
+};
130
+
116 131
 /** An X.509 certificate extensions set */
117 132
 struct x509_extensions {
118 133
 	/** Basic constraints */
119 134
 	struct x509_basic_constraints basic;
120 135
 	/** Key usage */
121 136
 	struct x509_key_usage usage;
137
+	/** Extended key usage */
138
+	struct x509_extended_key_usage ext_usage;
122 139
 };
123 140
 
124 141
 /** An X.509 certificate */
@@ -161,6 +178,16 @@ struct x509_extension {
161 178
 			  const struct asn1_cursor *raw );
162 179
 };
163 180
 
181
+/** An X.509 key purpose */
182
+struct x509_key_purpose {
183
+	/** Name */
184
+	const char *name;
185
+	/** Object identifier */
186
+	struct asn1_cursor oid;
187
+	/** Extended key usage bits */
188
+	unsigned int bits;
189
+};
190
+
164 191
 /** An X.509 root certificate store */
165 192
 struct x509_root {
166 193
 	/** Fingerprint digest algorithm */

Loading…
取消
儲存