mirror of https://github.com/ipxe/ipxe.git
[crypto] Parse X.509 extended key usage extension
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/6/head
parent
f2af64aba5
commit
fe6e741c62
|
@ -683,12 +683,92 @@ static int x509_parse_key_usage ( struct x509_certificate *cert,
|
||||||
return 0;
|
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 */
|
/** "id-ce-basicConstraints" object identifier */
|
||||||
static uint8_t oid_ce_basic_constraints[] = { ASN1_OID_BASICCONSTRAINTS };
|
static uint8_t oid_ce_basic_constraints[] = { ASN1_OID_BASICCONSTRAINTS };
|
||||||
|
|
||||||
/** "id-ce-keyUsage" object identifier */
|
/** "id-ce-keyUsage" object identifier */
|
||||||
static uint8_t oid_ce_key_usage[] = { ASN1_OID_KEYUSAGE };
|
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 */
|
/** Supported certificate extensions */
|
||||||
static struct x509_extension x509_extensions[] = {
|
static struct x509_extension x509_extensions[] = {
|
||||||
{
|
{
|
||||||
|
@ -701,6 +781,11 @@ static struct x509_extension x509_extensions[] = {
|
||||||
.oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
|
.oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
|
||||||
.parse = x509_parse_key_usage,
|
.parse = x509_parse_key_usage,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "extKeyUsage",
|
||||||
|
.oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
|
||||||
|
.parse = x509_parse_extended_key_usage,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -140,6 +140,18 @@ struct asn1_cursor {
|
||||||
ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 29 ), \
|
ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 29 ), \
|
||||||
ASN1_OID_SINGLE ( 19 )
|
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 an ASN.1 cursor containing an OID */
|
||||||
#define ASN1_OID_CURSOR( oid_value ) { \
|
#define ASN1_OID_CURSOR( oid_value ) { \
|
||||||
.data = oid_value, \
|
.data = oid_value, \
|
||||||
|
|
|
@ -113,12 +113,29 @@ enum x509_key_usage_bits {
|
||||||
X509_DECIPHER_ONLY = 0x8000,
|
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 */
|
/** An X.509 certificate extensions set */
|
||||||
struct x509_extensions {
|
struct x509_extensions {
|
||||||
/** Basic constraints */
|
/** Basic constraints */
|
||||||
struct x509_basic_constraints basic;
|
struct x509_basic_constraints basic;
|
||||||
/** Key usage */
|
/** Key usage */
|
||||||
struct x509_key_usage usage;
|
struct x509_key_usage usage;
|
||||||
|
/** Extended key usage */
|
||||||
|
struct x509_extended_key_usage ext_usage;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An X.509 certificate */
|
/** An X.509 certificate */
|
||||||
|
@ -161,6 +178,16 @@ struct x509_extension {
|
||||||
const struct asn1_cursor *raw );
|
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 */
|
/** An X.509 root certificate store */
|
||||||
struct x509_root {
|
struct x509_root {
|
||||||
/** Fingerprint digest algorithm */
|
/** Fingerprint digest algorithm */
|
||||||
|
|
Loading…
Reference in New Issue