]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Generalise asn1_{digest,pubkey,signature}_algorithm()
authorMichael Brown <mcb30@ipxe.org>
Sun, 13 May 2012 23:13:00 +0000 (00:13 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sun, 13 May 2012 23:20:28 +0000 (00:20 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/asn1.c
src/crypto/cms.c
src/crypto/x509.c
src/include/ipxe/asn1.h

index 55860558d10debac6752db07c29c12f3579a45f3..47c735c56273d20330ee088eb62cbbd683014a85 100644 (file)
@@ -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
@@ -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 */
@@ -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;
 }
 
 /**
index 18e59bfba9d0e9773d0064402c83293e2b40500d..2083433e582e43c0a440e037b8c50ad58893345c 100644 (file)
@@ -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 };
@@ -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 */
@@ -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 */
index 1cb46a1de9a59d27f25b4b3c2ef2bdbc4e0648cd..f25424a11cc26f0449923ffb6b4a7d4b49f938c7 100644 (file)
@@ -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
  *
@@ -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 );
@@ -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 );
@@ -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 );
index 38f0e5b015c7e04af3c6a19cfeb95233dd7d3bde..cd0d5342370bf9f28bd4b003d929bd0da4d95a4e 100644 (file)
@@ -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 );