blob: 5b8cf1c5d7bf5bb1137536733bc8e57760590142 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <openssl/engine.h>
16
Adam Langley2b2d66d2015-01-30 17:08:37 -080017#include <string.h>
18
Adam Langley95c29f32014-06-20 12:00:00 -070019#include <openssl/dh.h>
20#include <openssl/dsa.h>
21#include <openssl/ec_key.h>
Adam Langley7ea84812014-10-09 16:26:09 -070022#include <openssl/err.h>
Adam Langley95c29f32014-06-20 12:00:00 -070023#include <openssl/mem.h>
24#include <openssl/rsa.h>
25#include <openssl/thread.h>
26
27
28struct engine_st {
29 DH_METHOD *dh_method;
30 DSA_METHOD *dsa_method;
31 RSA_METHOD *rsa_method;
32 ECDSA_METHOD *ecdsa_method;
33};
34
David Benjaminc44d2f42014-08-20 16:24:00 -040035ENGINE *ENGINE_new(void) {
Adam Langley95c29f32014-06-20 12:00:00 -070036 ENGINE *engine = OPENSSL_malloc(sizeof(ENGINE));
37 if (engine == NULL) {
38 return NULL;
39 }
40
41 memset(engine, 0, sizeof(ENGINE));
42 return engine;
43}
44
45void ENGINE_free(ENGINE *engine) {
46 if (engine->dh_method != NULL) {
47 METHOD_unref(engine->dh_method);
48 }
49
50 OPENSSL_free(engine);
51}
52
53/* set_method takes a pointer to a method and its given size and sets
54 * |*out_member| to point to a copy of it. The copy is |compiled_size| bytes
55 * long and has zero padding if needed. */
56static int set_method(void **out_member, const void *method, size_t method_size,
57 size_t compiled_size) {
58 void *copy = OPENSSL_malloc(compiled_size);
59 if (copy == NULL) {
60 return 0;
61 }
62
63 memset(copy, 0, compiled_size);
64
65 if (method_size > compiled_size) {
66 method_size = compiled_size;
67 }
68 memcpy(copy, method, method_size);
69
70 METHOD_unref(*out_member);
71 *out_member = copy;
72
73 return 1;
74}
75
76int ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method,
77 size_t method_size) {
78 return set_method((void **)&engine->dh_method, method, method_size,
79 sizeof(DH_METHOD));
80}
81
82DH_METHOD *ENGINE_get_DH_method(const ENGINE *engine) {
83 return engine->dh_method;
84}
85
86int ENGINE_set_DSA_method(ENGINE *engine, const DSA_METHOD *method,
87 size_t method_size) {
88 return set_method((void **)&engine->dsa_method, method, method_size,
89 sizeof(DSA_METHOD));
90}
91
92DSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine) {
93 return engine->dsa_method;
94}
95
96int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method,
97 size_t method_size) {
98 return set_method((void **)&engine->rsa_method, method, method_size,
99 sizeof(RSA_METHOD));
100}
101
102RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine) {
103 return engine->rsa_method;
104}
105
106int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method,
107 size_t method_size) {
108 return set_method((void **)&engine->ecdsa_method, method, method_size,
109 sizeof(ECDSA_METHOD));
110}
111
112ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine) {
113 return engine->ecdsa_method;
114}
115
116void METHOD_ref(void *method_in) {
117 struct openssl_method_common_st *method = method_in;
118
119 if (method->is_static) {
120 return;
121 }
122
123 CRYPTO_add(&method->references, 1, CRYPTO_LOCK_ENGINE);
124}
125
126void METHOD_unref(void *method_in) {
127 struct openssl_method_common_st *method = method_in;
128
129 if (method == NULL || method->is_static) {
130 return;
131 }
132
133 if (CRYPTO_add(&method->references, -1, CRYPTO_LOCK_ENGINE) == 0) {
134 OPENSSL_free(method);
135 }
136}
Adam Langley7ea84812014-10-09 16:26:09 -0700137
138OPENSSL_DECLARE_ERROR_REASON(ENGINE, OPERATION_NOT_SUPPORTED);