openssl: Add a generic private key loader
authorTobias Brunner <tobias@strongswan.org>
Thu, 22 Sep 2016 14:21:22 +0000 (16:21 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 5 Oct 2016 09:32:52 +0000 (11:32 +0200)
src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
src/libstrongswan/plugins/openssl/openssl_pkcs12.c
src/libstrongswan/plugins/openssl/openssl_plugin.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
src/libstrongswan/plugins/openssl/openssl_util.h

index 24fe623..22bbf6d 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2016 Tobias Brunner
  * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -304,7 +304,26 @@ static private_openssl_ec_private_key_t *create_empty(void)
        return this;
 }
 
-/**
+/*
+ * See header.
+ */
+private_key_t *openssl_ec_private_key_create(EVP_PKEY *key)
+{
+       private_openssl_ec_private_key_t *this;
+       EC_KEY *ec;
+
+       ec = EVP_PKEY_get1_EC_KEY(key);
+       EVP_PKEY_free(key);
+       if (!ec)
+       {
+               return NULL;
+       }
+       this = create_empty();
+       this->ec = ec;
+       return &this->public.key;
+}
+
+/*
  * See header.
  */
 openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type,
index f56c95a..84314f6 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2008-2016 Tobias Brunner
+ * HSR 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
@@ -21,6 +21,8 @@
 #ifndef OPENSSL_EC_PRIVATE_KEY_H_
 #define OPENSSL_EC_PRIVATE_KEY_H_
 
+#include <openssl/evp.h>
+
 #include <credentials/builder.h>
 #include <credentials/keys/private_key.h>
 
@@ -61,4 +63,12 @@ openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type,
 openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
                                                                                                          va_list args);
 
+/**
+ * Wrap an EVP_PKEY object of type EVP_PKEY_EC
+ *
+ * @param key          EVP_PKEY_EC key object (adopted)
+ * @return                     loaded key, NULL on failure
+ */
+private_key_t *openssl_ec_private_key_create(EVP_PKEY *key);
+
 #endif /** OPENSSL_EC_PRIVATE_KEY_H_ @}*/
index 705e96c..bbd400c 100644 (file)
 #include <library.h>
 #include <credentials/sets/mem_cred.h>
 
-#ifdef OPENSSL_IS_BORINGSSL
-#define EVP_PKEY_base_id(p) EVP_PKEY_type(p->type)
-#endif
-
 typedef struct private_pkcs12_t private_pkcs12_t;
 
 /**
index 1330427..ab73d71 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2008-2013 Tobias Brunner
+ * Copyright (C) 2008-2016 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -269,6 +269,53 @@ static bool seed_rng()
        return TRUE;
 }
 
+/**
+ * Generic key loader
+ */
+static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
+{
+       chunk_t blob = chunk_empty;
+       EVP_PKEY *key;
+
+       while (TRUE)
+       {
+               switch (va_arg(args, builder_part_t))
+               {
+                       case BUILD_BLOB_ASN1_DER:
+                               blob = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_END:
+                               break;
+                       default:
+                               return NULL;
+               }
+               break;
+       }
+
+       if (blob.ptr)
+       {
+               key = d2i_AutoPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
+               if (key)
+               {
+                       switch (EVP_PKEY_base_id(key))
+                       {
+#ifndef OPENSSL_NO_RSA
+                               case EVP_PKEY_RSA:
+                                       return openssl_rsa_private_key_create(key);
+#endif
+#ifndef OPENSSL_NO_ECDSA
+                               case EVP_PKEY_EC:
+                                       return openssl_ec_private_key_create(key);
+#endif
+                               default:
+                                       EVP_PKEY_free(key);
+                                       break;
+                       }
+               }
+       }
+       return NULL;
+}
+
 METHOD(plugin_t, get_name, char*,
        private_openssl_plugin_t *this)
 {
@@ -504,6 +551,9 @@ METHOD(plugin_t, get_features, int,
                PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
 #endif
 #endif /* OPENSSL_NO_ECDSA */
+               /* generic key loader */
+               PLUGIN_REGISTER(PRIVKEY, openssl_private_key_load, TRUE),
+                       PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
                PLUGIN_REGISTER(RNG, openssl_rng_create),
                        PLUGIN_PROVIDE(RNG, RNG_STRONG),
                        PLUGIN_PROVIDE(RNG, RNG_WEAK),
index cf8c3d7..54ecf25 100644 (file)
@@ -1,7 +1,7 @@
 /*
+ * Copyright (C) 2008-2016 Tobias Brunner
  * Copyright (C) 2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -327,7 +327,7 @@ static private_openssl_rsa_private_key_t *create_empty()
        return this;
 }
 
-/**
+/*
  * See header.
  */
 openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type,
@@ -383,7 +383,26 @@ error:
        return NULL;
 }
 
-/**
+/*
+ * See header
+ */
+private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key)
+{
+       private_openssl_rsa_private_key_t *this;
+       RSA *rsa;
+
+       rsa = EVP_PKEY_get1_RSA(key);
+       EVP_PKEY_free(key);
+       if (!rsa)
+       {
+               return NULL;
+       }
+       this = create_empty();
+       this->rsa = rsa;
+       return &this->public.key;
+}
+
+/*
  * See header
  */
 openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
@@ -528,7 +547,7 @@ static bool login(ENGINE *engine, chunk_t keyid)
 }
 #endif /* OPENSSL_NO_ENGINE */
 
-/**
+/*
  * See header.
  */
 openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
index 60889d6..34ce4c7 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2008-2016 Tobias Brunner
+ * HSR 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
@@ -21,6 +21,8 @@
 #ifndef OPENSSL_RSA_PRIVATE_KEY_H_
 #define OPENSSL_RSA_PRIVATE_KEY_H_
 
+#include <openssl/evp.h>
+
 #include <credentials/builder.h>
 #include <credentials/keys/private_key.h>
 
@@ -62,6 +64,14 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
                                                                                                                va_list args);
 
 /**
+ * Wrap an EVP_PKEY object of type EVP_PKEY_RSA
+ *
+ * @param key          EVP_PKEY_RSA key object (adopted)
+ * @return                     loaded key, NULL on failure
+ */
+private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key);
+
+/**
  * Connect to a RSA private key on a smartcard.
  *
  * Accepts the BUILD_SMARTCARD_KEYID and the BUILD_SMARTCARD_PIN
index f4186e8..7c5c367 100644 (file)
@@ -136,6 +136,13 @@ int openssl_asn1_known_oid(ASN1_OBJECT *obj);
 time_t openssl_asn1_to_time(ASN1_TIME *time);
 
 /**
+ * Compatibility macros
+ */
+#ifdef OPENSSL_IS_BORINGSSL
+#define EVP_PKEY_base_id(p) EVP_PKEY_type(p->type)
+#endif
+
+/**
  * Macros to define fallback getters/setters to access keys (BIGNUM*) for types
  * that were made opaque with OpenSSL 1.1.0.
  */