summaryrefslogtreecommitdiffstats
path: root/src/crypto/asn1.c
diff options
context:
space:
mode:
authorMichael Brown2012-03-21 14:57:32 +0100
committerMichael Brown2012-03-22 01:31:22 +0100
commit38b7e43f7d88a35b23b2d44a72d07d2ee589d31e (patch)
tree1e8a9472a0b433e1f0e25f694b49301f850c1c17 /src/crypto/asn1.c
parent[test] Add X.509 self-tests (diff)
downloadipxe-38b7e43f7d88a35b23b2d44a72d07d2ee589d31e.tar.gz
ipxe-38b7e43f7d88a35b23b2d44a72d07d2ee589d31e.tar.xz
ipxe-38b7e43f7d88a35b23b2d44a72d07d2ee589d31e.zip
[crypto] Generalise X.509 OID-identified algorithm to asn1.c
The concept of an OID-identified algorithm as defined in X.509 is used in some other standards (e.g. PKCS#7). Generalise this functionality and provide it as part of the ASN.1 core. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto/asn1.c')
-rw-r--r--src/crypto/asn1.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/crypto/asn1.c b/src/crypto/asn1.c
index f075b66dd..cd502502d 100644
--- a/src/crypto/asn1.c
+++ b/src/crypto/asn1.c
@@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stddef.h>
#include <string.h>
#include <errno.h>
+#include <ipxe/tables.h>
#include <ipxe/asn1.h>
/** @file
@@ -341,3 +342,56 @@ int asn1_compare ( const struct asn1_cursor *cursor1,
return ( difference ? difference :
memcmp ( cursor1->data, cursor2->data, cursor1->len ) );
}
+
+/**
+ * Identify ASN.1 algorithm by OID
+ *
+ * @v cursor ASN.1 object cursor
+
+ * @ret algorithm Algorithm, or NULL
+ */
+static struct asn1_algorithm *
+asn1_find_algorithm ( const struct asn1_cursor *cursor ) {
+ struct asn1_algorithm *algorithm;
+
+ for_each_table_entry ( algorithm, ASN1_ALGORITHMS ) {
+ if ( asn1_compare ( &algorithm->oid, cursor ) == 0 )
+ return algorithm;
+ }
+
+ return NULL;
+}
+
+/**
+ * Parse ASN.1 OID-identified algorithm
+ *
+ * @v cursor ASN.1 object cursor
+ * @ret algorithm Algorithm, or NULL
+ */
+struct asn1_algorithm * asn1_algorithm ( const struct asn1_cursor *cursor ) {
+ struct asn1_cursor contents;
+ struct asn1_algorithm *algorithm;
+ int rc;
+
+ /* Enter signatureAlgorithm */
+ memcpy ( &contents, cursor, sizeof ( contents ) );
+ asn1_enter ( &contents, ASN1_SEQUENCE );
+
+ /* Enter algorithm */
+ if ( ( rc = asn1_enter ( &contents, ASN1_OID ) ) != 0 ) {
+ DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
+ cursor );
+ DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
+ return NULL;
+ }
+
+ /* Identify 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 algorithm;
+}