1 /* $OpenBSD: tls_signer.c,v 1.4 2022/02/01 17:18:38 jsing Exp $ */
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.
20 #include <openssl/ecdsa.h>
21 #include <openssl/err.h>
22 #include <openssl/rsa.h>
25 #include "tls_internal.h"
27 struct tls_signer_key
{
31 struct tls_signer_key
*next
;
35 struct tls_error error
;
36 struct tls_signer_key
*keys
;
39 static pthread_mutex_t signer_method_lock
= PTHREAD_MUTEX_INITIALIZER
;
44 struct tls_signer
*signer
;
46 if ((signer
= calloc(1, sizeof(*signer
))) == NULL
)
53 tls_signer_free(struct tls_signer
*signer
)
55 struct tls_signer_key
*skey
;
60 tls_error_clear(&signer
->error
);
62 while (signer
->keys
) {
64 signer
->keys
= skey
->next
;
66 EC_KEY_free(skey
->ecdsa
);
75 tls_signer_error(struct tls_signer
*signer
)
77 return (signer
->error
.msg
);
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";
87 EVP_PKEY
*pkey
= 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");
98 if ((x509
= PEM_read_bio_X509(bio
, NULL
, tls_password_cb
,
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",
106 if (tls_cert_pubkey_hash(x509
, &hash
) == -1) {
107 tls_error_setx(&signer
->error
,
108 "failed to get certificate hash");
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");
122 if ((pkey
= PEM_read_bio_PrivateKey(bio
, NULL
, tls_password_cb
,
124 tls_error_setx(&signer
->error
, "failed to read private key");
128 if ((skey
= calloc(1, sizeof(*skey
))) == NULL
) {
129 tls_error_set(&signer
->error
, "failed to create key entry");
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");
139 skey
->next
= signer
->keys
;
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
;
164 if (tls_config_load_file(&signer
->error
, "certificate", cert_file
,
165 &cert
, &cert_len
) == -1)
168 if (tls_config_load_file(&signer
->error
, "key", key_file
, &key
,
172 rv
= tls_signer_add_keypair_mem(signer
, cert
, cert_len
, key
, key_len
);
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
;
199 tls_error_setx(&signer
->error
, "invalid RSA padding type (%d)",
204 if (input_len
> INT_MAX
) {
205 tls_error_setx(&signer
->error
, "input too large");
208 if ((rsa_size
= RSA_size(skey
->rsa
)) <= 0) {
209 tls_error_setx(&signer
->error
, "invalid RSA size: %d",
213 if ((signature
= calloc(1, rsa_size
)) == NULL
) {
214 tls_error_set(&signer
->error
, "RSA signature");
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");
226 *out_signature
= signature
;
227 *out_signature_len
= (size_t)signature_len
;
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
;
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");
248 if (input_len
> INT_MAX
) {
249 tls_error_setx(&signer
->error
, "digest too large");
252 if ((signature_len
= ECDSA_size(skey
->ecdsa
)) <= 0) {
253 tls_error_setx(&signer
->error
, "invalid ECDSA size: %d",
257 if ((signature
= calloc(1, signature_len
)) == NULL
) {
258 tls_error_set(&signer
->error
, "ECDSA signature");
262 if (!ECDSA_sign(0, input
, input_len
, signature
, &signature_len
,
264 /* XXX - include further details from libcrypto. */
265 tls_error_setx(&signer
->error
, "ECDSA signing failed");
270 *out_signature
= signature
;
271 *out_signature_len
= signature_len
;
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
))
291 tls_error_setx(&signer
->error
, "key not found");
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");
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
;
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
)
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
;
343 if (config
->sign_cb(config
->sign_cb_arg
, pubkey_hash
, from
, from_len
,
344 padding_type
, &signature
, &signature_len
) == -1)
347 if (signature_len
> INT_MAX
|| (int)signature_len
> RSA_size(rsa
))
350 memcpy(to
, signature
, signature_len
);
353 return ((int)signature_len
);
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
)
371 rsa_method
= RSA_meth_new("libtls RSA method", 0);
372 if (rsa_method
== NULL
)
375 RSA_meth_set_priv_enc(rsa_method
, tls_rsa_priv_enc
);
378 pthread_mutex_unlock(&signer_method_lock
);
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
)
408 if (config
->sign_cb(config
->sign_cb_arg
, pubkey_hash
, dgst
, dgst_len
,
409 TLS_PADDING_NONE
, &signature
, &signature_len
) == -1)
413 if ((ecdsa_sig
= d2i_ECDSA_SIG(NULL
, &p
, signature_len
)) == NULL
)
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
)
436 ecdsa_method
= calloc(1, sizeof(*ecdsa_method
));
437 if (ecdsa_method
== NULL
)
440 ecdsa_method
->ecdsa_do_sign
= tls_ecdsa_do_sign
;
441 ecdsa_method
->name
= strdup("libtls ECDSA method");
442 if (ecdsa_method
->name
== NULL
) {
448 pthread_mutex_unlock(&signer_method_lock
);
450 return (ecdsa_method
);