aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/crypto/c_src/otp_test_engine.c89
1 files changed, 87 insertions, 2 deletions
diff --git a/lib/crypto/c_src/otp_test_engine.c b/lib/crypto/c_src/otp_test_engine.c
index 414e89c0f6..a66bee2ddf 100644
--- a/lib/crypto/c_src/otp_test_engine.c
+++ b/lib/crypto/c_src/otp_test_engine.c
@@ -26,6 +26,8 @@
#include <openssl/engine.h>
#include <openssl/md5.h>
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
#define PACKED_OPENSSL_VERSION(MAJ, MIN, FIX, P) \
((((((((MAJ << 8) | MIN) << 8 ) | FIX) << 8) | (P-'a'+1)) << 4) | 0xf)
@@ -41,8 +43,16 @@
static const char *test_engine_id = "MD5";
static const char *test_engine_name = "MD5 test engine";
+/* The callback that does the job of fetching keys on demand by the Engine */
+EVP_PKEY* test_key_load(ENGINE *er, const char *id, UI_METHOD *ui_method, void *callback_data);
+
+
static int test_init(ENGINE *e) {
printf("OTP Test Engine Initializatzion!\r\n");
+
+ /* Load all digest and cipher algorithms. Needed for password protected private keys */
+ OpenSSL_add_all_algorithms();
+
return 111;
}
@@ -156,6 +166,7 @@ static int test_engine_digest_selector(ENGINE *e, const EVP_MD **digest,
ok = 0;
*digest = NULL;
}
+
return ok;
}
@@ -165,8 +176,11 @@ static int bind_helper(ENGINE * e, const char *id)
if (!ENGINE_set_id(e, test_engine_id) ||
!ENGINE_set_name(e, test_engine_name) ||
!ENGINE_set_init_function(e, test_init) ||
- !ENGINE_set_digests(e, &test_engine_digest_selector)
- )
+ !ENGINE_set_digests(e, &test_engine_digest_selector) ||
+ /* For testing of key storage in an Engine: */
+ !ENGINE_set_load_privkey_function(e, &test_key_load) ||
+ !ENGINE_set_load_pubkey_function(e, &test_key_load)
+ )
return 0;
return 1;
@@ -175,3 +189,74 @@ static int bind_helper(ENGINE * e, const char *id)
IMPLEMENT_DYNAMIC_CHECK_FN();
IMPLEMENT_DYNAMIC_BIND_FN(bind_helper);
+
+/********************************************************
+ *
+ * Engine storage simulation
+ *
+ */
+int pem_passwd_cb_fun(char *buf, int size, int rwflag, void *password);
+
+EVP_PKEY* test_key_load(ENGINE *er, const char *id, UI_METHOD *ui_method, void *callback_data)
+{
+ EVP_PKEY *pkey = NULL;
+ FILE *f = fopen(id, "r");
+
+ if (!f) {
+ fprintf(stderr, "%s:%d fopen(%s) failed\r\n", __FILE__,__LINE__,id);
+ return NULL;
+ }
+
+ /* First try to read as a private key. If that fails, try to read as a public key: */
+ pkey = PEM_read_PrivateKey(f, NULL, pem_passwd_cb_fun, callback_data);
+ if (!pkey) {
+ /* ERR_print_errors_fp (stderr); */
+ fclose(f);
+ f = fopen(id, "r");
+ pkey = PEM_read_PUBKEY(f, NULL, NULL, NULL);
+ }
+ fclose(f);
+
+ if (!pkey) {
+ fprintf(stderr, "%s:%d Key read from file failed. ", __FILE__,__LINE__);
+ if (callback_data)
+ fprintf(stderr, "Pwd = \"%s\". ", (char *)callback_data);
+ fprintf(stderr, "Contents of file \"%s\":\r\n",id);
+ f = fopen(id, "r");
+ { /* Print the contents of the key file */
+ char c;
+ while (!feof(f)) {
+ switch (c=fgetc(f)) {
+ case '\n':
+ case '\r': putc('\r',stdout); putc('\n',stdout); break;
+ default: putc(c, stdout);
+ }
+ }
+ }
+ fclose(f);
+ }
+
+ return pkey;
+}
+
+
+int pem_passwd_cb_fun(char *buf, int size, int rwflag, void *password)
+{
+ int i;
+
+ fprintf(stderr, "In pem_passwd_cb_fun\r\n");
+ if (!password)
+ return 0;
+
+ i = strlen(password);
+ if (i < size) {
+ /* whole pwd (incl terminating 0) fits */
+ fprintf(stderr, "Got FULL pwd %d(%d) chars\r\n", i, size);
+ memcpy(buf, (char*)password, i+1);
+ return i+1;
+ } else {
+ fprintf(stderr, "Got TO LONG pwd %d(%d) chars\r\n", i, size);
+ /* meaningless with a truncated password */
+ return 0;
+ }
+}