dhcpcd: update README.DRAGONFLY
[dragonfly.git] / crypto / libressl / tls / tls_signer.c
blob1f11096792ae41007c244692e36c454342bae2df
1 /* $OpenBSD: tls_signer.c,v 1.4 2022/02/01 17:18:38 jsing Exp $ */
2 /*
3 * Copyright (c) 2021 Eric Faurot <eric@openbsd.org>
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.
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.
18 #include <limits.h>
20 #include <openssl/ecdsa.h>
21 #include <openssl/err.h>
22 #include <openssl/rsa.h>
24 #include "tls.h"
25 #include "tls_internal.h"
27 struct tls_signer_key {
28 char *hash;
29 RSA *rsa;
30 EC_KEY *ecdsa;
31 struct tls_signer_key *next;
34 struct tls_signer {
35 struct tls_error error;
36 struct tls_signer_key *keys;
39 static pthread_mutex_t signer_method_lock = PTHREAD_MUTEX_INITIALIZER;
41 struct tls_signer *
42 tls_signer_new(void)
44 struct tls_signer *signer;
46 if ((signer = calloc(1, sizeof(*signer))) == NULL)
47 return (NULL);
49 return (signer);
52 void
53 tls_signer_free(struct tls_signer *signer)
55 struct tls_signer_key *skey;
57 if (signer == NULL)
58 return;
60 tls_error_clear(&signer->error);
62 while (signer->keys) {
63 skey = signer->keys;
64 signer->keys = skey->next;
65 RSA_free(skey->rsa);
66 EC_KEY_free(skey->ecdsa);
67 free(skey->hash);
68 free(skey);
71 free(signer);
74 const char *
75 tls_signer_error(struct tls_signer *signer)
77 return (signer->error.msg);
80 int
81 tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert,
82 size_t cert_len, const uint8_t *key, size_t key_len)
84 struct tls_signer_key *skey = NULL;
85 char *errstr = "unknown";
86 int ssl_err;
87 EVP_PKEY *pkey = NULL;
88 X509 *x509 = NULL;
89 BIO *bio = NULL;
90 char *hash = NULL;
92 /* Compute certificate hash */
93 if ((bio = BIO_new_mem_buf(cert, cert_len)) == NULL) {
94 tls_error_setx(&signer->error,
95 "failed to create certificate bio");
96 goto err;
98 if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb,
99 NULL)) == NULL) {
100 if ((ssl_err = ERR_peek_error()) != 0)
101 errstr = ERR_error_string(ssl_err, NULL);
102 tls_error_setx(&signer->error, "failed to load certificate: %s",
103 errstr);
104 goto err;
106 if (tls_cert_pubkey_hash(x509, &hash) == -1) {
107 tls_error_setx(&signer->error,
108 "failed to get certificate hash");
109 goto err;
112 X509_free(x509);
113 x509 = NULL;
114 BIO_free(bio);
115 bio = NULL;
117 /* Read private key */
118 if ((bio = BIO_new_mem_buf(key, key_len)) == NULL) {
119 tls_error_setx(&signer->error, "failed to create key bio");
120 goto err;
122 if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
123 NULL)) == NULL) {
124 tls_error_setx(&signer->error, "failed to read private key");
125 goto err;
128 if ((skey = calloc(1, sizeof(*skey))) == NULL) {
129 tls_error_set(&signer->error, "failed to create key entry");
130 goto err;
132 skey->hash = hash;
133 if ((skey->rsa = EVP_PKEY_get1_RSA(pkey)) == NULL &&
134 (skey->ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
135 tls_error_setx(&signer->error, "unknown key type");
136 goto err;
139 skey->next = signer->keys;
140 signer->keys = skey;
141 EVP_PKEY_free(pkey);
142 BIO_free(bio);
144 return (0);
146 err:
147 EVP_PKEY_free(pkey);
148 X509_free(x509);
149 BIO_free(bio);
150 free(hash);
151 free(skey);
153 return (-1);
157 tls_signer_add_keypair_file(struct tls_signer *signer, const char *cert_file,
158 const char *key_file)
160 char *cert = NULL, *key = NULL;
161 size_t cert_len, key_len;
162 int rv = -1;
164 if (tls_config_load_file(&signer->error, "certificate", cert_file,
165 &cert, &cert_len) == -1)
166 goto err;
168 if (tls_config_load_file(&signer->error, "key", key_file, &key,
169 &key_len) == -1)
170 goto err;
172 rv = tls_signer_add_keypair_mem(signer, cert, cert_len, key, key_len);
174 err:
175 free(cert);
176 free(key);
178 return (rv);
181 static int
182 tls_sign_rsa(struct tls_signer *signer, struct tls_signer_key *skey,
183 const uint8_t *input, size_t input_len, int padding_type,
184 uint8_t **out_signature, size_t *out_signature_len)
186 int rsa_padding, rsa_size, signature_len;
187 char *signature = NULL;
189 *out_signature = NULL;
190 *out_signature_len = 0;
192 if (padding_type == TLS_PADDING_NONE) {
193 rsa_padding = RSA_NO_PADDING;
194 } else if (padding_type == TLS_PADDING_RSA_PKCS1) {
195 rsa_padding = RSA_PKCS1_PADDING;
196 } else if (padding_type == TLS_PADDING_RSA_X9_31) {
197 rsa_padding = RSA_X931_PADDING;
198 } else {
199 tls_error_setx(&signer->error, "invalid RSA padding type (%d)",
200 padding_type);
201 return (-1);
204 if (input_len > INT_MAX) {
205 tls_error_setx(&signer->error, "input too large");
206 return (-1);
208 if ((rsa_size = RSA_size(skey->rsa)) <= 0) {
209 tls_error_setx(&signer->error, "invalid RSA size: %d",
210 rsa_size);
211 return (-1);
213 if ((signature = calloc(1, rsa_size)) == NULL) {
214 tls_error_set(&signer->error, "RSA signature");
215 return (-1);
218 if ((signature_len = RSA_private_encrypt((int)input_len, input,
219 signature, skey->rsa, rsa_padding)) <= 0) {
220 /* XXX - include further details from libcrypto. */
221 tls_error_setx(&signer->error, "RSA signing failed");
222 free(signature);
223 return (-1);
226 *out_signature = signature;
227 *out_signature_len = (size_t)signature_len;
229 return (0);
232 static int
233 tls_sign_ecdsa(struct tls_signer *signer, struct tls_signer_key *skey,
234 const uint8_t *input, size_t input_len, int padding_type,
235 uint8_t **out_signature, size_t *out_signature_len)
237 unsigned char *signature;
238 int signature_len;
240 *out_signature = NULL;
241 *out_signature_len = 0;
243 if (padding_type != TLS_PADDING_NONE) {
244 tls_error_setx(&signer->error, "invalid ECDSA padding");
245 return (-1);
248 if (input_len > INT_MAX) {
249 tls_error_setx(&signer->error, "digest too large");
250 return (-1);
252 if ((signature_len = ECDSA_size(skey->ecdsa)) <= 0) {
253 tls_error_setx(&signer->error, "invalid ECDSA size: %d",
254 signature_len);
255 return (-1);
257 if ((signature = calloc(1, signature_len)) == NULL) {
258 tls_error_set(&signer->error, "ECDSA signature");
259 return (-1);
262 if (!ECDSA_sign(0, input, input_len, signature, &signature_len,
263 skey->ecdsa)) {
264 /* XXX - include further details from libcrypto. */
265 tls_error_setx(&signer->error, "ECDSA signing failed");
266 free(signature);
267 return (-1);
270 *out_signature = signature;
271 *out_signature_len = signature_len;
273 return (0);
277 tls_signer_sign(struct tls_signer *signer, const char *pubkey_hash,
278 const uint8_t *input, size_t input_len, int padding_type,
279 uint8_t **out_signature, size_t *out_signature_len)
281 struct tls_signer_key *skey;
283 *out_signature = NULL;
284 *out_signature_len = 0;
286 for (skey = signer->keys; skey; skey = skey->next)
287 if (!strcmp(pubkey_hash, skey->hash))
288 break;
290 if (skey == NULL) {
291 tls_error_setx(&signer->error, "key not found");
292 return (-1);
295 if (skey->rsa != NULL)
296 return tls_sign_rsa(signer, skey, input, input_len,
297 padding_type, out_signature, out_signature_len);
299 if (skey->ecdsa != NULL)
300 return tls_sign_ecdsa(signer, skey, input, input_len,
301 padding_type, out_signature, out_signature_len);
303 tls_error_setx(&signer->error, "unknown key type");
305 return (-1);
308 static int
309 tls_rsa_priv_enc(int from_len, const unsigned char *from, unsigned char *to,
310 RSA *rsa, int rsa_padding)
312 struct tls_config *config;
313 uint8_t *signature = NULL;
314 size_t signature_len = 0;
315 const char *pubkey_hash;
316 int padding_type;
319 * This function is called via RSA_private_encrypt() and has to conform
320 * to its calling convention/signature. The caller is required to
321 * provide a 'to' buffer of at least RSA_size() bytes.
324 pubkey_hash = RSA_get_ex_data(rsa, 0);
325 config = RSA_get_ex_data(rsa, 1);
327 if (pubkey_hash == NULL || config == NULL)
328 goto err;
330 if (rsa_padding == RSA_NO_PADDING) {
331 padding_type = TLS_PADDING_NONE;
332 } else if (rsa_padding == RSA_PKCS1_PADDING) {
333 padding_type = TLS_PADDING_RSA_PKCS1;
334 } else if (rsa_padding == RSA_X931_PADDING) {
335 padding_type = TLS_PADDING_RSA_X9_31;
336 } else {
337 goto err;
340 if (from_len < 0)
341 goto err;
343 if (config->sign_cb(config->sign_cb_arg, pubkey_hash, from, from_len,
344 padding_type, &signature, &signature_len) == -1)
345 goto err;
347 if (signature_len > INT_MAX || (int)signature_len > RSA_size(rsa))
348 goto err;
350 memcpy(to, signature, signature_len);
351 free(signature);
353 return ((int)signature_len);
355 err:
356 free(signature);
358 return (-1);
361 RSA_METHOD *
362 tls_signer_rsa_method(void)
364 static RSA_METHOD *rsa_method = NULL;
366 pthread_mutex_lock(&signer_method_lock);
368 if (rsa_method != NULL)
369 goto out;
371 rsa_method = RSA_meth_new("libtls RSA method", 0);
372 if (rsa_method == NULL)
373 goto out;
375 RSA_meth_set_priv_enc(rsa_method, tls_rsa_priv_enc);
377 out:
378 pthread_mutex_unlock(&signer_method_lock);
380 return (rsa_method);
383 static ECDSA_SIG *
384 tls_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
385 const BIGNUM *rp, EC_KEY *eckey)
387 struct tls_config *config;
388 ECDSA_SIG *ecdsa_sig = NULL;
389 uint8_t *signature = NULL;
390 size_t signature_len = 0;
391 const unsigned char *p;
392 const char *pubkey_hash;
395 * This function is called via ECDSA_do_sign_ex() and has to conform
396 * to its calling convention/signature.
399 pubkey_hash = ECDSA_get_ex_data(eckey, 0);
400 config = ECDSA_get_ex_data(eckey, 1);
402 if (pubkey_hash == NULL || config == NULL)
403 goto err;
405 if (dgst_len < 0)
406 goto err;
408 if (config->sign_cb(config->sign_cb_arg, pubkey_hash, dgst, dgst_len,
409 TLS_PADDING_NONE, &signature, &signature_len) == -1)
410 goto err;
412 p = signature;
413 if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &p, signature_len)) == NULL)
414 goto err;
416 free(signature);
418 return (ecdsa_sig);
420 err:
421 free(signature);
423 return (NULL);
426 ECDSA_METHOD *
427 tls_signer_ecdsa_method(void)
429 static ECDSA_METHOD *ecdsa_method = NULL;
431 pthread_mutex_lock(&signer_method_lock);
433 if (ecdsa_method != NULL)
434 goto out;
436 ecdsa_method = calloc(1, sizeof(*ecdsa_method));
437 if (ecdsa_method == NULL)
438 goto out;
440 ecdsa_method->ecdsa_do_sign = tls_ecdsa_do_sign;
441 ecdsa_method->name = strdup("libtls ECDSA method");
442 if (ecdsa_method->name == NULL) {
443 free(ecdsa_method);
444 ecdsa_method = NULL;
447 out:
448 pthread_mutex_unlock(&signer_method_lock);
450 return (ecdsa_method);