summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreric <>2022-01-25 21:51:24 +0000
committereric <>2022-01-25 21:51:24 +0000
commit5bc45eb57d3df492a992eb97f4f9efadef0b060c (patch)
treef7e1f8bcb82bc7a21b3720f212d7fbf3f1d02872 /src
parentc8578f33457bc1465ca08176ebca6e8aac53fcd3 (diff)
downloadopenbsd-5bc45eb57d3df492a992eb97f4f9efadef0b060c.tar.gz
openbsd-5bc45eb57d3df492a992eb97f4f9efadef0b060c.tar.bz2
openbsd-5bc45eb57d3df492a992eb97f4f9efadef0b060c.zip
Introduce a signer interface intented to make TLS privsep simpler
to implement. Add a tls_config_set_sign_cb() function that allows to register a callback for the signing operation on a tls_config. When used, the context installs fake pivate keys internally, and the callback receives the hash of the public key. Add a tls_signer_*() set of functions to manage tls_signer objects. A tls_signer is an opaque structure on which keys are added. It is used to compute signatures with private keys identified by their associated public key hash. Discussed with and ok jsing@ tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libtls/Makefile3
-rw-r--r--src/lib/libtls/Symbols.list6
-rw-r--r--src/lib/libtls/tls.c20
-rw-r--r--src/lib/libtls/tls.h18
-rw-r--r--src/lib/libtls/tls_config.c13
-rw-r--r--src/lib/libtls/tls_internal.h7
-rw-r--r--src/lib/libtls/tls_signer.c376
7 files changed, 438 insertions, 5 deletions
diff --git a/src/lib/libtls/Makefile b/src/lib/libtls/Makefile
index 23a6ed1f2a..78ff99b585 100644
--- a/src/lib/libtls/Makefile
+++ b/src/lib/libtls/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.36 2020/06/09 16:53:53 deraadt Exp $ 1# $OpenBSD: Makefile,v 1.37 2022/01/25 21:51:24 eric Exp $
2 2
3.include <bsd.own.mk> 3.include <bsd.own.mk>
4.ifndef NOMAN 4.ifndef NOMAN
@@ -35,6 +35,7 @@ SRCS= tls.c \
35 tls_keypair.c \ 35 tls_keypair.c \
36 tls_peer.c \ 36 tls_peer.c \
37 tls_server.c \ 37 tls_server.c \
38 tls_signer.c \
38 tls_util.c \ 39 tls_util.c \
39 tls_ocsp.c \ 40 tls_ocsp.c \
40 tls_verify.c 41 tls_verify.c
diff --git a/src/lib/libtls/Symbols.list b/src/lib/libtls/Symbols.list
index 42c039d294..d00e5e0ce6 100644
--- a/src/lib/libtls/Symbols.list
+++ b/src/lib/libtls/Symbols.list
@@ -43,6 +43,7 @@ tls_config_set_protocols
43tls_config_set_session_id 43tls_config_set_session_id
44tls_config_set_session_lifetime 44tls_config_set_session_lifetime
45tls_config_set_session_fd 45tls_config_set_session_fd
46tls_config_set_sign_cb
46tls_config_set_verify_depth 47tls_config_set_verify_depth
47tls_config_skip_private_key_check 48tls_config_skip_private_key_check
48tls_config_use_fake_private_key 49tls_config_use_fake_private_key
@@ -87,5 +88,10 @@ tls_peer_ocsp_url
87tls_read 88tls_read
88tls_reset 89tls_reset
89tls_server 90tls_server
91tls_signer_add_keypair_file
92tls_signer_add_keypair_mem
93tls_signer_free
94tls_signer_new
95tls_signer_sign
90tls_unload_file 96tls_unload_file
91tls_write 97tls_write
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c
index 608f0a3acd..fd525aa428 100644
--- a/src/lib/libtls/tls.c
+++ b/src/lib/libtls/tls.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.c,v 1.92 2021/10/21 14:31:21 tb Exp $ */ 1/* $OpenBSD: tls.c,v 1.93 2022/01/25 21:51:24 eric Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -387,6 +387,8 @@ tls_keypair_to_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY **pke
387static int 387static int
388tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *pkey) 388tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *pkey)
389{ 389{
390 RSA_METHOD *rsa_method;
391 ECDSA_METHOD *ecdsa_method;
390 RSA *rsa = NULL; 392 RSA *rsa = NULL;
391 EC_KEY *eckey = NULL; 393 EC_KEY *eckey = NULL;
392 int ret = -1; 394 int ret = -1;
@@ -407,6 +409,14 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
407 tls_set_errorx(ctx, "RSA key setup failure"); 409 tls_set_errorx(ctx, "RSA key setup failure");
408 goto err; 410 goto err;
409 } 411 }
412 if (ctx->config->sign_cb == NULL)
413 break;
414 if ((rsa_method = tls_signer_rsa_method()) == NULL ||
415 RSA_set_ex_data(rsa, 1, ctx->config) == 0 ||
416 RSA_set_method(rsa, rsa_method) == 0) {
417 tls_set_errorx(ctx, "failed to setup RSA key");
418 goto err;
419 }
410 break; 420 break;
411 case EVP_PKEY_EC: 421 case EVP_PKEY_EC:
412 if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL || 422 if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL ||
@@ -414,6 +424,14 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
414 tls_set_errorx(ctx, "EC key setup failure"); 424 tls_set_errorx(ctx, "EC key setup failure");
415 goto err; 425 goto err;
416 } 426 }
427 if (ctx->config->sign_cb == NULL)
428 break;
429 if ((ecdsa_method = tls_signer_ecdsa_method()) == NULL ||
430 ECDSA_set_ex_data(eckey, 1, ctx->config) == 0 ||
431 ECDSA_set_method(eckey, ecdsa_method) == 0) {
432 tls_set_errorx(ctx, "failed to setup EC key");
433 goto err;
434 }
417 break; 435 break;
418 default: 436 default:
419 tls_set_errorx(ctx, "incorrect key type"); 437 tls_set_errorx(ctx, "incorrect key type");
diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h
index 20f55dcabd..22f04f4023 100644
--- a/src/lib/libtls/tls.h
+++ b/src/lib/libtls/tls.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.h,v 1.58 2020/01/22 06:44:02 beck Exp $ */ 1/* $OpenBSD: tls.h,v 1.59 2022/01/25 21:51:24 eric Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -79,6 +79,9 @@ typedef ssize_t (*tls_read_cb)(struct tls *_ctx, void *_buf, size_t _buflen,
79 void *_cb_arg); 79 void *_cb_arg);
80typedef ssize_t (*tls_write_cb)(struct tls *_ctx, const void *_buf, 80typedef ssize_t (*tls_write_cb)(struct tls *_ctx, const void *_buf,
81 size_t _buflen, void *_cb_arg); 81 size_t _buflen, void *_cb_arg);
82typedef int (*tls_sign_cb)(void *_cb_arg, const char *_hash,
83 const uint8_t *_dgst, size_t _dgstlen, uint8_t *_psig, size_t *_psiglen,
84 int _padding);
82 85
83int tls_init(void); 86int tls_init(void);
84 87
@@ -135,6 +138,8 @@ int tls_config_set_ocsp_staple_file(struct tls_config *_config,
135int tls_config_set_protocols(struct tls_config *_config, uint32_t _protocols); 138int tls_config_set_protocols(struct tls_config *_config, uint32_t _protocols);
136int tls_config_set_session_fd(struct tls_config *_config, int _session_fd); 139int tls_config_set_session_fd(struct tls_config *_config, int _session_fd);
137int tls_config_set_verify_depth(struct tls_config *_config, int _verify_depth); 140int tls_config_set_verify_depth(struct tls_config *_config, int _verify_depth);
141int tls_config_set_sign_cb(struct tls_config *_config, tls_sign_cb _cb,
142 void *_cb_arg);
138 143
139void tls_config_prefer_ciphers_client(struct tls_config *_config); 144void tls_config_prefer_ciphers_client(struct tls_config *_config);
140void tls_config_prefer_ciphers_server(struct tls_config *_config); 145void tls_config_prefer_ciphers_server(struct tls_config *_config);
@@ -212,6 +217,17 @@ time_t tls_peer_ocsp_revocation_time(struct tls *_ctx);
212time_t tls_peer_ocsp_this_update(struct tls *_ctx); 217time_t tls_peer_ocsp_this_update(struct tls *_ctx);
213const char *tls_peer_ocsp_url(struct tls *_ctx); 218const char *tls_peer_ocsp_url(struct tls *_ctx);
214 219
220struct tls_signer* tls_signer_new(void);
221void tls_signer_free(struct tls_signer * _signer);
222const char *tls_signer_error(struct tls_signer * _signer);
223int tls_signer_add_keypair_file(struct tls_signer *_signer,
224 const char *_cert_file, const char *_key_file);
225int tls_signer_add_keypair_mem(struct tls_signer *_signer, const uint8_t *_cert,
226 size_t _cert_len, const uint8_t *_key, size_t _key_len);
227int tls_signer_sign(struct tls_signer *_signer, const char *_hash,
228 const uint8_t *_dgst, size_t _dgstlen, uint8_t **_psig, size_t *_psiglen,
229 int _padding);
230
215#ifdef __cplusplus 231#ifdef __cplusplus
216} 232}
217#endif 233#endif
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c
index 4ca497a032..15e218b4e0 100644
--- a/src/lib/libtls/tls_config.c
+++ b/src/lib/libtls/tls_config.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_config.c,v 1.64 2021/10/21 08:33:07 tb Exp $ */ 1/* $OpenBSD: tls_config.c,v 1.65 2022/01/25 21:51:24 eric Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -738,6 +738,17 @@ tls_config_set_session_fd(struct tls_config *config, int session_fd)
738} 738}
739 739
740int 740int
741tls_config_set_sign_cb(struct tls_config *config, tls_sign_cb cb, void *cb_arg)
742{
743 config->use_fake_private_key = 1;
744 config->skip_private_key_check = 1;
745 config->sign_cb = cb;
746 config->sign_cb_arg = cb_arg;
747
748 return (0);
749}
750
751int
741tls_config_set_verify_depth(struct tls_config *config, int verify_depth) 752tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
742{ 753{
743 config->verify_depth = verify_depth; 754 config->verify_depth = verify_depth;
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h
index 5487b123ec..bc5044518b 100644
--- a/src/lib/libtls/tls_internal.h
+++ b/src/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_internal.h,v 1.78 2021/01/21 19:09:10 eric Exp $ */ 1/* $OpenBSD: tls_internal.h,v 1.79 2022/01/25 21:51:24 eric Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> 3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -112,6 +112,8 @@ struct tls_config {
112 int verify_time; 112 int verify_time;
113 int skip_private_key_check; 113 int skip_private_key_check;
114 int use_fake_private_key; 114 int use_fake_private_key;
115 tls_sign_cb sign_cb;
116 void *sign_cb_arg;
115}; 117};
116 118
117struct tls_conninfo { 119struct tls_conninfo {
@@ -291,6 +293,9 @@ int tls_cert_pubkey_hash(X509 *_cert, char **_hash);
291 293
292int tls_password_cb(char *_buf, int _size, int _rwflag, void *_u); 294int tls_password_cb(char *_buf, int _size, int _rwflag, void *_u);
293 295
296RSA_METHOD *tls_signer_rsa_method(void);
297ECDSA_METHOD *tls_signer_ecdsa_method(void);
298
294__END_HIDDEN_DECLS 299__END_HIDDEN_DECLS
295 300
296/* XXX this function is not fully hidden so relayd can use it */ 301/* XXX this function is not fully hidden so relayd can use it */
diff --git a/src/lib/libtls/tls_signer.c b/src/lib/libtls/tls_signer.c
new file mode 100644
index 0000000000..690cb51615
--- /dev/null
+++ b/src/lib/libtls/tls_signer.c
@@ -0,0 +1,376 @@
1/* $OpenBSD: tls_signer.c,v 1.1 2022/01/25 21:51:24 eric Exp $ */
2/*
3 * Copyright (c) 2021 Eric Faurot <eric@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <openssl/err.h>
19
20#include "tls.h"
21#include "tls_internal.h"
22
23struct tls_signer_key {
24 char *hash;
25 RSA *rsa;
26 EC_KEY *ecdsa;
27 struct tls_signer_key *next;
28};
29
30struct tls_signer {
31 struct tls_error error;
32 struct tls_signer_key *keys;
33};
34
35static pthread_mutex_t signer_method_lock = PTHREAD_MUTEX_INITIALIZER;
36
37struct tls_signer *
38tls_signer_new(void)
39{
40 struct tls_signer *signer;
41
42 if ((signer = calloc(1, sizeof(*signer))) == NULL)
43 return (NULL);
44
45 return (signer);
46}
47
48void
49tls_signer_free(struct tls_signer *signer)
50{
51 struct tls_signer_key *skey;
52
53 if (signer == NULL)
54 return;
55
56 tls_error_clear(&signer->error);
57
58 while (signer->keys) {
59 skey = signer->keys;
60 signer->keys = skey->next;
61 RSA_free(skey->rsa);
62 EC_KEY_free(skey->ecdsa);
63 free(skey->hash);
64 free(skey);
65 }
66
67 free(signer);
68}
69
70const char *
71tls_signer_error(struct tls_signer *signer)
72{
73 return (signer->error.msg);
74}
75
76int
77tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert,
78 size_t cert_len, const uint8_t *key, size_t key_len)
79{
80 struct tls_signer_key *skey = NULL;
81 char *errstr = "unknown";
82 int ssl_err;
83 EVP_PKEY *pkey = NULL;
84 X509 *x509 = NULL;
85 BIO *bio = NULL;
86 char *hash = NULL;
87
88 /* Compute certificate hash */
89 if ((bio = BIO_new_mem_buf(cert, cert_len)) == NULL) {
90 tls_error_setx(&signer->error,
91 "failed to create certificate bio");
92 goto err;
93 }
94 if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb,
95 NULL)) == NULL) {
96 if ((ssl_err = ERR_peek_error()) != 0)
97 errstr = ERR_error_string(ssl_err, NULL);
98 tls_error_setx(&signer->error, "failed to load certificate: %s",
99 errstr);
100 goto err;
101 }
102 if (tls_cert_pubkey_hash(x509, &hash) == -1) {
103 tls_error_setx(&signer->error,
104 "failed to get certificate hash");
105 goto err;
106 }
107
108 X509_free(x509);
109 x509 = NULL;
110 BIO_free(bio);
111 bio = NULL;
112
113 /* Read private key */
114 if ((bio = BIO_new_mem_buf(key, key_len)) == NULL) {
115 tls_error_setx(&signer->error, "failed to create key bio");
116 goto err;
117 }
118 if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
119 NULL)) == NULL) {
120 tls_error_setx(&signer->error, "failed to read private key");
121 goto err;
122 }
123
124 if ((skey = calloc(1, sizeof(*skey))) == NULL) {
125 tls_error_set(&signer->error, "failed to create key entry");
126 goto err;
127 }
128 skey->hash = hash;
129 if ((skey->rsa = EVP_PKEY_get1_RSA(pkey)) == NULL &&
130 (skey->ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
131 tls_error_setx(&signer->error, "unknown key type");
132 goto err;
133 }
134
135 skey->next = signer->keys;
136 signer->keys = skey;
137 EVP_PKEY_free(pkey);
138 BIO_free(bio);
139
140 return (0);
141
142 err:
143 EVP_PKEY_free(pkey);
144 X509_free(x509);
145 BIO_free(bio);
146 free(hash);
147 free(skey);
148
149 return (-1);
150}
151
152int
153tls_signer_add_keypair_file(struct tls_signer *signer, const char *cert_file,
154 const char *key_file)
155{
156 char *cert = NULL, *key = NULL;
157 size_t cert_len, key_len;
158 int rv = -1;
159
160 if (tls_config_load_file(&signer->error, "certificate", cert_file,
161 &cert, &cert_len) == -1)
162 goto err;
163
164 if (tls_config_load_file(&signer->error, "key", key_file, &key,
165 &key_len) == -1)
166 goto err;
167
168 rv = tls_signer_add_keypair_mem(signer, cert, cert_len, key, key_len);
169
170 err:
171 free(cert);
172 free(key);
173
174 return (rv);
175}
176
177static int
178tls_sign_rsa(struct tls_signer *signer, struct tls_signer_key *skey,
179 const uint8_t *dgst, size_t dgstlen, uint8_t **psig, size_t *psiglen,
180 int padding)
181{
182
183 char *buf;
184 int siglen, r;
185
186 *psig = NULL;
187 *psiglen = 0;
188
189 siglen = RSA_size(skey->rsa);
190 if (siglen <= 0) {
191 tls_error_setx(&signer->error, "incorrect RSA_size: %d",
192 siglen);
193 return (-1);
194 }
195
196 if ((buf = malloc(siglen)) == NULL) {
197 tls_error_set(&signer->error, "RSA sign");
198 return (-1);
199 }
200
201 r = RSA_private_encrypt((int)dgstlen, dgst, buf, skey->rsa, padding);
202 if (r == -1) {
203 tls_error_setx(&signer->error, "RSA_private_encrypt failed");
204 free(buf);
205 return (-1);
206 }
207
208 *psig = buf;
209 *psiglen = (size_t)r;
210
211 return (0);
212}
213
214static int
215tls_sign_ecdsa(struct tls_signer *signer, struct tls_signer_key *skey,
216 const uint8_t *dgst, size_t dgstlen, uint8_t **psig, size_t *psiglen)
217{
218 unsigned char *sig;
219 unsigned int siglen;
220
221 *psig = NULL;
222 *psiglen = 0;
223
224 siglen = ECDSA_size(skey->ecdsa);
225 if (siglen == 0) {
226 tls_error_setx(&signer->error, "incorrect ECDSA_size: %u",
227 siglen);
228 return (-1);
229 }
230 if ((sig = malloc(siglen)) == NULL) {
231 tls_error_set(&signer->error, "ECDSA sign");
232 return (-1);
233 }
234
235 if (!ECDSA_sign(0, dgst, dgstlen, sig, &siglen, skey->ecdsa)) {
236 tls_error_setx(&signer->error, "ECDSA_sign failed");
237 free(sig);
238 return (-1);
239 }
240
241 *psig = sig;
242 *psiglen = siglen;
243
244 return (0);
245}
246
247int
248tls_signer_sign(struct tls_signer *signer, const char *hash,
249 const uint8_t *dgst, size_t dgstlen, uint8_t **psig, size_t *psiglen,
250 int padding)
251{
252 struct tls_signer_key *skey;
253
254 for (skey = signer->keys; skey; skey = skey->next)
255 if (!strcmp(hash, skey->hash))
256 break;
257
258 if (skey == NULL) {
259 tls_error_setx(&signer->error, "key not found");
260 return (-1);
261 }
262
263 if (skey->rsa != NULL)
264 return tls_sign_rsa(signer, skey, dgst, dgstlen, psig, psiglen,
265 padding);
266
267 if (skey->ecdsa != NULL)
268 return tls_sign_ecdsa(signer, skey, dgst, dgstlen, psig, psiglen);
269
270 tls_error_setx(&signer->error, "unknown key type");
271 return (-1);
272}
273
274static int
275tls_rsa_priv_enc(int srclen, const unsigned char *src, unsigned char *to,
276 RSA *rsa, int padding)
277{
278 struct tls_config *config;
279 const char *hash;
280 size_t tolen;
281
282 hash = RSA_get_ex_data(rsa, 0);
283 config = RSA_get_ex_data(rsa, 1);
284
285 if (hash == NULL || config == NULL)
286 return (-1);
287
288 if (config->sign_cb(config->sign_cb_arg, hash, (const uint8_t *)src,
289 srclen, (uint8_t *)to, &tolen, padding) == -1)
290 return (-1);
291
292 if (tolen > INT_MAX)
293 return (-1);
294
295 return ((int)tolen);
296}
297
298RSA_METHOD *
299tls_signer_rsa_method(void)
300{
301 static RSA_METHOD *rsa_method = NULL;
302
303 pthread_mutex_lock(&signer_method_lock);
304
305 if (rsa_method != NULL)
306 goto out;
307
308 rsa_method = RSA_meth_new("libtls RSA method", 0);
309 if (rsa_method == NULL)
310 goto out;
311
312 RSA_meth_set_priv_enc(rsa_method, tls_rsa_priv_enc);
313
314 out:
315 pthread_mutex_unlock(&signer_method_lock);
316
317 return (rsa_method);
318}
319
320static ECDSA_SIG *
321tls_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
322 const BIGNUM *rp, EC_KEY *eckey)
323{
324 struct tls_config *config;
325 ECDSA_SIG *sig = NULL;
326 const unsigned char *tsigbuf;
327 const char *hash;
328 char *sigbuf;
329 size_t siglen;
330
331 hash = ECDSA_get_ex_data(eckey, 0);
332 config = ECDSA_get_ex_data(eckey, 1);
333
334 if (hash == NULL || config == NULL)
335 return (NULL);
336
337 siglen = ECDSA_size(eckey);
338 if ((sigbuf = malloc(siglen)) == NULL)
339 return (NULL);
340
341 if (config->sign_cb(config->sign_cb_arg, hash, dgst, dgst_len, sigbuf,
342 &siglen, 0) != -1) {
343 tsigbuf = sigbuf;
344 sig = d2i_ECDSA_SIG(NULL, &tsigbuf, siglen);
345 }
346 free(sigbuf);
347
348 return (sig);
349}
350
351ECDSA_METHOD *
352tls_signer_ecdsa_method(void)
353{
354 static ECDSA_METHOD *ecdsa_method = NULL;
355
356 pthread_mutex_lock(&signer_method_lock);
357
358 if (ecdsa_method != NULL)
359 goto out;
360
361 ecdsa_method = calloc(1, sizeof(*ecdsa_method));
362 if (ecdsa_method == NULL)
363 goto out;
364
365 ecdsa_method->ecdsa_do_sign = tls_ecdsa_do_sign;
366 ecdsa_method->name = strdup("libtls ECDSA method");
367 if (ecdsa_method->name == NULL) {
368 free(ecdsa_method);
369 ecdsa_method = NULL;
370 }
371
372 out:
373 pthread_mutex_unlock(&signer_method_lock);
374
375 return (ecdsa_method);
376}