__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
* 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 */
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;
}
/**
__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 };
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 */
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 */
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
*
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 );
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 );
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 );
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 );