aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/ffi/ffi.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-04-02 16:01:40 -0400
committerJack Lloyd <[email protected]>2017-04-02 16:01:40 -0400
commitafbf3dc9e0e1169dce42a72275d95128c6d4e4da (patch)
tree987b3a5be31eb25b5e80d5d49e34b00b47729550 /src/lib/ffi/ffi.cpp
parentf6723299eb3a05b0e3482ed88650680a43be1cd8 (diff)
Add generic getters for PK parameters in C interface
Supporting RSA, DSA, and ECC. Add also DSA specific loading functions.
Diffstat (limited to 'src/lib/ffi/ffi.cpp')
-rw-r--r--src/lib/ffi/ffi.cpp301
1 files changed, 226 insertions, 75 deletions
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 8eb984c55..f067db75b 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -32,10 +32,22 @@
#include <botan/rsa.h>
#endif
+#if defined(BOTAN_HAS_DSA)
+ #include <botan/dsa.h>
+#endif
+
#if defined(BOTAN_HAS_ECDSA)
#include <botan/ecdsa.h>
#endif
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+ #include <botan/ecc_key.h>
+#endif
+
+#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
+ #include <botan/dl_algo.h>
+#endif
+
#if defined(BOTAN_HAS_ECDH)
#include <botan/ecdh.h>
#endif
@@ -1184,118 +1196,257 @@ int botan_pubkey_load_rsa(botan_pubkey_t* key,
#endif
}
-int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
+int botan_privkey_load_dsa(botan_privkey_t* key,
+ botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x)
{
-#if defined(BOTAN_HAS_RSA)
- return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
- if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k))
- {
- safe_get(p) = rsa->get_p();
- }
- else
- throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_p");
- });
+ *key = nullptr;
+
+#if defined(BOTAN_HAS_DSA)
+ try
+ {
+ Botan::Null_RNG null_rng;
+ Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
+ *key = new botan_privkey_struct(new Botan::DSA_PrivateKey(null_rng, group, safe_get(x)));
+ return 0;
+ }
+ catch(std::exception& e)
+ {
+ log_exception(BOTAN_CURRENT_FUNCTION, e.what());
+ }
+ return -1;
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
}
-int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key)
+int botan_pubkey_load_dsa(botan_pubkey_t* key,
+ botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y)
{
-#if defined(BOTAN_HAS_RSA)
- return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
- if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k))
- {
- safe_get(q) = rsa->get_q();
- }
- else
- throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_q");
- });
+ *key = nullptr;
+
+#if defined(BOTAN_HAS_DSA)
+ try
+ {
+ Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
+ *key = new botan_pubkey_struct(new Botan::DSA_PublicKey(group, safe_get(y)));
+ return 0;
+ }
+ catch(std::exception& exn)
+ {
+ log_exception(BOTAN_CURRENT_FUNCTION, exn.what());
+ }
+
+ return -1;
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
}
-int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key)
+namespace {
+
+Botan::BigInt botan_pubkey_do_get_field(const Botan::Public_Key& key,
+ const std::string& field)
{
+ // Maybe this should be `return key.get_integer_field(field_name)`?
+
#if defined(BOTAN_HAS_RSA)
- return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
- if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k))
- {
- safe_get(n) = rsa->get_n();
- }
+ if(const Botan::RSA_PublicKey* rsa = dynamic_cast<const Botan::RSA_PublicKey*>(&key))
+ {
+ if(field == "n")
+ return rsa->get_n();
+ else if(field == "e")
+ return rsa->get_e();
else
- throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_n");
- });
-#else
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+ throw Botan::Exception("Field not supported");
+ }
+#endif
+
+#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
+ // Handles DSA, ElGamal, etc
+ if(const Botan::DL_Scheme_PublicKey* dl = dynamic_cast<const Botan::DL_Scheme_PublicKey*>(&key))
+ {
+ if(field == "p")
+ return dl->group_p();
+ else if(field == "q")
+ return dl->group_q();
+ else if(field == "g")
+ return dl->group_g();
+ else if(field == "y")
+ return dl->get_y();
+ else
+ throw Botan::Exception("Field not supported");
+ }
#endif
+
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+ if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key))
+ {
+ if(field == "public_x")
+ return ecc->public_point().get_affine_x();
+ else if(field == "public_y")
+ return ecc->public_point().get_affine_y();
+ else if(field == "base_x")
+ return ecc->domain().get_base_point().get_affine_x();
+ else if(field == "base_y")
+ return ecc->domain().get_base_point().get_affine_y();
+ else if(field == "p")
+ return ecc->domain().get_curve().get_p();
+ else if(field == "a")
+ return ecc->domain().get_curve().get_a();
+ else if(field == "b")
+ return ecc->domain().get_curve().get_b();
+ else if(field == "cofactor")
+ return ecc->domain().get_cofactor();
+ else if(field == "order")
+ return ecc->domain().get_order();
+ else
+ throw Botan::Exception("Field not supported");
+ }
+#endif
+
+ // Some other algorithm type not supported by this function
+ throw Botan::Exception("Unsupported algorithm type for botan_pubkey_get_field");
}
-int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
+Botan::BigInt botan_privkey_do_get_field(const Botan::Private_Key& key,
+ const std::string& field)
{
+ //return key.get_integer_field(field);
+
#if defined(BOTAN_HAS_RSA)
- return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
- if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k))
- {
- safe_get(e) = rsa->get_e();
- }
+
+ if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&key))
+ {
+ if(field == "p")
+ return rsa->get_p();
+ else if(field == "q")
+ return rsa->get_q();
+ else if(field == "d")
+ return rsa->get_d();
+ else if(field == "c")
+ return rsa->get_c();
+ else if(field == "d1")
+ return rsa->get_d1();
+ else if(field == "d2")
+ return rsa->get_d2();
else
- throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_e");
- });
-#else
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+ return botan_pubkey_do_get_field(key, field);
+ }
#endif
+
+#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
+ // Handles DSA, ElGamal, etc
+ if(const Botan::DL_Scheme_PrivateKey* dl = dynamic_cast<const Botan::DL_Scheme_PrivateKey*>(&key))
+ {
+ if(field == "x")
+ return dl->get_x();
+ else
+ return botan_pubkey_do_get_field(key, field);
+ }
+#endif
+
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+ if(const Botan::EC_PrivateKey* ecc = dynamic_cast<const Botan::EC_PrivateKey*>(&key))
+ {
+ if(field == "x")
+ return ecc->private_value();
+ else
+ return botan_pubkey_do_get_field(key, field);
+ }
+#endif
+
+ // Some other algorithm type not supported by this function
+ throw Botan::Exception("Unsupported algorithm type for botan_privkey_get_field");
}
-int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key)
+}
+
+int botan_pubkey_get_field(botan_mp_t output,
+ botan_pubkey_t key,
+ const char* field_name_cstr)
{
-#if defined(BOTAN_HAS_RSA)
+ if(field_name_cstr == NULL)
+ return BOTAN_FFI_ERROR_NULL_POINTER;
+
+ const std::string field_name(field_name_cstr);
+
+ return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
+ safe_get(output) = botan_pubkey_do_get_field(k, field_name);
+ });
+ }
+
+int botan_privkey_get_field(botan_mp_t output,
+ botan_privkey_t key,
+ const char* field_name_cstr)
+ {
+ if(field_name_cstr == NULL)
+ return BOTAN_FFI_ERROR_NULL_POINTER;
+
+ const std::string field_name(field_name_cstr);
+
return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
- if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k))
- {
- safe_get(d) = rsa->get_e();
- }
- else
- throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_d");
+ safe_get(output) = botan_privkey_do_get_field(k, field_name);
});
-#else
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
-#endif
+ }
+
+int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
+ {
+ return botan_privkey_get_field(p, key, "p");
+ }
+
+int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key)
+ {
+ return botan_privkey_get_field(q, key, "q");
+ }
+
+int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key)
+ {
+ return botan_privkey_get_field(n, key, "n");
+ }
+
+int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
+ {
+ return botan_privkey_get_field(e, key, "e");
+ }
+
+int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key)
+ {
+ return botan_privkey_get_field(d, key, "d");
}
int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key)
{
-#if defined(BOTAN_HAS_RSA)
- return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
- if(const Botan::RSA_PublicKey* rsa = dynamic_cast<Botan::RSA_PublicKey*>(&k))
- {
- safe_get(e) = rsa->get_e();
- }
- else
- throw FFI_Error("Passed non-RSA key to botan_pubkey_rsa_get_e");
- });
-#else
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
-#endif
+ return botan_pubkey_get_field(e, key, "e");
}
int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key)
{
-#if defined(BOTAN_HAS_RSA)
- return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
- if(const Botan::RSA_PublicKey* rsa = dynamic_cast<Botan::RSA_PublicKey*>(&k))
- {
- safe_get(n) = rsa->get_n();
- }
- else
- throw FFI_Error("Passed non-RSA key to botan_pubkey_rsa_get_n");
- });
-#else
- return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
-#endif
+ return botan_pubkey_get_field(n, key, "n");
}
+int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key)
+ {
+ return botan_privkey_get_field(x, key, "x");
+ }
+
+int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key)
+ {
+ return botan_pubkey_get_field(p, key, "p");
+ }
+int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key)
+ {
+ return botan_pubkey_get_field(q, key, "q");
+ }
+int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key)
+ {
+ return botan_pubkey_get_field(g, key, "g");
+ }
+int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
+ {
+ return botan_pubkey_get_field(y, key, "y");
+ }
+
+
int botan_privkey_destroy(botan_privkey_t key)
{
delete key;