curve25519: Support loading Ed25519 public keys from simple blobs
authorTobias Brunner <tobias@strongswan.org>
Mon, 22 Oct 2018 12:33:36 +0000 (14:33 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 26 Oct 2018 09:01:10 +0000 (11:01 +0200)
src/libstrongswan/credentials/builder.c
src/libstrongswan/credentials/builder.h
src/libstrongswan/plugins/curve25519/curve25519_public_key.c

index 0239ee1..61dfbbc 100644 (file)
@@ -73,6 +73,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
        "BUILD_SAFE_PRIMES",
        "BUILD_SHARES",
        "BUILD_THRESHOLD",
+       "BUILD_EDDSA_PUB",
        "BUILD_EDDSA_PRIV_ASN1_DER",
        "BUILD_END",
 );
index 7928ef4..b283bd1 100644 (file)
@@ -156,6 +156,8 @@ enum builder_part_t {
        BUILD_SHARES,
        /** minimum number of participating private key shares */
        BUILD_THRESHOLD,
+       /** EdDSA public key blob */
+       BUILD_EDDSA_PUB,
        /** DER encoded ASN.1 EdDSA private key */
        BUILD_EDDSA_PRIV_ASN1_DER,
        /** end of variable argument builder list */
index 1d4dec5..6eb80a1 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2018 Tobias Brunner
  * Copyright (C) 2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -200,22 +201,68 @@ static const asn1Object_t pubkeyObjects[] = {
 #define ED25519_SUBJECT_PUBLIC_KEY                             2
 
 /**
+ * Parse the ASN.1-encoded subjectPublicKeyInfo
+ */
+static bool parse_public_key_info(private_curve25519_public_key_t *this,
+                                                                 chunk_t blob)
+{
+       asn1_parser_t *parser;
+       chunk_t object;
+       bool success = FALSE;
+       int objectID, oid;
+
+       parser = asn1_parser_create(pubkeyObjects, blob);
+
+       while (parser->iterate(parser, &objectID, &object))
+       {
+               switch (objectID)
+               {
+                       case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM:
+                       {
+                               oid = asn1_parse_algorithmIdentifier(object,
+                                                                               parser->get_level(parser) + 1, NULL);
+                               if (oid != OID_ED25519)
+                               {
+                                       goto end;
+                               }
+                               break;
+                       }
+                       case ED25519_SUBJECT_PUBLIC_KEY:
+                       {
+                               /* encoded as an ASN1 BIT STRING */
+                               if (object.len != 1 + ED25519_KEY_LEN)
+                               {
+                                       goto end;
+                               }
+                               this->pubkey = chunk_clone(chunk_skip(object, 1));
+                               break;
+                       }
+               }
+       }
+       success = parser->success(parser);
+
+end:
+       parser->destroy(parser);
+       return success;
+}
+
+/**
  * See header.
  */
 curve25519_public_key_t *curve25519_public_key_load(key_type_t type,
                                                                                                        va_list args)
 {
        private_curve25519_public_key_t *this;
-       chunk_t blob = chunk_empty, object;
-       asn1_parser_t *parser;
-       bool success = FALSE;
-       int objectID, oid;
+       chunk_t asn1 = chunk_empty, blob = chunk_empty;
 
        while (TRUE)
        {
                switch (va_arg(args, builder_part_t))
                {
                        case BUILD_BLOB_ASN1_DER:
+                               asn1 = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_EDDSA_PUB:
                                blob = va_arg(args, chunk_t);
                                continue;
                        case BUILD_END:
@@ -244,39 +291,11 @@ curve25519_public_key_t *curve25519_public_key_load(key_type_t type,
                .ref = 1,
        );
 
-       parser = asn1_parser_create(pubkeyObjects, blob);
-
-       while (parser->iterate(parser, &objectID, &object))
+       if (blob.len == ED25519_KEY_LEN)
        {
-               switch (objectID)
-               {
-                       case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM:
-                       {
-                               oid = asn1_parse_algorithmIdentifier(object,
-                                                                               parser->get_level(parser) + 1, NULL);
-                               if (oid != OID_ED25519)
-                               {
-                                       goto end;
-                               }
-                               break;
-                       }
-                       case ED25519_SUBJECT_PUBLIC_KEY:
-                       {
-                               /* encoded as an ASN1 BIT STRING */
-                               if (object.len != 1 + ED25519_KEY_LEN)
-                               {
-                                       goto end;
-                               }
-                               this->pubkey = chunk_clone(chunk_skip(object, 1));
-                               break;
-                       }
-               }
+               this->pubkey = chunk_clone(blob);
        }
-       success = parser->success(parser);
-
-end:
-       parser->destroy(parser);
-       if (!success)
+       else if (!asn1.len || !parse_public_key_info(this, asn1))
        {
                destroy(this);
                return NULL;