diff options
Diffstat (limited to 'lib/crypto/c_src/otp_test_engine.c')
-rw-r--r-- | lib/crypto/c_src/otp_test_engine.c | 89 |
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; + } +} |