sshkey: Added builder for SSHKEY RSA keys
authorTobias Brunner <tobias@strongswan.org>
Mon, 1 Apr 2013 14:02:00 +0000 (16:02 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 7 May 2013 13:38:28 +0000 (15:38 +0200)
src/libstrongswan/credentials/builder.c
src/libstrongswan/credentials/builder.h
src/libstrongswan/plugins/sshkey/Makefile.am
src/libstrongswan/plugins/sshkey/sshkey_builder.c [new file with mode: 0644]
src/libstrongswan/plugins/sshkey/sshkey_builder.h [new file with mode: 0644]
src/libstrongswan/plugins/sshkey/sshkey_plugin.c

index f585838..6710dfb 100644 (file)
@@ -24,6 +24,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
        "BUILD_BLOB_PEM",
        "BUILD_BLOB_PGP",
        "BUILD_BLOB_DNSKEY",
+       "BUILD_BLOB_SSHKEY",
        "BUILD_BLOB_ALGID_PARAMS",
        "BUILD_KEY_SIZE",
        "BUILD_SIGNING_KEY",
index 740041a..5ab462f 100644 (file)
@@ -59,6 +59,8 @@ enum builder_part_t {
        BUILD_BLOB_PGP,
        /** DNS public key blob (RFC 4034, RSA specifc RFC 3110), chunk_t */
        BUILD_BLOB_DNSKEY,
+       /** SSH public key blob (RFC 4253), chunk_t */
+       BUILD_BLOB_SSHKEY,
        /** parameters from algorithmIdentifier (ASN.1 blob), chunk_t */
        BUILD_BLOB_ALGID_PARAMS,
        /** key size in bits, as used for key generation, u_int */
index 108a5f3..8101726 100644 (file)
@@ -10,6 +10,7 @@ plugin_LTLIBRARIES = libstrongswan-sshkey.la
 endif
 
 libstrongswan_sshkey_la_SOURCES = \
-       sshkey_plugin.h sshkey_plugin.c
+       sshkey_plugin.h sshkey_plugin.c \
+       sshkey_builder.h sshkey_builder.c
 
 libstrongswan_sshkey_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/sshkey/sshkey_builder.c b/src/libstrongswan/plugins/sshkey/sshkey_builder.c
new file mode 100644 (file)
index 0000000..31c7b21
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "sshkey_builder.h"
+
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+/**
+ * Load a generic public key from an SSH key blob
+ */
+static sshkey_public_key_t *parse_public_key(chunk_t blob)
+{
+       bio_reader_t *reader;
+       chunk_t format;
+
+       reader = bio_reader_create(blob);
+       if (!reader->read_data32(reader, &format))
+       {
+               DBG1(DBG_LIB, "invalid key format in SSH key");
+               reader->destroy(reader);
+               return NULL;
+       }
+       if (chunk_equals(format, chunk_from_str("ssh-rsa")))
+       {
+               chunk_t n, e;
+
+               if (!reader->read_data32(reader, &e) ||
+                       !reader->read_data32(reader, &n))
+               {
+                       DBG1(DBG_LIB, "invalid RSA key in SSH key");
+                       reader->destroy(reader);
+                       return NULL;
+               }
+               reader->destroy(reader);
+               return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+                                               BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
+       }
+       DBG1(DBG_LIB, "unsupported SSH key format %.*s", (int)format.len,
+                format.ptr);
+       reader->destroy(reader);
+       return NULL;
+}
+
+/**
+ * See header.
+ */
+sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
+{
+       chunk_t blob = chunk_empty;
+
+       while (TRUE)
+       {
+               switch (va_arg(args, builder_part_t))
+               {
+                       case BUILD_BLOB_SSHKEY:
+                               blob = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_END:
+                               break;
+                       default:
+                               return NULL;
+               }
+               break;
+       }
+       if (blob.ptr && type == KEY_ANY)
+       {
+               return parse_public_key(blob);
+       }
+       return NULL;
+}
diff --git a/src/libstrongswan/plugins/sshkey/sshkey_builder.h b/src/libstrongswan/plugins/sshkey/sshkey_builder.h
new file mode 100644 (file)
index 0000000..e4c7a90
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sshky_public_key sshky_public_key
+ * @{ @ingroup sshkey_p
+ */
+
+#ifndef SSHKEY_BUILDER_H_
+#define SSHKEY_BUILDER_H_
+
+#include <credentials/builder.h>
+#include <credentials/keys/public_key.h>
+
+typedef struct sshkey_public_key_t sshkey_public_key_t;
+
+/**
+ * Public key implementation supporting RFC 4253 decoding.
+ */
+struct sshkey_public_key_t {
+
+       /**
+        * Implements public_key_t interface.
+        */
+       public_key_t interface;
+};
+
+/**
+ * Load a public key in RFC 4253 format.
+ *
+ * Takes a BUILD_BLOB_SSHKEY to parse the public key.
+ *
+ * @param type         type of the key, must be KEY_ANY
+ * @param args         builder_part_t argument list
+ * @return                     built key, NULL on failure
+ */
+sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args);
+
+#endif /** SSHKEY_BUILDER_H_ @}*/
index 3d90db6..fe62526 100644 (file)
@@ -16,6 +16,7 @@
 #include "sshkey_plugin.h"
 
 #include <library.h>
+#include "sshkey_builder.h"
 
 typedef struct private_sshkey_plugin_t private_sshkey_plugin_t;
 
@@ -40,6 +41,8 @@ METHOD(plugin_t, get_features, int,
        private_sshkey_plugin_t *this, plugin_feature_t *features[])
 {
        static plugin_feature_t f[] = {
+               PLUGIN_REGISTER(PUBKEY, sshkey_public_key_load, FALSE),
+                       PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
        };
        *features = f;
        return countof(f);