diff options
author | Adam Langley <agl@chromium.org> | 2014-06-20 23:00:00 +0400 |
---|---|---|
committer | Adam Langley <agl@chromium.org> | 2014-06-21 00:17:32 +0400 |
commit | 95c29f3cd1f6c08c6c0927868683392eea727ccb (patch) | |
tree | 012767320ced9abca61472a4daa4c4a56b7ebe2b /crypto/engine |
Inital import.
Initial fork from f2d678e6e89b6508147086610e985d4e8416e867 (1.0.2 beta).
(This change contains substantial changes from the original and
effectively starts a new history.)
Diffstat (limited to 'crypto/engine')
-rw-r--r-- | crypto/engine/CMakeLists.txt | 9 | ||||
-rw-r--r-- | crypto/engine/engine.c | 133 | ||||
-rw-r--r-- | crypto/engine/engine.h | 100 |
3 files changed, 242 insertions, 0 deletions
diff --git a/crypto/engine/CMakeLists.txt b/crypto/engine/CMakeLists.txt new file mode 100644 index 00000000..5126e2a9 --- /dev/null +++ b/crypto/engine/CMakeLists.txt @@ -0,0 +1,9 @@ +include_directories(. .. ../../include) + +add_library( + engine + + OBJECT + + engine.c +) diff --git a/crypto/engine/engine.c b/crypto/engine/engine.c new file mode 100644 index 00000000..bb0886e2 --- /dev/null +++ b/crypto/engine/engine.c @@ -0,0 +1,133 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <openssl/engine.h> + +#include <openssl/dh.h> +#include <openssl/dsa.h> +#include <openssl/ec_key.h> +#include <openssl/mem.h> +#include <openssl/rsa.h> +#include <openssl/thread.h> + + +struct engine_st { + DH_METHOD *dh_method; + DSA_METHOD *dsa_method; + RSA_METHOD *rsa_method; + ECDSA_METHOD *ecdsa_method; +}; + +ENGINE *ENGINE_new() { + ENGINE *engine = OPENSSL_malloc(sizeof(ENGINE)); + if (engine == NULL) { + return NULL; + } + + memset(engine, 0, sizeof(ENGINE)); + return engine; +} + +void ENGINE_free(ENGINE *engine) { + if (engine->dh_method != NULL) { + METHOD_unref(engine->dh_method); + } + + OPENSSL_free(engine); +} + +/* set_method takes a pointer to a method and its given size and sets + * |*out_member| to point to a copy of it. The copy is |compiled_size| bytes + * long and has zero padding if needed. */ +static int set_method(void **out_member, const void *method, size_t method_size, + size_t compiled_size) { + void *copy = OPENSSL_malloc(compiled_size); + if (copy == NULL) { + return 0; + } + + memset(copy, 0, compiled_size); + + if (method_size > compiled_size) { + method_size = compiled_size; + } + memcpy(copy, method, method_size); + + METHOD_unref(*out_member); + *out_member = copy; + + return 1; +} + +int ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->dh_method, method, method_size, + sizeof(DH_METHOD)); +} + +DH_METHOD *ENGINE_get_DH_method(const ENGINE *engine) { + return engine->dh_method; +} + +int ENGINE_set_DSA_method(ENGINE *engine, const DSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->dsa_method, method, method_size, + sizeof(DSA_METHOD)); +} + +DSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine) { + return engine->dsa_method; +} + +int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->rsa_method, method, method_size, + sizeof(RSA_METHOD)); +} + +RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine) { + return engine->rsa_method; +} + +int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->ecdsa_method, method, method_size, + sizeof(ECDSA_METHOD)); +} + +ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine) { + return engine->ecdsa_method; +} + +void METHOD_ref(void *method_in) { + struct openssl_method_common_st *method = method_in; + + if (method->is_static) { + return; + } + + CRYPTO_add(&method->references, 1, CRYPTO_LOCK_ENGINE); +} + +void METHOD_unref(void *method_in) { + struct openssl_method_common_st *method = method_in; + + if (method == NULL || method->is_static) { + return; + } + + if (CRYPTO_add(&method->references, -1, CRYPTO_LOCK_ENGINE) == 0) { + OPENSSL_free(method); + } +} diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h new file mode 100644 index 00000000..c97196e8 --- /dev/null +++ b/crypto/engine/engine.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_ENGINE_H +#define OPENSSL_HEADER_ENGINE_H + +#include <openssl/base.h> + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* Engines are collections of methods. Methods are tables of function pointers, + * defined for certain algorithms, that allow operations on those algorithms to + * be overridden via a callback. This can be used, for example, to implement an + * RSA* that forwards operations to a hardware module. + * + * Methods are reference counted but |ENGINE|s are not. When creating a method, + * you should zero the whole structure and fill in the function pointers that + * you wish before setting it on an |ENGINE|. Any functions pointers that + * are NULL indicate that the default behaviour should be used. */ + + +/* Allocation and destruction. */ + +/* ENGINE_new returns an empty ENGINE that uses the default method for all + * algorithms. */ +ENGINE *ENGINE_new(); + +/* ENGINE_free decrements the reference counts for all methods linked from + * |engine| and frees |engine| itself. */ +void ENGINE_free(ENGINE *engine); + + +/* Method accessors. + * + * Method accessors take a method pointer and the size of the structure. The + * size allows for ABI compatibility in the case that the method structure is + * extended with extra elements at the end. Methods are always copied by the + * set functions. + * + * Set functions return one on success and zero on allocation failure. */ + +int ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method, + size_t method_size); +DH_METHOD *ENGINE_get_DH_method(const ENGINE *engine); + +int ENGINE_set_DSA_method(ENGINE *engine, const DSA_METHOD *method, + size_t method_size); +DSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine); + +int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method, + size_t method_size); +RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine); + +int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method, + size_t method_size); +ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine); + + +/* Generic method functions. + * + * These functions take a void* type but actually operate on all method + * structures. */ + +/* METHOD_ref increments the reference count of |method|. */ +void METHOD_ref(void *method); + +/* METHOD_unref decrements the reference count of |method| and frees it if the + * reference count drops to zero. */ +void METHOD_unref(void *method); + + +/* Private functions. */ + +/* openssl_method_common_st contains the common part of all method structures. + * This must be the first member of all method structures. */ +struct openssl_method_common_st { + int references; + char is_static; +}; + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_ENGINE_H */ |