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