return 0;
}
+/** "id-kp-codeSigning" object identifier */
+static uint8_t oid_code_signing[] = { ASN1_OID_CODESIGNING };
+
+/** Supported key purposes */
+static struct x509_key_purpose x509_key_purposes[] = {
+ {
+ .name = "codeSigning",
+ .bits = X509_CODE_SIGNING,
+ .oid = ASN1_OID_CURSOR ( oid_code_signing ),
+ },
+};
+
+/**
+ * Parse X.509 certificate key purpose identifier
+ *
+ * @v cert X.509 certificate
+ * @v raw ASN.1 cursor
+ * @ret rc Return status code
+ */
+static int x509_parse_key_purpose ( struct x509_certificate *cert,
+ const struct asn1_cursor *raw ) {
+ struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
+ struct x509_key_purpose *purpose;
+ struct asn1_cursor cursor;
+ unsigned int i;
+ int rc;
+
+ /* Enter keyPurposeId */
+ memcpy ( &cursor, raw, sizeof ( cursor ) );
+ if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
+ DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
+ DBGC_HDA ( cert, 0, raw->data, raw->len );
+ return rc;
+ }
+
+ /* Identify key purpose */
+ for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
+ sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
+ purpose = &x509_key_purposes[i];
+ if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
+ DBGC ( cert, "X509 %p has key purpose %s\n",
+ cert, purpose->name );
+ ext_usage->bits |= purpose->bits;
+ return 0;
+ }
+ }
+
+ /* Ignore unrecognised key purposes */
+ return 0;
+}
+
+/**
+ * Parse X.509 certificate extended key usage
+ *
+ * @v cert X.509 certificate
+ * @v raw ASN.1 cursor
+ * @ret rc Return status code
+ */
+static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
+ const struct asn1_cursor *raw ) {
+ struct asn1_cursor cursor;
+ int rc;
+
+ /* Enter extKeyUsage */
+ memcpy ( &cursor, raw, sizeof ( cursor ) );
+ asn1_enter ( &cursor, ASN1_SEQUENCE );
+
+ /* Parse each extension in turn */
+ while ( cursor.len ) {
+ if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
+ return rc;
+ asn1_skip_any ( &cursor );
+ }
+
+ return 0;
+}
+
/** "id-ce-basicConstraints" object identifier */
static uint8_t oid_ce_basic_constraints[] = { ASN1_OID_BASICCONSTRAINTS };
/** "id-ce-keyUsage" object identifier */
static uint8_t oid_ce_key_usage[] = { ASN1_OID_KEYUSAGE };
+/** "id-ce-extKeyUsage" object identifier */
+static uint8_t oid_ce_ext_key_usage[] = { ASN1_OID_EXTKEYUSAGE };
+
/** Supported certificate extensions */
static struct x509_extension x509_extensions[] = {
{
.oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
.parse = x509_parse_key_usage,
},
+ {
+ .name = "extKeyUsage",
+ .oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
+ .parse = x509_parse_extended_key_usage,
+ },
};
/**
ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 29 ), \
ASN1_OID_SINGLE ( 19 )
+/** ASN.1 OID for id-ce-extKeyUsage (2.5.29.37) */
+#define ASN1_OID_EXTKEYUSAGE \
+ ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 29 ), \
+ ASN1_OID_SINGLE ( 37 )
+
+/** ASN.1 OID for id-kp-codeSigning (1.3.6.1.5.5.7.3.3) */
+#define ASN1_OID_CODESIGNING \
+ ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 6 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 5 ), \
+ ASN1_OID_SINGLE ( 5 ), ASN1_OID_SINGLE ( 7 ), \
+ ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 3 )
+
/** Define an ASN.1 cursor containing an OID */
#define ASN1_OID_CURSOR( oid_value ) { \
.data = oid_value, \
X509_DECIPHER_ONLY = 0x8000,
};
+/** An X.509 certificate extended key usage */
+struct x509_extended_key_usage {
+ /** Usage bits */
+ unsigned int bits;
+};
+
+/** X.509 certificate extended key usage bits
+ *
+ * Extended key usages are identified by OID; these bits are purely an
+ * internal definition.
+ */
+enum x509_extended_key_usage_bits {
+ X509_CODE_SIGNING = 0x0001,
+};
+
/** An X.509 certificate extensions set */
struct x509_extensions {
/** Basic constraints */
struct x509_basic_constraints basic;
/** Key usage */
struct x509_key_usage usage;
+ /** Extended key usage */
+ struct x509_extended_key_usage ext_usage;
};
/** An X.509 certificate */
const struct asn1_cursor *raw );
};
+/** An X.509 key purpose */
+struct x509_key_purpose {
+ /** Name */
+ const char *name;
+ /** Object identifier */
+ struct asn1_cursor oid;
+ /** Extended key usage bits */
+ unsigned int bits;
+};
+
/** An X.509 root certificate store */
struct x509_root {
/** Fingerprint digest algorithm */