botan_ec_public_key.h botan_ec_public_key.c \
botan_ec_private_key.h botan_ec_private_key.c \
botan_util.h botan_util.c \
+ botan_util_keys.h botan_util_keys.c \
botan_gcm.h botan_gcm.c
libstrongswan_botan_la_LDFLAGS = -module -avoid-version
#include "botan_ec_private_key.h"
+#include "botan_ec_public_key.h"
#include "botan_util.h"
#include <botan/build.h>
METHOD(private_key_t, get_public_key, public_key_t*,
private_botan_ec_private_key_t *this)
{
- public_key_t *public;
botan_pubkey_t pubkey;
- chunk_t key = chunk_empty;
if (botan_privkey_export_pubkey(&pubkey, this->key))
{
- return FALSE;
- }
-
- if (botan_pubkey_export(pubkey, NULL, &key.len,
- BOTAN_PRIVKEY_EXPORT_FLAG_DER)
- != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
- {
- botan_pubkey_destroy(pubkey);
- return FALSE;
- }
-
- key = chunk_alloc(key.len);
-
- if (botan_pubkey_export(pubkey, key.ptr, &key.len,
- BOTAN_PRIVKEY_EXPORT_FLAG_DER))
- {
- chunk_free(&key);
- botan_pubkey_destroy(pubkey);
- return FALSE;
+ return NULL;
}
-
- public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
- BUILD_BLOB_ASN1_DER, key, BUILD_END);
-
- chunk_free(&key);
- botan_pubkey_destroy(pubkey);
- return public;
+ return (public_key_t*)botan_ec_public_key_adopt(pubkey);
}
METHOD(private_key_t, get_fingerprint, bool,
return this;
}
+/*
+ * Described in header
+ */
+botan_ec_private_key_t *botan_ec_private_key_adopt(botan_privkey_t key, int oid)
+{
+ private_botan_ec_private_key_t *this;
+
+ this = create_empty(oid);
+ this->key = key;
+
+ return &this->public;
+}
+
/*
* Described in header
*/
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2018 René Korthaus
* Copyright (C) 2018 Konstantinos Kolelis
* Rohde & Schwarz Cybersecurity GmbH
#ifndef BOTAN_EC_PRIVATE_KEY_H_
#define BOTAN_EC_PRIVATE_KEY_H_
+#include <botan/ffi.h>
+
#include <credentials/builder.h>
#include <credentials/keys/private_key.h>
botan_ec_private_key_t *botan_ec_private_key_load(key_type_t type,
va_list args);
+/**
+ * Load a ECDSA private key by adopting a botan_privkey_t object.
+ *
+ * @param key private key object (adopted)
+ * @param oid EC curve OID
+ * @return loaded key, NULL on failure
+ */
+botan_ec_private_key_t *botan_ec_private_key_adopt(botan_privkey_t key,
+ int oid);
+
#endif /** BOTAN_EC_PRIVATE_KEY_H_ @}*/
/*
* Described in header
*/
-botan_ec_public_key_t *botan_ec_public_key_load(key_type_t type, va_list args)
+botan_ec_public_key_t *botan_ec_public_key_adopt(botan_pubkey_t key)
{
private_botan_ec_public_key_t *this;
- chunk_t blob = chunk_empty;
- botan_rng_t rng;
- size_t namesize = 0;
- char *namebuf;
-
- if (type != KEY_ECDSA)
- {
- return NULL;
- }
-
- 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;
- }
INIT(this,
.public = {
.destroy = _destroy,
},
},
+ .key = key,
.ref = 1,
);
- if (botan_pubkey_load(&this->key, blob.ptr, blob.len))
- {
- free(this);
- return NULL;
- }
-
- if (botan_pubkey_algo_name(this->key, NULL, &namesize)
- != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
- {
- destroy(this);
- return NULL;
- }
-
- namebuf = malloc(namesize);
- if (botan_pubkey_algo_name(this->key, namebuf, &namesize))
- {
- free(namebuf);
- destroy(this);
- return NULL;
- }
-
- if (!strneq(namebuf, "ECDSA", namesize))
- {
- free(namebuf);
- destroy(this);
- return NULL;
- }
- free(namebuf);
-
- if (botan_rng_init(&rng, "user"))
- {
- return NULL;
- }
-
- if (botan_pubkey_check_key(this->key, rng, BOTAN_CHECK_KEY_EXPENSIVE_TESTS))
- {
- DBG1(DBG_LIB, "public key failed key checks");
- botan_rng_destroy(rng);
- destroy(this);
- return NULL;
- }
-
- botan_rng_destroy(rng);
return &this->public;
}
#ifndef BOTAN_EC_PUBLIC_KEY_H_
#define BOTAN_EC_PUBLIC_KEY_H_
-typedef struct botan_ec_public_key_t botan_ec_public_key_t;
+#include <botan/ffi.h>
#include <credentials/builder.h>
#include <credentials/keys/public_key.h>
+typedef struct botan_ec_public_key_t botan_ec_public_key_t;
+
/**
* public_key_t implementation of ECDSA using botan.
*/
};
/**
- * Load a ECDSA public key using botan.
- *
- * Accepts a BUILD_BLOB_ASN1_DER argument.
+ * Load a ECDSA public key by adopting a botan_pubkey_t object.
*
- * @param type type of the key, must be KEY_ECDSA
- * @param args builder_part_t argument list
- * @return loaded key, NULL on failure
+ * @param key public key object (adopted)
+ * @return loaded key, NULL on failure
*/
-botan_ec_public_key_t *botan_ec_public_key_load(key_type_t type, va_list args);
+botan_ec_public_key_t *botan_ec_public_key_adopt(botan_pubkey_t key);
#endif /** BOTAN_EC_PUBLIC_KEY_H_ @}*/
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2018 René Korthaus
* Copyright (C) 2018 Konstantinos Kolelis
* Rohde & Schwarz Cybersecurity GmbH
#include "botan_ec_public_key.h"
#include "botan_ec_private_key.h"
#include "botan_gcm.h"
+#include "botan_util_keys.h"
#include <library.h>
PLUGIN_PROVIDE(DH, MODP_1024_160),
PLUGIN_PROVIDE(DH, MODP_768_BIT),
PLUGIN_PROVIDE(DH, MODP_CUSTOM),
+#endif
+#ifdef BOTAN_HAS_ECDH
+ /* EC DH groups */
+ PLUGIN_REGISTER(DH, botan_ec_diffie_hellman_create),
+ PLUGIN_PROVIDE(DH, ECP_256_BIT),
+ PLUGIN_PROVIDE(DH, ECP_384_BIT),
+ PLUGIN_PROVIDE(DH, ECP_521_BIT),
+ PLUGIN_PROVIDE(DH, ECP_256_BP),
+ PLUGIN_PROVIDE(DH, ECP_384_BP),
+ PLUGIN_PROVIDE(DH, ECP_512_BP),
#endif
/* crypters */
PLUGIN_REGISTER(CRYPTER, botan_crypter_create),
#endif
#endif /* BOTAN_HAS_HMAC */
-#ifdef BOTAN_HAS_ECDH
- /* EC DH groups */
- PLUGIN_REGISTER(DH, botan_ec_diffie_hellman_create),
- PLUGIN_PROVIDE(DH, ECP_256_BIT),
- PLUGIN_PROVIDE(DH, ECP_384_BIT),
- PLUGIN_PROVIDE(DH, ECP_521_BIT),
- PLUGIN_PROVIDE(DH, ECP_256_BP),
- PLUGIN_PROVIDE(DH, ECP_384_BP),
- PLUGIN_PROVIDE(DH, ECP_512_BP),
+ /* generic key loaders */
+#if defined (BOTAN_HAS_RSA) || defined(BOTAN_HAS_ECDSA)
+ PLUGIN_REGISTER(PUBKEY, botan_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+#ifdef BOTAN_HAS_RSA
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+#endif
+#ifdef BOTAN_HAS_ECDSA
+ PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
+#endif
+ PLUGIN_REGISTER(PRIVKEY, botan_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+#ifdef BOTAN_HAS_RSA
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+#endif
+#ifdef BOTAN_HAS_ECDSA
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
+#endif
#endif
/* RSA */
#ifdef BOTAN_HAS_RSA
PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
PLUGIN_REGISTER(PRIVKEY, botan_rsa_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
PLUGIN_REGISTER(PRIVKEY_GEN, botan_rsa_private_key_gen, FALSE),
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
/* encryption/signature schemes */
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
PLUGIN_REGISTER(PRIVKEY_GEN, botan_ec_private_key_gen, FALSE),
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA),
- PLUGIN_REGISTER(PUBKEY, botan_ec_public_key_load, TRUE),
- PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
#ifdef BOTAN_HAS_EMSA_RAW
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL),
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2018 René Korthaus
* Rohde & Schwarz Cybersecurity GmbH
*
*/
#include "botan_rsa_private_key.h"
+#include "botan_rsa_public_key.h"
#include <botan/build.h>
refcount_t ref;
};
-/**
- * Get the binary representation of a named RSA parameter
- */
-static bool get_rsa_field(botan_privkey_t *key, const char *field_name,
- chunk_t *value)
-{
- botan_mp_t field;
- size_t field_size = 0;
-
- if (botan_mp_init(&field))
- {
- return FALSE;
- }
-
- if (botan_privkey_get_field(field, *key, field_name) ||
- botan_mp_num_bytes(field, &field_size) ||
- !field_size)
- {
- botan_mp_destroy(field);
- return FALSE;
- }
-
- *value = chunk_alloc(field_size);
- if (botan_mp_to_bin(field, value->ptr))
- {
- botan_mp_destroy(field);
- chunk_clear(value);
- return FALSE;
- }
- botan_mp_destroy(field);
- return TRUE;
-}
-
/**
* Build an EMSA PSS signature described in PKCS#1
*/
METHOD(private_key_t, get_public_key, public_key_t*,
private_botan_rsa_private_key_t *this)
{
- public_key_t *pub_key;
- chunk_t n, e;
-
- if (!get_rsa_field(&this->key, "n", &n))
- {
- return NULL;
- }
+ botan_pubkey_t pubkey;
- if (!get_rsa_field(&this->key, "e", &e))
+ if (botan_privkey_export_pubkey(&pubkey, this->key))
{
- chunk_free(&n);
return NULL;
}
-
- pub_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
- BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e,
- BUILD_END);
-
- chunk_free(&n);
- chunk_free(&e);
- return pub_key;
+ return (public_key_t*)botan_rsa_public_key_adopt(pubkey);
}
METHOD(private_key_t, get_fingerprint, bool,
return this;
}
+/*
+ * Described in header
+ */
+botan_rsa_private_key_t *botan_rsa_private_key_adopt(botan_privkey_t key)
+{
+ private_botan_rsa_private_key_t *this;
+
+ this = create_empty();
+ this->key = key;
+
+ return &this->public;
+}
+
/*
* Described in header
*/
break;
}
+ if (type == KEY_ANY && !blob.ptr)
+ {
+ return NULL;
+ }
+
if (blob.ptr)
{
this = create_empty();
#ifndef BOTAN_RSA_PRIVATE_KEY_H_
#define BOTAN_RSA_PRIVATE_KEY_H_
+#include <botan/ffi.h>
+
#include <credentials/builder.h>
#include <credentials/keys/private_key.h>
botan_rsa_private_key_t *botan_rsa_private_key_load(key_type_t type,
va_list args);
+/**
+ * Load a RSA private key by adopting a botan_privkey_t object.
+ *
+ * @param key private key object (adopted)
+ * @return loaded key, NULL on failure
+ */
+botan_rsa_private_key_t *botan_rsa_private_key_adopt(botan_privkey_t key);
+
#endif /** BOTAN_RSA_PRIVATE_KEY_H_ @}*/
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2018 René Korthaus
* Rohde & Schwarz Cybersecurity GmbH
*
return this;
}
+/*
+ * Described in header
+ */
+botan_rsa_public_key_t *botan_rsa_public_key_adopt(botan_pubkey_t key)
+{
+ private_botan_rsa_public_key_t *this;
+
+ this = create_empty();
+ this->key = key;
+
+ return &this->public;
+}
+
/*
* Described in header
*/
va_list args)
{
private_botan_rsa_public_key_t *this = NULL;
- chunk_t blob, n, e;
+ chunk_t n, e;
- n = e = blob = chunk_empty;
+ n = e = chunk_empty;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
{
- case BUILD_BLOB_ASN1_DER:
- blob = va_arg(args, chunk_t);
- continue;
case BUILD_RSA_MODULUS:
n = va_arg(args, chunk_t);
continue;
break;
}
- if (blob.ptr)
- {
- switch (type)
- {
- /* SubjectPublicKeyInfo */
- case KEY_RSA:
- case KEY_ANY:
- {
- size_t namesize = 0;
- char *namebuf;
-
- this = create_empty();
-
- if (botan_pubkey_load(&this->key, blob.ptr, blob.len))
- {
- free(this);
- return NULL;
- }
-
- if (botan_pubkey_algo_name(this->key, NULL, &namesize)
- != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
- {
- destroy(this);
- return NULL;
- }
-
- namebuf = malloc(namesize);
- if (botan_pubkey_algo_name(this->key, namebuf, &namesize))
- {
- free(namebuf);
- destroy(this);
- return NULL;
- }
-
- if (!strneq(namebuf, "RSA", namesize))
- {
- free(namebuf);
- destroy(this);
- return NULL;
- }
- free(namebuf);
- break;
- }
- default:
- return NULL;
- }
- }
- else if (n.ptr && e.ptr && type == KEY_RSA)
+ if (n.ptr && e.ptr && type == KEY_RSA)
{
botan_mp_t mp_n, mp_e;
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2018 René Korthaus
* Rohde & Schwarz Cybersecurity GmbH
*
#ifndef BOTAN_RSA_PUBLIC_KEY_H_
#define BOTAN_RSA_PUBLIC_KEY_H_
-typedef struct botan_rsa_public_key_t botan_rsa_public_key_t;
+#include <botan/ffi.h>
#include <credentials/keys/public_key.h>
+typedef struct botan_rsa_public_key_t botan_rsa_public_key_t;
+
/**
* public_key_t implementation of RSA algorithm using Botan.
*/
/**
* Load a RSA public key using Botan.
*
- * Accepts a BUILD_BLOB_ASN1_DER argument.
+ * Accepts a BUILD_RSA_MODULUS/BUILD_RSA_PUB_EXP arguments.
*
* @param type type of the key, must be KEY_RSA
* @param args builder_part_t argument list
botan_rsa_public_key_t *botan_rsa_public_key_load(key_type_t type,
va_list args);
+/**
+ * Load a RSA public key by adopting a botan_pubkey_t object.
+ *
+ * @param key public key object (adopted)
+ * @return loaded key, NULL on failure
+ */
+botan_rsa_public_key_t *botan_rsa_public_key_adopt(botan_pubkey_t key);
+
#endif /** BOTAN_RSA_PUBLIC_KEY_H_ @}*/
--- /dev/null
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "botan_util_keys.h"
+#include "botan_ec_public_key.h"
+#include "botan_ec_private_key.h"
+#include "botan_rsa_public_key.h"
+#include "botan_rsa_private_key.h"
+
+#include <asn1/asn1.h>
+#include <asn1/oid.h>
+
+/**
+ * Get the algorithm name of a public key
+ */
+static char *get_algo_name(botan_pubkey_t pubkey)
+{
+ char *name;
+ size_t len = 0;
+
+ if (botan_pubkey_algo_name(pubkey, NULL, &len)
+ != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
+ {
+ return NULL;
+ }
+
+ name = malloc(len);
+ if (botan_pubkey_algo_name(pubkey, name, &len))
+ {
+ free(name);
+ return NULL;
+ }
+ return name;
+}
+
+/*
+ * Described in header
+ */
+public_key_t *botan_public_key_load(key_type_t type, va_list args)
+{
+ public_key_t *this = NULL;
+ botan_pubkey_t pubkey;
+ chunk_t blob = chunk_empty;
+ botan_rng_t rng;
+ char *name;
+
+ 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 (botan_rng_init(&rng, "user"))
+ {
+ return NULL;
+ }
+ if (botan_pubkey_load(&pubkey, blob.ptr, blob.len))
+ {
+ botan_rng_destroy(rng);
+ return NULL;
+ }
+ if (botan_pubkey_check_key(pubkey, rng, BOTAN_CHECK_KEY_EXPENSIVE_TESTS))
+ {
+ DBG1(DBG_LIB, "public key failed key checks");
+ botan_pubkey_destroy(pubkey);
+ botan_rng_destroy(rng);
+ return NULL;
+ }
+ botan_rng_destroy(rng);
+
+ name = get_algo_name(pubkey);
+ if (!name)
+ {
+ botan_pubkey_destroy(pubkey);
+ return NULL;
+ }
+
+ if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
+ {
+ this = (public_key_t*)botan_rsa_public_key_adopt(pubkey);
+ }
+ else if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
+ {
+ this = (public_key_t*)botan_ec_public_key_adopt(pubkey);
+ }
+ else
+ {
+ botan_pubkey_destroy(pubkey);
+ }
+ free(name);
+ return this;
+}
+
+/**
+ * Determine the curve OID from a PKCS#8 structure
+ */
+static int determine_ec_oid(chunk_t pkcs8)
+{
+ int oid = OID_UNKNOWN;
+ chunk_t inner, params = chunk_empty;
+
+ if (asn1_unwrap(&pkcs8, &pkcs8) == ASN1_SEQUENCE &&
+ asn1_unwrap(&pkcs8, &inner) == ASN1_INTEGER &&
+ asn1_parse_integer_uint64(inner) == 0 &&
+ asn1_parse_algorithmIdentifier(pkcs8, 0, ¶ms) == OID_EC_PUBLICKEY &&
+ params.len &&
+ asn1_unwrap(¶ms, ¶ms) == ASN1_OID)
+ {
+ oid = asn1_known_oid(params);
+ }
+ return oid;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *botan_private_key_load(key_type_t type, va_list args)
+{
+ private_key_t *this = NULL;
+ botan_privkey_t key;
+ botan_pubkey_t pubkey;
+ chunk_t blob = chunk_empty;
+ botan_rng_t rng;
+ char *name;
+ int oid;
+
+ 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 (botan_rng_init(&rng, "user"))
+ {
+ return NULL;
+ }
+ if (botan_privkey_load(&key, rng, blob.ptr, blob.len, NULL))
+ {
+ botan_rng_destroy(rng);
+ return NULL;
+ }
+ botan_rng_destroy(rng);
+
+ if (botan_privkey_export_pubkey(&pubkey, key))
+ {
+ botan_privkey_destroy(key);
+ return NULL;
+ }
+ name = get_algo_name(pubkey);
+ botan_pubkey_destroy(pubkey);
+ if (!name)
+ {
+ return NULL;
+ }
+ if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
+ {
+ this = (private_key_t*)botan_rsa_private_key_adopt(key);
+ }
+ else if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
+ {
+ oid = determine_ec_oid(blob);
+ if (oid != OID_UNKNOWN)
+ {
+ this = (private_key_t*)botan_ec_private_key_adopt(key, oid);
+ }
+ }
+ if (!this)
+ {
+ botan_privkey_destroy(key);
+ }
+ free(name);
+ return this;
+}
--- /dev/null
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * Helper functions to load public and private keys in a generic way
+ *
+ * @defgroup botan_util_keys botan_util_keys
+ * @{ @ingroup botan_p
+ */
+
+#ifndef BOTAN_UTIL_KEYS_H_
+#define BOTAN_UTIL_KEYS_H_
+
+#include <botan/ffi.h>
+
+#include <credentials/keys/public_key.h>
+#include <credentials/keys/private_key.h>
+
+/**
+ * Load a public key in subjectPublicKeyInfo encoding
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
+ *
+ * @param type type of the key
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+public_key_t *botan_public_key_load(key_type_t type, va_list args);
+
+/**
+ * Load a private key in PKCS#8 encoding
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
+ *
+ * @param type type of the key
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+private_key_t *botan_private_key_load(key_type_t type, va_list args);
+
+#endif /** BOTAN_UTIL_KEYS_H_ @}*/