* Hudson (tjh@cryptsoft.com).
*
*/
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/engine.h>
#include <openssl/dso.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
/* This testing gunk is implemented (and explained) lower down. It also assumes
* the application explicitly calls "ENGINE_load_openssl()" because this is no
* longer automatic in ENGINE_load_builtin_engines(). */
#define TEST_ENG_OPENSSL_RC4
-/* #define TEST_ENC_OPENSSL_RC4_FALLBACK */
+#define TEST_ENG_OPENSSL_PKEY
/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
#define TEST_ENG_OPENSSL_RC4_P_INIT
/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
#define TEST_ENG_OPENSSL_SHA
-/* #define TEST_ENG_OPENSSL_SHA_FALLBACK */
/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
+/* Now check what of those algorithms are actually enabled */
+#ifdef OPENSSL_NO_RC4
+#undef TEST_ENG_OPENSSL_RC4
+#undef TEST_ENG_OPENSSL_RC4_OTHERS
+#undef TEST_ENG_OPENSSL_RC4_P_INIT
+#undef TEST_ENG_OPENSSL_RC4_P_CIPHER
+#endif
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1)
+#undef TEST_ENG_OPENSSL_SHA
+#undef TEST_ENG_OPENSSL_SHA_OTHERS
+#undef TEST_ENG_OPENSSL_SHA_P_INIT
+#undef TEST_ENG_OPENSSL_SHA_P_UPDATE
+#undef TEST_ENG_OPENSSL_SHA_P_FINAL
+#endif
+
#ifdef TEST_ENG_OPENSSL_RC4
static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid);
const int **nids, int nid);
#endif
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+#endif
+
/* The constants used when creating the ENGINE */
static const char *engine_openssl_id = "openssl";
static const char *engine_openssl_name = "Software engine support";
-static ENGINE *engine_openssl(void)
+/* This internal function is used by ENGINE_openssl() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
{
- ENGINE *ret = ENGINE_new();
- if(!ret)
- return NULL;
- if(!ENGINE_set_id(ret, engine_openssl_id)
- || !ENGINE_set_name(ret, engine_openssl_name)
+ if(!ENGINE_set_id(e, engine_openssl_id)
+ || !ENGINE_set_name(e, engine_openssl_name)
+#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
#ifndef OPENSSL_NO_RSA
- || !ENGINE_set_RSA(ret, RSA_get_default_method())
+ || !ENGINE_set_RSA(e, RSA_get_default_method())
#endif
#ifndef OPENSSL_NO_DSA
- || !ENGINE_set_DSA(ret, DSA_get_default_method())
+ || !ENGINE_set_DSA(e, DSA_get_default_method())
+#endif
+#ifndef OPENSSL_NO_ECDH
+ || !ENGINE_set_ECDH(e, ECDH_OpenSSL())
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
#endif
#ifndef OPENSSL_NO_DH
- || !ENGINE_set_DH(ret, DH_get_default_method())
+ || !ENGINE_set_DH(e, DH_get_default_method())
#endif
- || !ENGINE_set_RAND(ret, RAND_SSLeay())
+ || !ENGINE_set_RAND(e, RAND_SSLeay())
#ifdef TEST_ENG_OPENSSL_RC4
- || !ENGINE_set_ciphers(ret, openssl_ciphers)
+ || !ENGINE_set_ciphers(e, openssl_ciphers)
#endif
#ifdef TEST_ENG_OPENSSL_SHA
- || !ENGINE_set_digests(ret, openssl_digests)
+ || !ENGINE_set_digests(e, openssl_digests)
+#endif
+#endif
+#ifdef TEST_ENG_OPENSSL_PKEY
+ || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
#endif
)
+ return 0;
+ /* If we add errors to this ENGINE, ensure the error handling is setup here */
+ /* openssl_load_error_strings(); */
+ return 1;
+ }
+
+static ENGINE *engine_openssl(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
{
ENGINE_free(ret);
return NULL;
ERR_clear_error();
}
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_openssl_id) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* ENGINE_DYNAMIC_SUPPORT */
+
#ifdef TEST_ENG_OPENSSL_RC4
/* This section of code compiles an "alternative implementation" of two modes of
* RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
* should under normal circumstances go via this support rather than the default
* EVP support. There are other symbols to tweak the testing;
- * TEST_ENC_OPENSSL_RC4_FALLBACK - declare support for "-1" so that all
- * uncached cipher lookups check with this ENGINE (ie. it'll get asked
- * about other ciphers, but hopefully not more than once for each nid).
* TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
- * we're asked for a cipher we don't support (should only happen in
- * combination with the "FALLBACK" case).
+ * we're asked for a cipher we don't support (should not happen).
* TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
* the "init_key" handler is called.
* TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
*/
-#include <openssl/evp.h>
#include <openssl/rc4.h>
#define TEST_RC4_KEY_SIZE 16
-#ifdef TEST_ENC_OPENSSL_RC4_FALLBACK
-static int test_cipher_nids[] = {-1};
-static int test_cipher_nids_number = 1;
-#else
static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
static int test_cipher_nids_number = 2;
-#endif
typedef struct {
unsigned char key[TEST_RC4_KEY_SIZE];
RC4_KEY ks;
return 1;
}
static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl)
+ const unsigned char *in, size_t inl)
{
#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
sizeof(TEST_RC4_KEY),
NULL,
NULL,
+ NULL,
NULL
};
static const EVP_CIPHER test_r4_40_cipher=
sizeof(TEST_RC4_KEY),
NULL,
NULL,
+ NULL,
NULL
};
static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
#ifdef TEST_ENG_OPENSSL_SHA
/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
-#include <openssl/evp.h>
#include <openssl/sha.h>
-#ifdef TEST_ENC_OPENSSL_SHA_FALLBACK
-static int test_digest_nids[] = {-1};
-static int test_digest_nids_number = 1;
-#else
static int test_digest_nids[] = {NID_sha1};
static int test_digest_nids_number = 1;
-#endif
static int test_sha1_init(EVP_MD_CTX *ctx)
{
#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
#endif
return SHA1_Init(ctx->md_data);
}
-static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
{
#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
return 1;
}
#endif
+
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data)
+ {
+ BIO *in;
+ EVP_PKEY *key;
+ fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
+ in = BIO_new_file(key_id, "r");
+ if (!in)
+ return NULL;
+ key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
+ BIO_free(in);
+ return key;
+ }
+#endif