Fixed leaks in key generation and other cleanups. Patch by Tomas Mraz.
[gnutls.git] / lib / auth_srp_rsa.c
blob4bf0202945fc55eaa6b2854fa665b688f5d5cbdd
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2010 Free Software
3 * Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
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.
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.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 #include <gnutls_int.h>
28 #ifdef ENABLE_SRP
30 #include "gnutls_errors.h"
31 #include "auth_srp_passwd.h"
32 #include "gnutls_auth.h"
33 #include "gnutls_auth.h"
34 #include "gnutls_srp.h"
35 #include "debug.h"
36 #include "gnutls_num.h"
37 #include "auth_srp.h"
38 #include <gnutls_str.h>
39 #include <auth_cert.h>
40 #include <gnutls_datum.h>
41 #include <gnutls_sig.h>
42 #include <auth_srp.h>
43 #include <gnutls_x509.h>
44 #include <gnutls_algorithms.h>
46 static int gen_srp_cert_server_kx (gnutls_session_t, opaque **);
47 static int proc_srp_cert_server_kx (gnutls_session_t, opaque *, size_t);
49 const mod_auth_st srp_rsa_auth_struct = {
50 "SRP",
51 _gnutls_gen_cert_server_certificate,
52 NULL,
53 gen_srp_cert_server_kx,
54 _gnutls_gen_srp_client_kx,
55 NULL,
56 NULL,
58 _gnutls_proc_cert_server_certificate,
59 NULL, /* certificate */
60 proc_srp_cert_server_kx,
61 _gnutls_proc_srp_client_kx,
62 NULL,
63 NULL
66 const mod_auth_st srp_dss_auth_struct = {
67 "SRP",
68 _gnutls_gen_cert_server_certificate,
69 NULL,
70 gen_srp_cert_server_kx,
71 _gnutls_gen_srp_client_kx,
72 NULL,
73 NULL,
75 _gnutls_proc_cert_server_certificate,
76 NULL, /* certificate */
77 proc_srp_cert_server_kx,
78 _gnutls_proc_srp_client_kx,
79 NULL,
80 NULL
83 static int
84 gen_srp_cert_server_kx (gnutls_session_t session, opaque ** data)
86 ssize_t ret, data_size;
87 gnutls_datum_t signature, ddata;
88 gnutls_certificate_credentials_t cred;
89 gnutls_cert *apr_cert_list;
90 gnutls_privkey_t apr_pkey;
91 int apr_cert_list_length;
92 gnutls_sign_algorithm_t sign_algo;
93 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
95 ret = _gnutls_gen_srp_server_kx (session, data);
97 if (ret < 0)
98 return ret;
100 data_size = ret;
101 ddata.data = *data;
102 ddata.size = data_size;
104 cred = (gnutls_certificate_credentials_t)
105 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
106 if (cred == NULL)
108 gnutls_assert ();
109 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
112 /* find the appropriate certificate */
113 if ((ret =
114 _gnutls_get_selected_cert (session, &apr_cert_list,
115 &apr_cert_list_length, &apr_pkey)) < 0)
117 gnutls_assert ();
118 return ret;
121 if ((ret =
122 _gnutls_handshake_sign_data (session, &apr_cert_list[0],
123 apr_pkey, &ddata, &signature,
124 &sign_algo)) < 0)
126 gnutls_assert ();
127 gnutls_free (*data);
128 return ret;
131 *data = gnutls_realloc_fast (*data, data_size + signature.size + 4);
132 if (*data == NULL)
134 _gnutls_free_datum (&signature);
135 gnutls_assert ();
136 return GNUTLS_E_MEMORY_ERROR;
139 if (_gnutls_version_has_selectable_sighash (ver))
141 const sign_algorithm_st *aid;
143 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
145 ret = GNUTLS_E_UNKNOWN_ALGORITHM;
146 goto cleanup;
149 aid = _gnutls_sign_to_tls_aid (sign_algo);
150 if (aid == NULL)
152 gnutls_assert();
153 ret = GNUTLS_E_UNKNOWN_ALGORITHM;
154 goto cleanup;
157 (*data)[data_size++] = aid->hash_algorithm;
158 (*data)[data_size++] = aid->sign_algorithm;
161 _gnutls_write_datum16 (&(*data)[data_size], signature);
162 data_size += signature.size + 2;
165 ret = data_size;
167 cleanup:
168 _gnutls_free_datum (&signature);
169 return ret;
173 static int
174 proc_srp_cert_server_kx (gnutls_session_t session, opaque * data,
175 size_t _data_size)
177 ssize_t ret;
178 int sigsize;
179 gnutls_datum_t vparams, signature;
180 ssize_t data_size;
181 cert_auth_info_t info;
182 gnutls_cert peer_cert;
183 opaque *p;
184 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
185 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
187 ret = _gnutls_proc_srp_server_kx (session, data, _data_size);
188 if (ret < 0)
189 return ret;
191 data_size = _data_size - ret;
193 info = _gnutls_get_auth_info (session);
194 if (info == NULL || info->ncerts == 0)
196 gnutls_assert ();
197 /* we need this in order to get peer's certificate */
198 return GNUTLS_E_INTERNAL_ERROR;
201 /* VERIFY SIGNATURE */
203 vparams.size = ret; /* all the data minus the signature */
204 vparams.data = data;
206 p = &data[vparams.size];
207 if (_gnutls_version_has_selectable_sighash (ver))
209 sign_algorithm_st aid;
211 DECR_LEN (data_size, 1);
212 aid.hash_algorithm = *p++;
213 DECR_LEN (data_size, 1);
214 aid.sign_algorithm = *p++;
215 sign_algo = _gnutls_tls_aid_to_sign (&aid);
216 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
218 gnutls_assert ();
219 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
223 DECR_LEN (data_size, 2);
224 sigsize = _gnutls_read_uint16 (p);
226 DECR_LEN (data_size, sigsize);
227 signature.data = &p[2];
228 signature.size = sigsize;
230 ret =
231 _gnutls_get_auth_info_gcert (&peer_cert,
232 session->security_parameters.cert_type,
233 info, CERT_NO_COPY);
235 if (ret < 0)
237 gnutls_assert ();
238 return ret;
241 ret =
242 _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature,
243 sign_algo);
245 _gnutls_gcert_deinit (&peer_cert);
246 if (ret < 0)
248 gnutls_assert ();
249 return ret;
252 return 0;
256 #endif /* ENABLE_SRP */