summaryrefslogtreecommitdiff
path: root/lib/auth/cert.h
blob: fd66628820e292ba99cdcd05973bdafc3cd6ea6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
 * Copyright (C) 2016-2019 Red Hat, Inc.
 *
 * Author: Nikos Mavrogiannopoulos
 *
 * This file is part of GnuTLS.
 *
 * The GnuTLS is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

#ifndef AUTH_CERT_H
#define AUTH_CERT_H
#include "auth.h"
#include <auth/dh_common.h>
#include <x509/x509_int.h>
#include <gnutls/abstract.h>
#include <gnutls/compat.h>
#include <str_array.h>
#include "abstract_int.h"

#define MAX_OCSP_RESPONSES 8

/* We use the structure below to hold a certificate chain
 * with corresponding public/private key pair. This structure will
 * also be used when raw public keys are used. The cert_list will
 * then not hold the cert chain but only a raw public-key. In that case
 * the list length is always 1.
 */
typedef struct {
	gnutls_pcert_st *cert_list;	/* a certificate chain */
	unsigned int cert_list_length;	/* its length */
	gnutls_str_array_t names;	/* the names in the first certificate */

	gnutls_status_request_ocsp_func ocsp_func;
	void *ocsp_func_ptr; /* corresponding OCSP response function + ptr */

	gnutls_ocsp_data_st ocsp_data[MAX_OCSP_RESPONSES];
	unsigned int ocsp_data_length;

	/* the private key corresponding to certificate */
	gnutls_privkey_t pkey;
} certs_st;

/* This structure may be complex, but it's the only way to
 * support a server that has multiple certificates
 */
typedef struct gnutls_certificate_credentials_st {
	gnutls_dh_params_t dh_params;
	unsigned deinit_dh_params; /* if the internal values are set */
	gnutls_sec_param_t dh_sec_param; /* used in RFC7919 negotiation */

	/* this callback is used to retrieve the DH or RSA
	 * parameters.
	 */
	gnutls_params_function *params_func;

	certs_st *certs;
	unsigned ncerts;	/* the number of certs */

	/* contains sorted index values for certs. Sorted in a way
	 * that RSA-PSS keys always take precedence over plain RSA keys
	 * to ensure that we use only RSA-PSS keys if present for RSA-PSS
	 * operations. We keep indexes to certs structures above.
	 */
	unsigned int *sorted_cert_idx;

	/* X509 specific stuff */
	gnutls_x509_trust_list_t tlist;
	unsigned flags; /* gnutls_certificate_flags */
	unsigned int verify_flags;	/* flags to be used at
					 * certificate verification.
					 */
	unsigned int verify_depth;
	unsigned int verify_bits;

	/* It's a mess here. However we need to keep the old 3 functions
	 * for compatibility */
	gnutls_certificate_retrieve_function *legacy_cert_cb1; /* deprecated */
	gnutls_certificate_retrieve_function2 *legacy_cert_cb2;
	gnutls_certificate_retrieve_function3 *get_cert_callback3;

	gnutls_certificate_verify_function *verify_callback;

	struct pin_info_st pin;
	/* temporarily hold the PIN if set_key_file2() is used with a PIN */
	char pin_tmp[GNUTLS_PKCS11_MAX_PIN_LEN];

	/* OCSP */
	gnutls_status_request_ocsp_func glob_ocsp_func;
	void *glob_ocsp_func_ptr; /* corresponding OCSP response function */
} certificate_credentials_st;

/* This is the information we keep for the peer
 * certificate.
 */
typedef struct cert_auth_info_st {
	/* These (dh/rsa) are just copies from the credentials_t structure.
	 * They must be freed.
	 */
	dh_info_st dh;

	/* we store the peer's OCSP responses received during
	 * this session. */
	gnutls_datum_t *raw_ocsp_list;
	unsigned int nocsp;

	/* we store the peer's certificates received during
	 * this ession */
	gnutls_datum_t *raw_certificate_list;
	unsigned int ncerts;

	gnutls_certificate_type_t cert_type;
} *cert_auth_info_t;

typedef struct cert_auth_info_st cert_auth_info_st;

/* AUTH X509 functions */
int _gnutls_gen_cert_server_crt(gnutls_session_t, gnutls_buffer_st *);
int _gnutls_gen_cert_client_crt(gnutls_session_t, gnutls_buffer_st *);
int _gnutls_gen_cert_client_crt_vrfy(gnutls_session_t, gnutls_buffer_st *);
int _gnutls_gen_cert_server_cert_req(gnutls_session_t, gnutls_buffer_st *);
int _gnutls_proc_cert_cert_req(gnutls_session_t, uint8_t *, size_t);
int _gnutls_proc_cert_client_crt_vrfy(gnutls_session_t, uint8_t *, size_t);
int _gnutls_proc_crt(gnutls_session_t, uint8_t *, size_t);
int _gnutls_get_selected_cert(gnutls_session_t session,
			      gnutls_pcert_st ** apr_cert_list,
			      int *apr_cert_list_length,
			      gnutls_privkey_t * apr_pkey);

int
_gnutls_select_client_cert(gnutls_session_t session,
			   const uint8_t * _data, size_t _data_size,
			   gnutls_pk_algorithm_t * pk_algos, int pk_algos_length);

int _gnutls_pcert_to_auth_info(cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts);

int
_gnutls_select_server_cert(gnutls_session_t session, const gnutls_cipher_suite_entry_st *cs);
void _gnutls_selected_certs_deinit(gnutls_session_t session);

int _gnutls_get_auth_info_pcert(gnutls_pcert_st * gcert,
				gnutls_certificate_type_t type,
				cert_auth_info_t info);

int _gnutls_selected_cert_supported_kx(struct gnutls_session_int *session,
				       gnutls_kx_algorithm_t * alg,
				       int *alg_size);

int _gnutls_check_key_cert_match(gnutls_certificate_credentials_t res);

int _gnutls_gen_dhe_signature(gnutls_session_t session,
			      gnutls_buffer_st * data, uint8_t * plain,
			      unsigned plain_size);
int _gnutls_proc_dhe_signature(gnutls_session_t session, uint8_t * data,
			       size_t _data_size,
			       gnutls_datum_t * vparams);

int _gnutls_gen_rawpk_crt(gnutls_session_t session, gnutls_buffer_st* data);
int _gnutls_proc_rawpk_crt(gnutls_session_t session,
				uint8_t * data, size_t data_size);

inline static unsigned get_key_usage(gnutls_session_t session, gnutls_pubkey_t pubkey)
{
	if (unlikely(session->internals.priorities &&
	    session->internals.priorities->allow_server_key_usage_violation))
		return 0;
	else
		return pubkey->key_usage;
}

#endif