aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/ffi/ffi.cpp167
-rw-r--r--src/tests/test_ffi.cpp32
2 files changed, 116 insertions, 83 deletions
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 9940c380e..4fcb73f82 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -330,8 +330,66 @@ Botan::BigInt privkey_get_field(const Botan::Private_Key& key,
throw Botan::Exception("Unsupported algorithm type for botan_privkey_get_field");
}
+template<class ECPrivateKey_t>
+int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
+ const Botan::BigInt& scalar,
+ const char* curve_name)
+ {
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+
+ if(curve_name == nullptr)
+ return -1;
+
+ try
+ {
+ Botan::Null_RNG null_rng;
+ Botan::EC_Group grp(curve_name);
+ key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
+ return 0;
+ }
+ catch(std::exception& e)
+ {
+ log_exception(BOTAN_CURRENT_FUNCTION, e.what());
+ }
+ return -1;
+#else
+ BOTAN_UNUSED(key, scalar, scalar_len, curve_name);
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
}
+template<class ECPublicKey_t>
+int pubkey_load_ec( std::unique_ptr<ECPublicKey_t>& key,
+ const Botan::BigInt& public_x,
+ const Botan::BigInt& public_y,
+ const char* curve_name)
+ {
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+
+ if(curve_name == nullptr)
+ return -1;
+
+ try
+ {
+ Botan::Null_RNG null_rng;
+ Botan::EC_Group grp(curve_name);
+ Botan::PointGFp uncompressed_point(grp.get_curve(), public_x, public_y);
+ key.reset(new ECPublicKey_t(grp, uncompressed_point));
+ return 0;
+ }
+ catch(std::exception& e)
+ {
+ log_exception(BOTAN_CURRENT_FUNCTION, e.what());
+ }
+ return -1;
+#else
+ BOTAN_UNUSED(key, public_x, public_y, curve_name);
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+
extern "C" {
#define BOTAN_FFI_DECLARE_STRUCT(NAME, TYPE, MAGIC) \
@@ -1699,85 +1757,20 @@ int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key,
#endif
}
-namespace {
-/* Those functions can't be defined in namespace {} that's located higher in this file
- * as they use botan_privkey_struct/botan_pubkey_struct structs.
- */
-int privkey_load_ec(botan_privkey_t* key,
- const botan_mp_t scalar,
- const char* curve_name,
- const std::string& algo_name)
+int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
+ const botan_mp_t public_x,
+ const botan_mp_t public_y,
+ const char* curve_name)
{
-#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
- *key = nullptr;
- try
- {
- Botan::Null_RNG null_rng;
- Botan::EC_Group grp(curve_name);
- if (algo_name.compare("ECDSA") == 0) {
- *key = new botan_privkey_struct(new Botan::ECDSA_PrivateKey(null_rng, grp, safe_get(scalar)));
- } else if (algo_name.compare("ECDH") == 0) {
- *key = new botan_privkey_struct(new Botan::ECDH_PrivateKey(null_rng, grp, safe_get(scalar)));
- } else {
- return -1;
- }
-
- return 0;
- }
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return -1;
-#else
- BOTAN_UNUSED(key, scalar, scalar_len, curve_name);
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-int pubkey_load_ec(botan_pubkey_t* key,
- const botan_mp_t public_x,
- const botan_mp_t public_y,
- const char* curve_name,
- const std::string& algo_name)
- {
-#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
- if(key == nullptr || curve_name == nullptr)
- return -1;
- *key = nullptr;
- try
+ std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
+ if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
{
- Botan::Null_RNG null_rng;
- Botan::EC_Group grp(curve_name);
- Botan::PointGFp uncompressed_point(grp.get_curve(), safe_get(public_x), safe_get(public_y));
- if (algo_name.compare("ECDSA") == 0) {
- *key = new botan_pubkey_struct(new Botan::ECDSA_PublicKey(grp, uncompressed_point));
- } else if (algo_name.compare("ECDH") == 0) {
- *key = new botan_pubkey_struct(new Botan::ECDH_PublicKey(grp, uncompressed_point));
- } else {
- return -1;
- }
-
+ *key = new botan_pubkey_struct(p_key.release());
return 0;
}
- catch(std::exception& e)
- {
- log_exception(BOTAN_CURRENT_FUNCTION, e.what());
- }
- return -1;
-#else
- BOTAN_UNUSED(key, public_x, public_y, curve_name);
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
-#endif
- }
-} // namespace {}
-int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
- const botan_mp_t public_x,
- const botan_mp_t public_y,
- const char* curve_name)
- {
- return pubkey_load_ec(key, public_x, public_y, curve_name, "ECDSA");
+ return -1;
}
int botan_pubkey_load_ecdh(botan_pubkey_t* key,
@@ -1785,21 +1778,41 @@ int botan_pubkey_load_ecdh(botan_pubkey_t* key,
const botan_mp_t public_y,
const char* curve_name)
{
- return pubkey_load_ec(key, public_x, public_y, curve_name, "ECDH");
+ std::unique_ptr<Botan::ECDH_PublicKey> p_key;
+ if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
+ {
+ *key = new botan_pubkey_struct(p_key.release());
+ return 0;
+ }
+
+ return -1;
}
int botan_privkey_load_ecdsa(botan_privkey_t* key,
const botan_mp_t scalar,
const char* curve_name)
{
- return privkey_load_ec(key, scalar, curve_name, "ECDSA");
- }
+ std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
+ if(!privkey_load_ec(p_key, safe_get(scalar), curve_name))
+ {
+ *key = new botan_privkey_struct(p_key.release());
+ return 0;
+ }
+ return -1;
+ }
int botan_privkey_load_ecdh(botan_privkey_t* key,
const botan_mp_t scalar,
const char* curve_name)
{
- return privkey_load_ec(key, scalar, curve_name, "ECDH");
+ std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
+ if(!privkey_load_ec(p_key, safe_get(scalar), curve_name))
+ {
+ *key = new botan_privkey_struct(p_key.release());
+ return 0;
+ }
+
+ return -1;
}
int botan_pubkey_get_field(botan_mp_t output,
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
index dc6b25a48..e9d9b6e20 100644
--- a/src/tests/test_ffi.cpp
+++ b/src/tests/test_ffi.cpp
@@ -1269,9 +1269,9 @@ class FFI_Unit_Tests : public Test
TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier));
}
- botan_mp_destroy(private_scalar);
- botan_mp_destroy(public_x);
- botan_mp_destroy(public_y);
+ TEST_FFI_OK(botan_mp_destroy, (private_scalar));
+ TEST_FFI_OK(botan_mp_destroy, (public_x));
+ TEST_FFI_OK(botan_mp_destroy, (public_y));
TEST_FFI_OK(botan_pubkey_destroy, (pub));
TEST_FFI_OK(botan_privkey_destroy, (priv));
TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
@@ -1284,6 +1284,13 @@ class FFI_Unit_Tests : public Test
{
Test::Result result("FFI ECDH");
+ botan_mp_t private_scalar, public_x, public_y;
+ botan_privkey_t loaded_privkey1;
+ botan_pubkey_t loaded_pubkey1;
+ botan_mp_init(&private_scalar);
+ botan_mp_init(&public_x);
+ botan_mp_init(&public_y);
+
botan_privkey_t priv1;
REQUIRE_FFI_OK(botan_privkey_create_ecdh, (&priv1, rng, "secp256r1"));
@@ -1296,11 +1303,20 @@ class FFI_Unit_Tests : public Test
botan_pubkey_t pub2;
REQUIRE_FFI_OK(botan_privkey_export_pubkey, (&pub2, priv2));
- ffi_test_pubkey_export(result, pub1, priv1, rng);
+ /* Reload key-pair1 in order to test functions for key loading */
+ TEST_FFI_OK(botan_privkey_get_field, (private_scalar, priv1, "x"));
+ TEST_FFI_OK(botan_pubkey_get_field, (public_x, pub1, "public_x"));
+ TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub1, "public_y"));
+ TEST_FFI_OK(botan_privkey_load_ecdh, (&loaded_privkey1, private_scalar, "secp256r1"));
+ TEST_FFI_OK(botan_pubkey_load_ecdh, (&loaded_pubkey1, public_x, public_y, "secp256r1"));
+ TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey1, rng, 0));
+ TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey1, rng, 0));
+
+ ffi_test_pubkey_export(result, loaded_pubkey1, priv1, rng);
ffi_test_pubkey_export(result, pub2, priv2, rng);
botan_pk_op_ka_t ka1;
- REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka1, priv1, "KDF2(SHA-256)", 0));
+ REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka1, loaded_privkey1, "KDF2(SHA-256)", 0));
botan_pk_op_ka_t ka2;
REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka2, priv2, "KDF2(SHA-256)", 0));
@@ -1333,13 +1349,17 @@ class FFI_Unit_Tests : public Test
result.test_eq("shared ECDH key", key1, key2);
+ TEST_FFI_OK(botan_mp_destroy, (private_scalar));
+ TEST_FFI_OK(botan_mp_destroy, (public_x));
+ TEST_FFI_OK(botan_mp_destroy, (public_y));
TEST_FFI_OK(botan_pk_op_key_agreement_destroy, (ka1));
TEST_FFI_OK(botan_pk_op_key_agreement_destroy, (ka2));
TEST_FFI_OK(botan_privkey_destroy, (priv1));
TEST_FFI_OK(botan_privkey_destroy, (priv2));
TEST_FFI_OK(botan_pubkey_destroy, (pub1));
TEST_FFI_OK(botan_pubkey_destroy, (pub2));
-
+ TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey1));
+ TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey1));
return result;
}