Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[crypto] Generalise asn1_{digest,pubkey,signature}_algorithm()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed May 13, 2012
1 parent 88c09b3 commit 7deb610
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 108 deletions.
115 changes: 107 additions & 8 deletions src/crypto/asn1.c
Expand Up @@ -58,6 +58,18 @@ FILE_LICENCE ( GPL2_OR_LATER );
__einfo_error ( EINFO_EINVAL_ASN1_TIME )
#define EINFO_EINVAL_ASN1_TIME \
__einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" )
#define EINVAL_ASN1_ALGORITHM \
__einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )
#define EINFO_EINVAL_ASN1_ALGORITHM \
__einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )
#define ENOTSUP_ALGORITHM \
__einfo_error ( EINFO_ENOTSUP_ALGORITHM )
#define EINFO_ENOTSUP_ALGORITHM \
__einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
#define ENOTTY_ALGORITHM \
__einfo_error ( EINFO_ENOTTY_ALGORITHM )
#define EINFO_ENOTTY_ALGORITHM \
__einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )

/**
* Invalidate ASN.1 object cursor
Expand Down Expand Up @@ -377,11 +389,12 @@ asn1_find_algorithm ( const struct asn1_cursor *cursor ) {
* Parse ASN.1 OID-identified algorithm
*
* @v cursor ASN.1 object cursor
* @ret algorithm Algorithm, or NULL
* @ret algorithm Algorithm
* @ret rc Return status code
*/
struct asn1_algorithm * asn1_algorithm ( const struct asn1_cursor *cursor ) {
int asn1_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm ) {
struct asn1_cursor contents;
struct asn1_algorithm *algorithm;
int rc;

/* Enter signatureAlgorithm */
Expand All @@ -393,18 +406,104 @@ struct asn1_algorithm * asn1_algorithm ( const struct asn1_cursor *cursor ) {
DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
cursor );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return NULL;
return -EINVAL_ASN1_ALGORITHM;
}

/* Identify algorithm */
algorithm = asn1_find_algorithm ( &contents );
if ( ! algorithm ) {
*algorithm = asn1_find_algorithm ( &contents );
if ( ! *algorithm ) {
DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return NULL;
return -ENOTSUP_ALGORITHM;
}

return 0;
}

/**
* Parse ASN.1 OID-identified public-key algorithm
*
* @v cursor ASN.1 object cursor
* @ret algorithm Algorithm
* @ret rc Return status code
*/
int asn1_pubkey_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm ) {
int rc;

/* Parse algorithm */
if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
return rc;

/* Check algorithm has a public key */
if ( ! (*algorithm)->pubkey ) {
DBGC ( cursor, "ASN1 %p algorithm %s is not a public-key "
"algorithm:\n", cursor, (*algorithm)->name );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return -ENOTTY_ALGORITHM;
}

return 0;
}

/**
* Parse ASN.1 OID-identified digest algorithm
*
* @v cursor ASN.1 object cursor
* @ret algorithm Algorithm
* @ret rc Return status code
*/
int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm ) {
int rc;

/* Parse algorithm */
if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
return rc;

/* Check algorithm has a digest */
if ( ! (*algorithm)->digest ) {
DBGC ( cursor, "ASN1 %p algorithm %s is not a digest "
"algorithm:\n", cursor, (*algorithm)->name );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return -ENOTTY_ALGORITHM;
}

return 0;
}

/**
* Parse ASN.1 OID-identified signature algorithm
*
* @v cursor ASN.1 object cursor
* @ret algorithm Algorithm
* @ret rc Return status code
*/
int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm ) {
int rc;

/* Parse algorithm */
if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
return rc;

/* Check algorithm has a public key */
if ( ! (*algorithm)->pubkey ) {
DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
"algorithm:\n", cursor, (*algorithm)->name );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return -ENOTTY_ALGORITHM;
}

/* Check algorithm has a digest */
if ( ! (*algorithm)->digest ) {
DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
"algorithm:\n", cursor, (*algorithm)->name );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return -ENOTTY_ALGORITHM;
}

return algorithm;
return 0;
}

/**
Expand Down
41 changes: 9 additions & 32 deletions src/crypto/cms.c
Expand Up @@ -65,15 +65,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
__einfo_error ( EINFO_ENOTSUP_SIGNEDDATA )
#define EINFO_ENOTSUP_SIGNEDDATA \
__einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Not a digital signature" )
#define ENOTSUP_DIGEST \
__einfo_error ( EINFO_ENOTSUP_DIGEST )
#define EINFO_ENOTSUP_DIGEST \
__einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported digest algorithm" )
#define ENOTSUP_PUBKEY \
__einfo_error ( EINFO_ENOTSUP_PUBKEY )
#define EINFO_ENOTSUP_PUBKEY \
__einfo_uniqify ( EINFO_ENOTSUP, 0x03, \
"Unsupported public-key algorithm" )

/** "pkcs7-signedData" object identifier */
static uint8_t oid_signeddata[] = { ASN1_OID_SIGNEDDATA };
Expand Down Expand Up @@ -257,21 +248,14 @@ static int cms_parse_digest_algorithm ( struct cms_signature *sig,
struct cms_signer_info *info,
const struct asn1_cursor *raw ) {
struct asn1_algorithm *algorithm;
int rc;

/* Identify algorithm */
algorithm = asn1_algorithm ( raw );
if ( ! algorithm ) {
DBGC ( sig, "CMS %p/%p could not identify digest algorithm:\n",
sig, info );
if ( ( rc = asn1_digest_algorithm ( raw, &algorithm ) ) != 0 ) {
DBGC ( sig, "CMS %p/%p could not identify digest algorithm: "
"%s\n", sig, info, strerror ( rc ) );
DBGC_HDA ( sig, 0, raw->data, raw->len );
return -ENOTSUP_DIGEST;
}

/* Check algorithm is a digest algorithm */
if ( ! algorithm->digest ) {
DBGC ( sig, "CMS %p/%p algorithm %s is not a digest "
"algorithm\n", sig, info, algorithm->name );
return -EINVAL_DIGEST;
return rc;
}

/* Record digest algorithm */
Expand All @@ -294,21 +278,14 @@ static int cms_parse_signature_algorithm ( struct cms_signature *sig,
struct cms_signer_info *info,
const struct asn1_cursor *raw ) {
struct asn1_algorithm *algorithm;
int rc;

/* Identify algorithm */
algorithm = asn1_algorithm ( raw );
if ( ! algorithm ) {
if ( ( rc = asn1_pubkey_algorithm ( raw, &algorithm ) ) != 0 ) {
DBGC ( sig, "CMS %p/%p could not identify public-key "
"algorithm:\n", sig, info );
"algorithm: %s\n", sig, info, strerror ( rc ) );
DBGC_HDA ( sig, 0, raw->data, raw->len );
return -ENOTSUP_PUBKEY;
}

/* Check algorithm is a signature algorithm */
if ( ! algorithm->pubkey ) {
DBGC ( sig, "CMS %p/%p algorithm %s is not a public-key "
"algorithm\n", sig, info, algorithm->name );
return -EINVAL_PUBKEY;
return rc;
}

/* Record signature algorithm */
Expand Down
79 changes: 13 additions & 66 deletions src/crypto/x509.c
Expand Up @@ -154,66 +154,6 @@ static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
static struct asn1_cursor oid_common_name_cursor =
ASN1_OID_CURSOR ( oid_common_name );

/**
* Parse X.509 certificate algorithm
*
* @v cert X.509 certificate
* @v algorithm Algorithm to fill in
* @v raw ASN.1 cursor
* @ret rc Return status code
*/
static int x509_parse_pubkey_algorithm ( struct x509_certificate *cert,
struct asn1_algorithm **algorithm,
const struct asn1_cursor *raw ) {

/* Parse algorithm */
*algorithm = asn1_algorithm ( raw );
if ( ! (*algorithm) ) {
DBGC ( cert, "X509 %p unrecognised algorithm:\n", cert );
DBGC_HDA ( cert, 0, raw->data, raw->len );
return -ENOTSUP_ALGORITHM;
}

/* Check algorithm has a public key */
if ( ! (*algorithm)->pubkey ) {
DBGC ( cert, "X509 %p algorithm %s is not a public-key "
"algorithm:\n", cert, (*algorithm)->name );
DBGC_HDA ( cert, 0, raw->data, raw->len );
return -EINVAL_ALGORITHM;
}

return 0;
}

/**
* Parse X.509 certificate signature algorithm
*
* @v cert X.509 certificate
* @v algorithm Algorithm to fill in
* @v raw ASN.1 cursor
* @ret rc Return status code
*/
static int x509_parse_signature_algorithm ( struct x509_certificate *cert,
struct asn1_algorithm **algorithm,
const struct asn1_cursor *raw ) {
int rc;

/* Parse algorithm */
if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
raw ) ) != 0 )
return rc;

/* Check algorithm is a signature algorithm */
if ( ! (*algorithm)->digest ) {
DBGC ( cert, "X509 %p algorithm %s is not a signature "
"algorithm:\n", cert, (*algorithm)->name );
DBGC_HDA ( cert, 0, raw->data, raw->len );
return -EINVAL_ALGORITHM;
}

return 0;
}

/**
* Parse X.509 certificate bit string
*
Expand Down Expand Up @@ -541,9 +481,11 @@ static int x509_parse_public_key ( struct x509_certificate *cert,
asn1_enter ( &cursor, ASN1_SEQUENCE );

/* Parse algorithm */
if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
&cursor ) ) != 0 )
if ( ( rc = asn1_pubkey_algorithm ( &cursor, algorithm ) ) != 0 ) {
DBGC ( cert, "X509 %p could not parse public key algorithm: "
"%s\n", cert, strerror ( rc ) );
return rc;
}
DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
cert, (*algorithm)->name );
asn1_skip_any ( &cursor );
Expand Down Expand Up @@ -1045,9 +987,11 @@ static int x509_parse_tbscertificate ( struct x509_certificate *cert,
asn1_skip_any ( &cursor );

/* Parse signature */
if ( ( rc = x509_parse_signature_algorithm ( cert, algorithm,
&cursor ) ) != 0 )
if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
DBGC ( cert, "X509 %p could not parse signature algorithm: "
"%s\n", cert, strerror ( rc ) );
return rc;
}
DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
cert, (*algorithm)->name );
asn1_skip_any ( &cursor );
Expand Down Expand Up @@ -1107,9 +1051,12 @@ static int x509_parse ( struct x509_certificate *cert,
asn1_skip_any ( &cursor );

/* Parse signatureAlgorithm */
if ( ( rc = x509_parse_signature_algorithm ( cert, signature_algorithm,
&cursor ) ) != 0 )
if ( ( rc = asn1_signature_algorithm ( &cursor,
signature_algorithm ) ) != 0 ) {
DBGC ( cert, "X509 %p could not parse signature algorithm: "
"%s\n", cert, strerror ( rc ) );
return rc;
}
DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
cert, (*signature_algorithm)->name );
asn1_skip_any ( &cursor );
Expand Down
10 changes: 8 additions & 2 deletions src/include/ipxe/asn1.h
Expand Up @@ -238,8 +238,14 @@ extern int asn1_boolean ( const struct asn1_cursor *cursor );
extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
extern int asn1_compare ( const struct asn1_cursor *cursor1,
const struct asn1_cursor *cursor2 );
extern struct asn1_algorithm *
asn1_algorithm ( const struct asn1_cursor *cursor );
extern int asn1_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_pubkey_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_generalized_time ( const struct asn1_cursor *cursor,
time_t *time );

Expand Down

0 comments on commit 7deb610

Please sign in to comment.