Line data Source code
1 : /*
2 : * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3 : * Copyright (C) 2017 Red Hat, Inc.
4 : *
5 : * Author: Nikos Mavrogiannopoulos
6 : *
7 : * This file is part of GnuTLS.
8 : *
9 : * The GnuTLS is free software; you can redistribute it and/or
10 : * modify it under the terms of the GNU Lesser General Public License
11 : * as published by the Free Software Foundation; either version 2.1 of
12 : * the License, or (at your option) any later version.
13 : *
14 : * This library is distributed in the hope that it will be useful, but
15 : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : * Lesser General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU Lesser General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>
21 : *
22 : */
23 :
24 : /* This file contains everything for the Ephemeral Diffie-Hellman
25 : * (DHE) key exchange. This is used in the handshake procedure of the
26 : * certificate authentication.
27 : */
28 :
29 : #include "gnutls_int.h"
30 : #include "auth.h"
31 : #include "errors.h"
32 : #include "dh.h"
33 : #include "num.h"
34 : #include "tls-sig.h"
35 : #include <datum.h>
36 : #include <algorithms.h>
37 : #include <auth/cert.h>
38 : #include <x509.h>
39 : #include <state.h>
40 : #include <auth/dh_common.h>
41 : #include <auth/ecdhe.h>
42 :
43 : static int gen_dhe_server_kx(gnutls_session_t, gnutls_buffer_st *);
44 : static int proc_dhe_server_kx(gnutls_session_t, uint8_t *, size_t);
45 : static int proc_dhe_client_kx(gnutls_session_t, uint8_t *, size_t);
46 :
47 : #ifdef ENABLE_DHE
48 :
49 : const mod_auth_st dhe_rsa_auth_struct = {
50 : "DHE_RSA",
51 : _gnutls_gen_cert_server_crt,
52 : _gnutls_gen_cert_client_crt,
53 : gen_dhe_server_kx,
54 : _gnutls_gen_dh_common_client_kx,
55 : _gnutls_gen_cert_client_crt_vrfy, /* gen client cert vrfy */
56 : _gnutls_gen_cert_server_cert_req, /* server cert request */
57 :
58 : _gnutls_proc_crt,
59 : _gnutls_proc_crt,
60 : proc_dhe_server_kx,
61 : proc_dhe_client_kx,
62 : _gnutls_proc_cert_client_crt_vrfy, /* proc client cert vrfy */
63 : _gnutls_proc_cert_cert_req /* proc server cert request */
64 : };
65 :
66 : const mod_auth_st dhe_dss_auth_struct = {
67 : "DHE_DSS",
68 : _gnutls_gen_cert_server_crt,
69 : _gnutls_gen_cert_client_crt,
70 : gen_dhe_server_kx,
71 : _gnutls_gen_dh_common_client_kx,
72 : _gnutls_gen_cert_client_crt_vrfy, /* gen client cert vrfy */
73 : _gnutls_gen_cert_server_cert_req, /* server cert request */
74 :
75 : _gnutls_proc_crt,
76 : _gnutls_proc_crt,
77 : proc_dhe_server_kx,
78 : proc_dhe_client_kx,
79 : _gnutls_proc_cert_client_crt_vrfy, /* proc client cert vrfy */
80 : _gnutls_proc_cert_cert_req /* proc server cert request */
81 : };
82 :
83 : #endif
84 :
85 : static int
86 1668 : gen_dhe_server_kx(gnutls_session_t session, gnutls_buffer_st * data)
87 : {
88 1668 : int ret = 0;
89 1668 : gnutls_certificate_credentials_t cred;
90 1668 : unsigned sig_pos;
91 :
92 1668 : cred = (gnutls_certificate_credentials_t)
93 1668 : _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
94 1668 : if (cred == NULL) {
95 0 : gnutls_assert();
96 0 : return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
97 : }
98 :
99 1668 : if ((ret = _gnutls_auth_info_init(session, GNUTLS_CRD_CERTIFICATE,
100 : sizeof(cert_auth_info_st),
101 : 1)) < 0) {
102 0 : gnutls_assert();
103 0 : return ret;
104 : }
105 :
106 1668 : ret =
107 1668 : _gnutls_figure_dh_params(session, cred->dh_params, cred->params_func, cred->dh_sec_param);
108 1668 : if (ret < 0) {
109 0 : return gnutls_assert_val(ret);
110 : }
111 :
112 1668 : sig_pos = data->length;
113 :
114 1668 : ret =
115 1668 : _gnutls_dh_common_print_server_kx(session, data);
116 1668 : if (ret < 0) {
117 0 : gnutls_assert();
118 0 : return ret;
119 : }
120 :
121 : /* Generate the signature. */
122 1668 : return _gnutls_gen_dhe_signature(session, data, &data->data[sig_pos],
123 1668 : data->length-sig_pos);
124 : }
125 :
126 :
127 : static int
128 159 : proc_dhe_server_kx(gnutls_session_t session, uint8_t * data,
129 : size_t _data_size)
130 : {
131 159 : gnutls_datum_t vdata;
132 159 : int ret;
133 :
134 159 : ret = _gnutls_proc_dh_common_server_kx(session, data, _data_size);
135 159 : if (ret < 0)
136 6 : return gnutls_assert_val(ret);
137 :
138 153 : vdata.data = data;
139 153 : vdata.size = ret;
140 :
141 153 : return _gnutls_proc_dhe_signature(session, data + ret,
142 : _data_size - ret, &vdata);
143 : }
144 :
145 :
146 : static int
147 1583 : proc_dhe_client_kx(gnutls_session_t session, uint8_t * data,
148 : size_t _data_size)
149 : {
150 1583 : return _gnutls_proc_dh_common_client_kx(session, data, _data_size,
151 : NULL);
152 : }
|