xref: /dragonfly/crypto/libressl/ssl/tls_lib.c (revision 6f5ec8b5)
1 /* $OpenBSD: tls_lib.c,v 1.2 2022/08/20 21:48:25 tb Exp $ */
2 /*
3  * Copyright (c) 2019, 2021 Joel Sing <jsing@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 "ssl_locl.h"
19 
20 int
21 tls_process_peer_certs(SSL *s, STACK_OF(X509) *peer_certs)
22 {
23 	STACK_OF(X509) *peer_certs_no_leaf;
24 	X509 *peer_cert = NULL;
25 	EVP_PKEY *pkey;
26 	int cert_type;
27 	int ret = 0;
28 
29 	if (sk_X509_num(peer_certs) < 1)
30 		goto err;
31 	peer_cert = sk_X509_value(peer_certs, 0);
32 	X509_up_ref(peer_cert);
33 
34 	if ((pkey = X509_get0_pubkey(peer_cert)) == NULL) {
35 		SSLerror(s, SSL_R_NO_PUBLICKEY);
36 		goto err;
37 	}
38 	if (EVP_PKEY_missing_parameters(pkey)) {
39 		SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
40 		goto err;
41 	}
42 	if ((cert_type = ssl_cert_type(pkey)) < 0) {
43 		SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
44 		goto err;
45 	}
46 
47 	s->session->peer_cert_type = cert_type;
48 
49 	X509_free(s->session->peer_cert);
50 	s->session->peer_cert = peer_cert;
51 	peer_cert = NULL;
52 
53 	sk_X509_pop_free(s->s3->hs.peer_certs, X509_free);
54 	if ((s->s3->hs.peer_certs = X509_chain_up_ref(peer_certs)) == NULL)
55 		goto err;
56 
57 	if ((peer_certs_no_leaf = X509_chain_up_ref(peer_certs)) == NULL)
58 		goto err;
59 	X509_free(sk_X509_shift(peer_certs_no_leaf));
60 	sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free);
61 	s->s3->hs.peer_certs_no_leaf = peer_certs_no_leaf;
62 
63 	ret = 1;
64  err:
65 	X509_free(peer_cert);
66 
67 	return ret;
68 }
69