2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2010 Free Software
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,
26 #include <gnutls_int.h>
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"
36 #include "gnutls_num.h"
38 #include <gnutls_str.h>
39 #include <auth_cert.h>
40 #include <gnutls_datum.h>
41 #include <gnutls_sig.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
= {
51 _gnutls_gen_cert_server_certificate
,
53 gen_srp_cert_server_kx
,
54 _gnutls_gen_srp_client_kx
,
58 _gnutls_proc_cert_server_certificate
,
59 NULL
, /* certificate */
60 proc_srp_cert_server_kx
,
61 _gnutls_proc_srp_client_kx
,
66 const mod_auth_st srp_dss_auth_struct
= {
68 _gnutls_gen_cert_server_certificate
,
70 gen_srp_cert_server_kx
,
71 _gnutls_gen_srp_client_kx
,
75 _gnutls_proc_cert_server_certificate
,
76 NULL
, /* certificate */
77 proc_srp_cert_server_kx
,
78 _gnutls_proc_srp_client_kx
,
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
);
102 ddata
.size
= data_size
;
104 cred
= (gnutls_certificate_credentials_t
)
105 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
109 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
112 /* find the appropriate certificate */
114 _gnutls_get_selected_cert (session
, &apr_cert_list
,
115 &apr_cert_list_length
, &apr_pkey
)) < 0)
122 _gnutls_handshake_sign_data (session
, &apr_cert_list
[0],
123 apr_pkey
, &ddata
, &signature
,
131 *data
= gnutls_realloc_fast (*data
, data_size
+ signature
.size
+ 4);
134 _gnutls_free_datum (&signature
);
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
;
149 aid
= _gnutls_sign_to_tls_aid (sign_algo
);
153 ret
= GNUTLS_E_UNKNOWN_ALGORITHM
;
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;
168 _gnutls_free_datum (&signature
);
174 proc_srp_cert_server_kx (gnutls_session_t session
, opaque
* data
,
179 gnutls_datum_t vparams
, signature
;
181 cert_auth_info_t info
;
182 gnutls_cert peer_cert
;
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
);
191 data_size
= _data_size
- ret
;
193 info
= _gnutls_get_auth_info (session
);
194 if (info
== NULL
|| info
->ncerts
== 0)
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 */
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
)
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
;
231 _gnutls_get_auth_info_gcert (&peer_cert
,
232 session
->security_parameters
.cert_type
,
242 _gnutls_handshake_verify_data (session
, &peer_cert
, &vparams
, &signature
,
245 _gnutls_gcert_deinit (&peer_cert
);
256 #endif /* ENABLE_SRP */