xref: /openbsd/lib/libtls/tls_signer.c (revision 8e652f17)
1 /* $OpenBSD: tls_signer.c,v 1.13 2024/06/11 16:35:24 op 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 <limits.h>
19 #include <pthread.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <openssl/bio.h>
26 #include <openssl/ec.h>
27 #include <openssl/err.h>
28 #include <openssl/evp.h>
29 #include <openssl/pem.h>
30 #include <openssl/rsa.h>
31 #include <openssl/x509.h>
32 
33 #include "tls.h"
34 #include "tls_internal.h"
35 
36 struct tls_signer_key {
37 	char *hash;
38 	RSA *rsa;
39 	EC_KEY *ecdsa;
40 	struct tls_signer_key *next;
41 };
42 
43 struct tls_signer {
44 	struct tls_error error;
45 	struct tls_signer_key *keys;
46 };
47 
48 static pthread_mutex_t signer_method_lock = PTHREAD_MUTEX_INITIALIZER;
49 
50 struct tls_signer *
tls_signer_new(void)51 tls_signer_new(void)
52 {
53 	struct tls_signer *signer;
54 
55 	if ((signer = calloc(1, sizeof(*signer))) == NULL)
56 		return (NULL);
57 
58 	return (signer);
59 }
60 
61 void
tls_signer_free(struct tls_signer * signer)62 tls_signer_free(struct tls_signer *signer)
63 {
64 	struct tls_signer_key *skey;
65 
66 	if (signer == NULL)
67 		return;
68 
69 	tls_error_clear(&signer->error);
70 
71 	while (signer->keys) {
72 		skey = signer->keys;
73 		signer->keys = skey->next;
74 		RSA_free(skey->rsa);
75 		EC_KEY_free(skey->ecdsa);
76 		free(skey->hash);
77 		free(skey);
78 	}
79 
80 	free(signer);
81 }
82 
83 const char *
tls_signer_error(struct tls_signer * signer)84 tls_signer_error(struct tls_signer *signer)
85 {
86 	return (signer->error.msg);
87 }
88 
89 int
tls_signer_add_keypair_mem(struct tls_signer * signer,const uint8_t * cert,size_t cert_len,const uint8_t * key,size_t key_len)90 tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert,
91     size_t cert_len, const uint8_t *key, size_t key_len)
92 {
93 	struct tls_signer_key *skey = NULL;
94 	char *errstr = "unknown";
95 	int ssl_err;
96 	EVP_PKEY *pkey = NULL;
97 	X509 *x509 = NULL;
98 	BIO *bio = NULL;
99 	char *hash = NULL;
100 
101 	/* Compute certificate hash */
102 	if ((bio = BIO_new_mem_buf(cert, cert_len)) == NULL) {
103 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
104 		    "failed to create certificate bio");
105 		goto err;
106 	}
107 	if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb,
108 	    NULL)) == NULL) {
109 		if ((ssl_err = ERR_peek_error()) != 0)
110 			errstr = ERR_error_string(ssl_err, NULL);
111 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
112 		    "failed to load certificate: %s", errstr);
113 		goto err;
114 	}
115 	if (tls_cert_pubkey_hash(x509, &hash) == -1) {
116 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
117 		    "failed to get certificate hash");
118 		goto err;
119 	}
120 
121 	X509_free(x509);
122 	x509 = NULL;
123 	BIO_free(bio);
124 	bio = NULL;
125 
126 	/* Read private key */
127 	if ((bio = BIO_new_mem_buf(key, key_len)) == NULL) {
128 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
129 		    "failed to create key bio");
130 		goto err;
131 	}
132 	if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
133 	    NULL)) == NULL) {
134 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
135 		    "failed to read private key");
136 		goto err;
137 	}
138 
139 	if ((skey = calloc(1, sizeof(*skey))) == NULL) {
140 		tls_error_set(&signer->error, TLS_ERROR_OUT_OF_MEMORY,
141 		    "out of memory");
142 		goto err;
143 	}
144 	skey->hash = hash;
145 	if ((skey->rsa = EVP_PKEY_get1_RSA(pkey)) == NULL &&
146 	    (skey->ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
147 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
148 		    "unknown key type");
149 		goto err;
150 	}
151 
152 	skey->next = signer->keys;
153 	signer->keys = skey;
154 	EVP_PKEY_free(pkey);
155 	BIO_free(bio);
156 
157 	return (0);
158 
159  err:
160 	EVP_PKEY_free(pkey);
161 	X509_free(x509);
162 	BIO_free(bio);
163 	free(hash);
164 	free(skey);
165 
166 	return (-1);
167 }
168 
169 int
tls_signer_add_keypair_file(struct tls_signer * signer,const char * cert_file,const char * key_file)170 tls_signer_add_keypair_file(struct tls_signer *signer, const char *cert_file,
171     const char *key_file)
172 {
173 	char *cert = NULL, *key = NULL;
174 	size_t cert_len, key_len;
175 	int rv = -1;
176 
177 	if (tls_config_load_file(&signer->error, "certificate", cert_file,
178 	    &cert, &cert_len) == -1)
179 		goto err;
180 
181 	if (tls_config_load_file(&signer->error, "key", key_file, &key,
182 	    &key_len) == -1)
183 		goto err;
184 
185 	rv = tls_signer_add_keypair_mem(signer, cert, cert_len, key, key_len);
186 
187  err:
188 	free(cert);
189 	free(key);
190 
191 	return (rv);
192 }
193 
194 static int
tls_sign_rsa(struct tls_signer * signer,struct tls_signer_key * skey,const uint8_t * input,size_t input_len,int padding_type,uint8_t ** out_signature,size_t * out_signature_len)195 tls_sign_rsa(struct tls_signer *signer, struct tls_signer_key *skey,
196     const uint8_t *input, size_t input_len, int padding_type,
197     uint8_t **out_signature, size_t *out_signature_len)
198 {
199 	int rsa_padding, rsa_size, signature_len;
200 	char *signature = NULL;
201 
202 	*out_signature = NULL;
203 	*out_signature_len = 0;
204 
205 	if (padding_type == TLS_PADDING_NONE) {
206 		rsa_padding = RSA_NO_PADDING;
207 	} else if (padding_type == TLS_PADDING_RSA_PKCS1) {
208 		rsa_padding = RSA_PKCS1_PADDING;
209 	} else {
210 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
211 		    "invalid RSA padding type (%d)", padding_type);
212 		return (-1);
213 	}
214 
215 	if (input_len > INT_MAX) {
216 		tls_error_setx(&signer->error, TLS_ERROR_INVALID_ARGUMENT,
217 		    "input too large");
218 		return (-1);
219 	}
220 	if ((rsa_size = RSA_size(skey->rsa)) <= 0) {
221 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
222 		    "invalid RSA size: %d", rsa_size);
223 		return (-1);
224 	}
225 	if ((signature = calloc(1, rsa_size)) == NULL) {
226 		tls_error_set(&signer->error, TLS_ERROR_OUT_OF_MEMORY,
227 		    "out of memory");
228 		return (-1);
229 	}
230 
231 	if ((signature_len = RSA_private_encrypt((int)input_len, input,
232 	    signature, skey->rsa, rsa_padding)) <= 0) {
233 		/* XXX - include further details from libcrypto. */
234 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
235 		    "RSA signing failed");
236 		free(signature);
237 		return (-1);
238 	}
239 
240 	*out_signature = signature;
241 	*out_signature_len = (size_t)signature_len;
242 
243 	return (0);
244 }
245 
246 static int
tls_sign_ecdsa(struct tls_signer * signer,struct tls_signer_key * skey,const uint8_t * input,size_t input_len,int padding_type,uint8_t ** out_signature,size_t * out_signature_len)247 tls_sign_ecdsa(struct tls_signer *signer, struct tls_signer_key *skey,
248     const uint8_t *input, size_t input_len, int padding_type,
249     uint8_t **out_signature, size_t *out_signature_len)
250 {
251 	unsigned char *signature;
252 	int signature_len;
253 
254 	*out_signature = NULL;
255 	*out_signature_len = 0;
256 
257 	if (padding_type != TLS_PADDING_NONE) {
258 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
259 		    "invalid ECDSA padding");
260 		return (-1);
261 	}
262 
263 	if (input_len > INT_MAX) {
264 		tls_error_setx(&signer->error, TLS_ERROR_INVALID_ARGUMENT,
265 		    "digest too large");
266 		return (-1);
267 	}
268 	if ((signature_len = ECDSA_size(skey->ecdsa)) <= 0) {
269 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
270 		    "invalid ECDSA size: %d", signature_len);
271 		return (-1);
272 	}
273 	if ((signature = calloc(1, signature_len)) == NULL) {
274 		tls_error_set(&signer->error, TLS_ERROR_OUT_OF_MEMORY,
275 		    "out of memory");
276 		return (-1);
277 	}
278 
279 	if (!ECDSA_sign(0, input, input_len, signature, &signature_len,
280 	    skey->ecdsa)) {
281 		/* XXX - include further details from libcrypto. */
282 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
283 		    "ECDSA signing failed");
284 		free(signature);
285 		return (-1);
286 	}
287 
288 	*out_signature = signature;
289 	*out_signature_len = signature_len;
290 
291 	return (0);
292 }
293 
294 int
tls_signer_sign(struct tls_signer * signer,const char * pubkey_hash,const uint8_t * input,size_t input_len,int padding_type,uint8_t ** out_signature,size_t * out_signature_len)295 tls_signer_sign(struct tls_signer *signer, const char *pubkey_hash,
296     const uint8_t *input, size_t input_len, int padding_type,
297     uint8_t **out_signature, size_t *out_signature_len)
298 {
299 	struct tls_signer_key *skey;
300 
301 	*out_signature = NULL;
302 	*out_signature_len = 0;
303 
304 	for (skey = signer->keys; skey; skey = skey->next)
305 		if (!strcmp(pubkey_hash, skey->hash))
306 			break;
307 
308 	if (skey == NULL) {
309 		tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN, "key not found");
310 		return (-1);
311 	}
312 
313 	if (skey->rsa != NULL)
314 		return tls_sign_rsa(signer, skey, input, input_len,
315 		    padding_type, out_signature, out_signature_len);
316 
317 	if (skey->ecdsa != NULL)
318 		return tls_sign_ecdsa(signer, skey, input, input_len,
319 		    padding_type, out_signature, out_signature_len);
320 
321 	tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN, "unknown key type");
322 
323 	return (-1);
324 }
325 
326 static int
tls_rsa_priv_enc(int from_len,const unsigned char * from,unsigned char * to,RSA * rsa,int rsa_padding)327 tls_rsa_priv_enc(int from_len, const unsigned char *from, unsigned char *to,
328     RSA *rsa, int rsa_padding)
329 {
330 	struct tls_config *config;
331 	uint8_t *signature = NULL;
332 	size_t signature_len = 0;
333 	const char *pubkey_hash;
334 	int padding_type;
335 
336 	/*
337 	 * This function is called via RSA_private_encrypt() and has to conform
338 	 * to its calling convention/signature. The caller is required to
339 	 * provide a 'to' buffer of at least RSA_size() bytes.
340 	 */
341 
342 	pubkey_hash = RSA_get_ex_data(rsa, 0);
343 	config = RSA_get_ex_data(rsa, 1);
344 
345 	if (pubkey_hash == NULL || config == NULL)
346 		goto err;
347 
348 	if (rsa_padding == RSA_NO_PADDING) {
349 		padding_type = TLS_PADDING_NONE;
350 	} else if (rsa_padding == RSA_PKCS1_PADDING) {
351 		padding_type = TLS_PADDING_RSA_PKCS1;
352 	} else {
353 		goto err;
354 	}
355 
356 	if (from_len < 0)
357 		goto err;
358 
359 	if (config->sign_cb(config->sign_cb_arg, pubkey_hash, from, from_len,
360 	    padding_type, &signature, &signature_len) == -1)
361 		goto err;
362 
363 	if (signature_len > INT_MAX || (int)signature_len > RSA_size(rsa))
364 		goto err;
365 
366 	memcpy(to, signature, signature_len);
367 	free(signature);
368 
369 	return ((int)signature_len);
370 
371  err:
372 	free(signature);
373 
374 	return (-1);
375 }
376 
377 RSA_METHOD *
tls_signer_rsa_method(void)378 tls_signer_rsa_method(void)
379 {
380 	static RSA_METHOD *rsa_method = NULL;
381 
382 	pthread_mutex_lock(&signer_method_lock);
383 
384 	if (rsa_method != NULL)
385 		goto out;
386 
387 	rsa_method = RSA_meth_new("libtls RSA method", 0);
388 	if (rsa_method == NULL)
389 		goto out;
390 
391 	RSA_meth_set_priv_enc(rsa_method, tls_rsa_priv_enc);
392 
393  out:
394 	pthread_mutex_unlock(&signer_method_lock);
395 
396 	return (rsa_method);
397 }
398 
399 static ECDSA_SIG *
tls_ecdsa_do_sign(const unsigned char * dgst,int dgst_len,const BIGNUM * inv,const BIGNUM * rp,EC_KEY * eckey)400 tls_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
401     const BIGNUM *rp, EC_KEY *eckey)
402 {
403 	struct tls_config *config;
404 	ECDSA_SIG *ecdsa_sig = NULL;
405 	uint8_t *signature = NULL;
406 	size_t signature_len = 0;
407 	const unsigned char *p;
408 	const char *pubkey_hash;
409 
410 	/*
411 	 * This function is called via ECDSA_do_sign_ex() and has to conform
412 	 * to its calling convention/signature.
413 	 */
414 
415 	pubkey_hash = EC_KEY_get_ex_data(eckey, 0);
416 	config = EC_KEY_get_ex_data(eckey, 1);
417 
418 	if (pubkey_hash == NULL || config == NULL)
419 		goto err;
420 
421 	if (dgst_len < 0)
422 		goto err;
423 
424 	if (config->sign_cb(config->sign_cb_arg, pubkey_hash, dgst, dgst_len,
425 	    TLS_PADDING_NONE, &signature, &signature_len) == -1)
426 		goto err;
427 
428 	p = signature;
429 	if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &p, signature_len)) == NULL)
430 		goto err;
431 
432 	free(signature);
433 
434 	return (ecdsa_sig);
435 
436  err:
437 	free(signature);
438 
439 	return (NULL);
440 }
441 
442 EC_KEY_METHOD *
tls_signer_ecdsa_method(void)443 tls_signer_ecdsa_method(void)
444 {
445 	static EC_KEY_METHOD *ecdsa_method = NULL;
446 	const EC_KEY_METHOD *default_method;
447 	int (*sign)(int type, const unsigned char *dgst, int dlen,
448 	    unsigned char *sig, unsigned int *siglen,
449 	    const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey);
450 	int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
451 	    BIGNUM **kinvp, BIGNUM **rp);
452 
453 	pthread_mutex_lock(&signer_method_lock);
454 
455 	if (ecdsa_method != NULL)
456 		goto out;
457 
458 	default_method = EC_KEY_get_default_method();
459 	ecdsa_method = EC_KEY_METHOD_new(default_method);
460 	if (ecdsa_method == NULL)
461 		goto out;
462 
463 	EC_KEY_METHOD_get_sign(default_method, &sign, &sign_setup, NULL);
464 	EC_KEY_METHOD_set_sign(ecdsa_method, sign, sign_setup,
465 	    tls_ecdsa_do_sign);
466 
467  out:
468 	pthread_mutex_unlock(&signer_method_lock);
469 
470 	return (ecdsa_method);
471 }
472