aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/ffi/ffi.h8
-rw-r--r--src/lib/ffi/ffi_pkey_algs.cpp49
-rw-r--r--src/tests/test_ffi.cpp17
3 files changed, 74 insertions, 0 deletions
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index 323bf54de..c1b1a1284 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -829,12 +829,20 @@ BOTAN_PUBLIC_API(2,0) int botan_privkey_load_rsa(botan_privkey_t* key,
botan_mp_t q,
botan_mp_t e);
+BOTAN_PUBLIC_API(2,0) int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key,
+ const uint8_t bits[],
+ size_t len);
+
BOTAN_PUBLIC_API(2,0) int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t rsa_key);
BOTAN_PUBLIC_API(2,0) int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t rsa_key);
BOTAN_PUBLIC_API(2,0) int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t rsa_key);
BOTAN_PUBLIC_API(2,0) int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t rsa_key);
BOTAN_PUBLIC_API(2,0) int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t rsa_key);
+BOTAN_PUBLIC_API(2,0) int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key,
+ uint8_t out[], size_t* out_len,
+ uint32_t flags);
+
BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_rsa(botan_pubkey_t* key,
botan_mp_t n,
botan_mp_t e);
diff --git a/src/lib/ffi/ffi_pkey_algs.cpp b/src/lib/ffi/ffi_pkey_algs.cpp
index 7fa06b71b..46c7e28d5 100644
--- a/src/lib/ffi/ffi_pkey_algs.cpp
+++ b/src/lib/ffi/ffi_pkey_algs.cpp
@@ -1,12 +1,14 @@
/*
* (C) 2015,2017 Jack Lloyd
* (C) 2017 Ribose Inc
+* (C) 2018 René Korthaus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/ffi.h>
#include <botan/hash.h>
+#include <botan/pem.h>
#include <botan/internal/ffi_util.h>
#include <botan/internal/ffi_pkey.h>
#include <botan/internal/ffi_rng.h>
@@ -282,6 +284,26 @@ int botan_privkey_load_rsa(botan_privkey_t* key,
#endif
}
+int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key,
+ const uint8_t bits[],
+ size_t len)
+ {
+#if defined(BOTAN_HAS_RSA)
+ *key = nullptr;
+
+ Botan::secure_vector<uint8_t> src(bits, bits + len);
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
+ *key = new botan_privkey_struct(new Botan::RSA_PrivateKey(Botan::AlgorithmIdentifier("RSA",
+ Botan::AlgorithmIdentifier::USE_NULL_PARAM),
+ src));
+ return BOTAN_FFI_SUCCESS;
+ });
+#else
+ BOTAN_UNUSED(key, bits, len);
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
int botan_pubkey_load_rsa(botan_pubkey_t* key,
botan_mp_t n, botan_mp_t e)
{
@@ -332,6 +354,33 @@ int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key)
return botan_pubkey_get_field(n, key, "n");
}
+int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key,
+ uint8_t out[], size_t* out_len,
+ uint32_t flags)
+ {
+#if defined(BOTAN_HAS_RSA)
+ return BOTAN_FFI_DO(Botan::Private_Key, rsa_key, k, {
+ if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&k))
+ {
+ if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER)
+ return write_vec_output(out, out_len, rsa->private_key_bits());
+ else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
+ return write_str_output(out, out_len, Botan::PEM_Code::encode(rsa->private_key_bits(),
+ "RSA PRIVATE KEY"));
+ else
+ return BOTAN_FFI_ERROR_BAD_FLAG;
+ }
+ else
+ {
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
+ }
+ });
+#else
+ BOTAN_UNUSED(rsa_key, out, out_len);
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
/* DSA specific operations */
int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
{
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
index 9eb7847a2..45a5f0139 100644
--- a/src/tests/test_ffi.cpp
+++ b/src/tests/test_ffi.cpp
@@ -1313,6 +1313,23 @@ class FFI_Unit_Tests final : public Test
botan_mp_destroy(e);
botan_mp_destroy(n);
+ size_t pkcs1_len = 0;
+ TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE,
+ botan_privkey_rsa_get_privkey, (loaded_privkey, nullptr, &pkcs1_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER));
+
+ std::vector<uint8_t> pkcs1(pkcs1_len);
+ TEST_FFI_OK(botan_privkey_rsa_get_privkey, (loaded_privkey, pkcs1.data(), &pkcs1_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER));
+
+ botan_privkey_t privkey_from_pkcs1;
+ TEST_FFI_OK(botan_privkey_load_rsa_pkcs1, (&privkey_from_pkcs1, pkcs1.data(), pkcs1_len));
+ TEST_FFI_OK(botan_privkey_destroy, (privkey_from_pkcs1));
+
+ pkcs1_len = 0;
+ TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE,
+ botan_privkey_rsa_get_privkey, (loaded_privkey, nullptr, &pkcs1_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
+ pkcs1.resize(pkcs1_len);
+ TEST_FFI_OK(botan_privkey_rsa_get_privkey, (loaded_privkey, pkcs1.data(), &pkcs1_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
+
char namebuf[32] = { 0 };
size_t name_len = sizeof(namebuf);
if(TEST_FFI_OK(botan_pubkey_algo_name, (loaded_pubkey, namebuf, &name_len)))