Add.
[gnutls.git] / lib / auth_rsa_export.c
bloba16ed17f3f7b6581a487ff0a26646f4cad532986
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 /* This file contains the RSA key exchange part of the certificate
26 * authentication.
29 #include "gnutls_int.h"
30 #include "gnutls_auth_int.h"
31 #include "gnutls_errors.h"
32 #include "gnutls_dh.h"
33 #include "gnutls_num.h"
34 #include "libtasn1.h"
35 #include "gnutls_datum.h"
36 #include "auth_cert.h"
37 #include <gnutls_pk.h>
38 #include <gnutls_algorithms.h>
39 #include <gnutls_global.h>
40 #include "debug.h"
41 #include <gnutls_sig.h>
42 #include <gnutls_x509.h>
43 #include <gnutls_rsa_export.h>
44 #include <gnutls_state.h>
46 int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
47 int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t);
48 static int gen_rsa_export_server_kx (gnutls_session_t, opaque **);
49 static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t);
51 const mod_auth_st rsa_export_auth_struct = {
52 "RSA EXPORT",
53 _gnutls_gen_cert_server_certificate,
54 _gnutls_gen_cert_client_certificate,
55 gen_rsa_export_server_kx,
56 _gnutls_gen_rsa_client_kx,
57 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
58 _gnutls_gen_cert_server_cert_req, /* server cert request */
60 _gnutls_proc_cert_server_certificate,
61 _gnutls_proc_cert_client_certificate,
62 proc_rsa_export_server_kx,
63 _gnutls_proc_rsa_client_kx, /* proc client kx */
64 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
65 _gnutls_proc_cert_cert_req /* proc server cert request */
68 static int
69 gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data)
71 gnutls_rsa_params_t rsa_params;
72 const mpi_t *rsa_mpis;
73 size_t n_e, n_m;
74 uint8_t *data_e, *data_m;
75 int ret = 0, data_size;
76 gnutls_cert *apr_cert_list;
77 gnutls_privkey *apr_pkey;
78 int apr_cert_list_length;
79 gnutls_datum_t signature, ddata;
80 cert_auth_info_t info;
81 gnutls_certificate_credentials_t cred;
83 cred = (gnutls_certificate_credentials_t)
84 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
85 if (cred == NULL)
87 gnutls_assert ();
88 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
91 /* find the appropriate certificate */
92 if ((ret =
93 _gnutls_get_selected_cert (session, &apr_cert_list,
94 &apr_cert_list_length, &apr_pkey)) < 0)
96 gnutls_assert ();
97 return ret;
100 /* abort sending this message if we have a certificate
101 * of 512 bits or less.
103 if (_gnutls_mpi_get_nbits (apr_pkey->params[0]) <= 512)
105 gnutls_assert ();
106 return GNUTLS_E_INT_RET_0;
109 rsa_params =
110 _gnutls_certificate_get_rsa_params (cred->rsa_params, cred->params_func,
111 session);
112 rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params);
113 if (rsa_mpis == NULL)
115 gnutls_assert ();
116 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
119 if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
120 sizeof (cert_auth_info_st), 0)) < 0)
122 gnutls_assert ();
123 return ret;
126 info = _gnutls_get_auth_info (session);
127 _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]);
129 _gnutls_mpi_print (NULL, &n_m, rsa_mpis[0]);
130 _gnutls_mpi_print (NULL, &n_e, rsa_mpis[1]);
132 (*data) = gnutls_malloc (n_e + n_m + 4);
133 if (*data == NULL)
135 return GNUTLS_E_MEMORY_ERROR;
138 data_m = &(*data)[0];
139 _gnutls_mpi_print (&data_m[2], &n_m, rsa_mpis[0]);
141 _gnutls_write_uint16 (n_m, data_m);
143 data_e = &data_m[2 + n_m];
144 _gnutls_mpi_print (&data_e[2], &n_e, rsa_mpis[1]);
146 _gnutls_write_uint16 (n_e, data_e);
148 data_size = n_m + n_e + 4;
151 /* Generate the signature. */
153 ddata.data = *data;
154 ddata.size = data_size;
156 if (apr_pkey != NULL)
158 if ((ret =
159 _gnutls_tls_sign_params (session, &apr_cert_list[0],
160 apr_pkey, &ddata, &signature)) < 0)
162 gnutls_assert ();
163 gnutls_free (*data);
164 *data = NULL;
165 return ret;
168 else
170 gnutls_assert ();
171 return data_size; /* do not put a signature - ILLEGAL! */
174 *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
175 if (*data == NULL)
177 _gnutls_free_datum (&signature);
178 gnutls_assert ();
179 return GNUTLS_E_MEMORY_ERROR;
182 _gnutls_write_datum16 (&((*data)[data_size]), signature);
183 data_size += signature.size + 2;
185 _gnutls_free_datum (&signature);
187 return data_size;
190 /* if the peer's certificate is of 512 bits or less, returns non zero.
193 _gnutls_peers_cert_less_512 (gnutls_session_t session)
195 gnutls_cert peer_cert;
196 int ret;
197 cert_auth_info_t info = _gnutls_get_auth_info (session);
199 if (info == NULL || info->ncerts == 0)
201 gnutls_assert ();
202 /* we need this in order to get peer's certificate */
203 return 0;
206 if ((ret =
207 _gnutls_raw_cert_to_gcert (&peer_cert,
208 session->security_parameters.cert_type,
209 &info->raw_certificate_list[0],
210 CERT_NO_COPY)) < 0)
212 gnutls_assert ();
213 return 0;
216 if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA)
218 gnutls_assert ();
219 _gnutls_gcert_deinit (&peer_cert);
220 return 0;
223 if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512)
225 _gnutls_gcert_deinit (&peer_cert);
226 return 1;
229 _gnutls_gcert_deinit (&peer_cert);
231 return 0;
234 static int
235 proc_rsa_export_server_kx (gnutls_session_t session,
236 opaque * data, size_t _data_size)
238 uint16_t n_m, n_e;
239 size_t _n_m, _n_e;
240 uint8_t *data_m;
241 uint8_t *data_e;
242 int i, sigsize;
243 gnutls_datum_t vparams, signature;
244 int ret;
245 ssize_t data_size = _data_size;
246 cert_auth_info_t info;
247 gnutls_cert peer_cert;
249 info = _gnutls_get_auth_info (session);
250 if (info == NULL || info->ncerts == 0)
252 gnutls_assert ();
253 /* we need this in order to get peer's certificate */
254 return GNUTLS_E_INTERNAL_ERROR;
258 i = 0;
260 DECR_LEN (data_size, 2);
261 n_m = _gnutls_read_uint16 (&data[i]);
262 i += 2;
264 DECR_LEN (data_size, n_m);
265 data_m = &data[i];
266 i += n_m;
268 DECR_LEN (data_size, 2);
269 n_e = _gnutls_read_uint16 (&data[i]);
270 i += 2;
272 DECR_LEN (data_size, n_e);
273 data_e = &data[i];
274 i += n_e;
276 _n_e = n_e;
277 _n_m = n_m;
279 if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, &_n_m) != 0)
281 gnutls_assert ();
282 return GNUTLS_E_MPI_SCAN_FAILED;
285 if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, &_n_e) != 0)
287 gnutls_assert ();
288 return GNUTLS_E_MPI_SCAN_FAILED;
291 _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1],
292 session->key->rsa[0]);
294 /* VERIFY SIGNATURE */
296 vparams.size = n_m + n_e + 4;
297 vparams.data = data;
299 DECR_LEN (data_size, 2);
300 sigsize = _gnutls_read_uint16 (&data[vparams.size]);
302 DECR_LEN (data_size, sigsize);
303 signature.data = &data[vparams.size + 2];
304 signature.size = sigsize;
306 if ((ret =
307 _gnutls_raw_cert_to_gcert (&peer_cert,
308 session->security_parameters.cert_type,
309 &info->raw_certificate_list[0],
310 CERT_NO_COPY)) < 0)
312 gnutls_assert ();
313 return ret;
316 ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
318 _gnutls_gcert_deinit (&peer_cert);
319 if (ret < 0)
321 gnutls_assert ();
324 return ret;