aboutsummaryrefslogtreecommitdiffstats
path: root/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp')
-rw-r--r--SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp b/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp
index cecc0ce..c7b1da3 100644
--- a/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp
+++ b/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp
@@ -47,6 +47,7 @@
#include <botan/bigint.h>
#include <botan/version.h>
#include <botan/der_enc.h>
+#include <botan/oids.h>
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
#include <botan/libstate.h>
@@ -162,6 +163,10 @@ int crypto_import_key_pair
#ifdef WITH_ECC
Botan::ECDSA_PrivateKey* ecdsa = NULL;
#endif
+#ifdef WITH_EDDSA
+ Botan::Curve25519_PrivateKey* x25519 = NULL;
+ Botan::Ed25519_PrivateKey* ed25519 = NULL;
+#endif
if (pkey->algo_name().compare("RSA") == 0)
{
@@ -177,6 +182,16 @@ int crypto_import_key_pair
ecdsa = dynamic_cast<Botan::ECDSA_PrivateKey*>(pkey);
}
#endif
+#ifdef WITH_EDDSA
+ else if (pkey->algo_name().compare("Curve25519") == 0)
+ {
+ x25519 = dynamic_cast<Botan::Curve25519_PrivateKey*>(pkey);
+ }
+ else if (pkey->algo_name().compare("Ed25519") == 0)
+ {
+ ed25519 = dynamic_cast<Botan::Ed25519_PrivateKey*>(pkey);
+ }
+#endif
else
{
fprintf(stderr, "ERROR: %s is not a supported algorithm.\n",
@@ -201,6 +216,16 @@ int crypto_import_key_pair
result = crypto_save_ecdsa(hSession, label, objID, objIDLen, noPublicKey, ecdsa);
}
#endif
+#ifdef WITH_EDDSA
+ else if (x25519)
+ {
+ result = crypto_save_eddsa(hSession, label, objID, objIDLen, noPublicKey, x25519, 0);
+ }
+ else if (ed25519)
+ {
+ result = crypto_save_eddsa(hSession, label, objID, objIDLen, noPublicKey, 0, ed25519);
+ }
+#endif
else
{
fprintf(stderr, "ERROR: Could not get the key material.\n");
@@ -702,3 +727,156 @@ void crypto_free_ecdsa(ecdsa_key_material_t* keyMat)
free(keyMat);
}
#endif
+
+#ifdef WITH_EDDSA
+// Save the key data in PKCS#11
+int crypto_save_eddsa
+(
+ CK_SESSION_HANDLE hSession,
+ char* label,
+ char* objID,
+ size_t objIDLen,
+ int noPublicKey,
+ Botan::Curve25519_PrivateKey* x25519,
+ Botan::Ed25519_PrivateKey* ed25519
+)
+{
+ eddsa_key_material_t* keyMat = crypto_malloc_eddsa(x25519, ed25519);
+ if (keyMat == NULL)
+ {
+ fprintf(stderr, "ERROR: Could not convert the key material to binary information.\n");
+ return 1;
+ }
+
+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY, privClass = CKO_PRIVATE_KEY;
+ CK_KEY_TYPE keyType = CKK_EC_EDWARDS;
+ CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE, ckToken = CK_TRUE;
+ if (noPublicKey)
+ {
+ ckToken = CK_FALSE;
+ }
+ CK_ATTRIBUTE pubTemplate[] = {
+ { CKA_CLASS, &pubClass, sizeof(pubClass) },
+ { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
+ { CKA_LABEL, label, strlen(label) },
+ { CKA_ID, objID, objIDLen },
+ { CKA_TOKEN, &ckToken, sizeof(ckToken) },
+ { CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
+ { CKA_ENCRYPT, &ckFalse, sizeof(ckFalse) },
+ { CKA_WRAP, &ckFalse, sizeof(ckFalse) },
+ { CKA_EC_PARAMS, keyMat->derOID, keyMat->sizeOID },
+ { CKA_EC_POINT, keyMat->bigA, keyMat->sizeA },
+ };
+ CK_ATTRIBUTE privTemplate[] = {
+ { CKA_CLASS, &privClass, sizeof(privClass) },
+ { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
+ { CKA_LABEL, label, strlen(label) },
+ { CKA_ID, objID, objIDLen },
+ { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
+ { CKA_DECRYPT, &ckFalse, sizeof(ckFalse) },
+ { CKA_UNWRAP, &ckFalse, sizeof(ckFalse) },
+ { CKA_SENSITIVE, &ckTrue, sizeof(ckTrue) },
+ { CKA_TOKEN, &ckTrue, sizeof(ckTrue) },
+ { CKA_PRIVATE, &ckTrue, sizeof(ckTrue) },
+ { CKA_EXTRACTABLE, &ckFalse, sizeof(ckFalse) },
+ { CKA_EC_PARAMS, keyMat->derOID, keyMat->sizeOID },
+ { CKA_VALUE, keyMat->bigK, keyMat->sizeK }
+ };
+
+ CK_OBJECT_HANDLE hKey1, hKey2;
+ CK_RV rv = p11->C_CreateObject(hSession, privTemplate, 13, &hKey1);
+ if (rv != CKR_OK)
+ {
+ fprintf(stderr, "ERROR: Could not save the private key in the token. "
+ "Maybe the algorithm is not supported.\n");
+ crypto_free_eddsa(keyMat);
+ return 1;
+ }
+
+ rv = p11->C_CreateObject(hSession, pubTemplate, 10, &hKey2);
+ crypto_free_eddsa(keyMat);
+
+ if (rv != CKR_OK)
+ {
+ p11->C_DestroyObject(hSession, hKey1);
+ fprintf(stderr, "ERROR: Could not save the public key in the token.\n");
+ return 1;
+ }
+
+ printf("The key pair has been imported.\n");
+
+ return 0;
+}
+
+// Convert the OpenSSL key to binary
+eddsa_key_material_t* crypto_malloc_eddsa
+(
+ Botan::Curve25519_PrivateKey* x25519,
+ Botan::Ed25519_PrivateKey* ed25519
+ )
+{
+ if ((x25519 == NULL) && (ed25519 == NULL))
+ {
+ return NULL;
+ }
+
+ eddsa_key_material_t* keyMat = (eddsa_key_material_t*)malloc(sizeof(eddsa_key_material_t));
+ if (keyMat == NULL)
+ {
+ return NULL;
+ }
+
+ Botan::OID oid;
+ if (x25519) oid = Botan::OIDS::lookup("Curve25519");
+ if (ed25519) oid = Botan::OIDS::lookup("Ed25519");
+ if (oid.empty())
+ {
+ return NULL;
+ }
+
+ Botan::secure_vector<Botan::byte> derOID;
+ derOID = Botan::DER_Encoder().encode(oid).get_contents();
+
+ memset(keyMat, 0, sizeof(*keyMat));
+ keyMat->sizeOID = derOID.size();
+ keyMat->derOID = (CK_VOID_PTR)malloc(keyMat->sizeOID);
+
+ std::vector<Botan::byte> pub;
+ if (x25519) pub = x25519->public_value();
+ if (ed25519) pub = ed25519->get_public_key();
+ keyMat->sizeA = pub.size();
+ keyMat->bigA = (CK_VOID_PTR)malloc(keyMat->sizeA);
+
+ Botan::secure_vector<Botan::byte> priv;
+ if (x25519) priv = x25519->get_x();
+ if (ed25519)
+ {
+ priv = ed25519->get_private_key();
+ priv.resize(32);
+ }
+ keyMat->sizeK = priv.size();
+ keyMat->bigK = (CK_VOID_PTR)malloc(keyMat->sizeK);
+
+ if (!keyMat->derOID || !keyMat->bigK || !keyMat->bigA)
+ {
+ crypto_free_eddsa(keyMat);
+ return NULL;
+ }
+
+ memcpy(keyMat->derOID, derOID.data(), keyMat->sizeOID);
+ memcpy(keyMat->bigA, pub.data(), keyMat->sizeA);
+ memcpy(keyMat->bigK, priv.data(), keyMat->sizeK);
+
+ return keyMat;
+}
+
+// Free the memory of the key
+void crypto_free_eddsa(eddsa_key_material_t* keyMat)
+{
+ if (keyMat == NULL) return;
+ if (keyMat->derOID) free(keyMat->derOID);
+ if (keyMat->bigK) free(keyMat->bigK);
+ if (keyMat->bigA) free(keyMat->bigA);
+ free(keyMat);
+}
+#endif