2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 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>
31 #include "gnutls_auth.h"
33 #include "gnutls_errors.h"
34 #include "gnutls_algorithms.h"
35 #include <gnutls_num.h>
36 #include <gnutls_extensions.h>
38 static int _gnutls_srp_unpack (gnutls_buffer_st
* ps
,
39 extension_priv_data_t
* _priv
);
40 static int _gnutls_srp_pack (extension_priv_data_t epriv
,
41 gnutls_buffer_st
* ps
);
42 static void _gnutls_srp_deinit_data (extension_priv_data_t epriv
);
43 static int _gnutls_srp_recv_params (gnutls_session_t state
,
44 const opaque
* data
, size_t data_size
);
45 static int _gnutls_srp_send_params (gnutls_session_t state
, opaque
* data
,
48 extension_entry_st ext_mod_srp
= {
50 .type
= GNUTLS_EXTENSION_SRP
,
51 .parse_type
= GNUTLS_EXT_TLS
,
53 .recv_func
= _gnutls_srp_recv_params
,
54 .send_func
= _gnutls_srp_send_params
,
55 .pack_func
= _gnutls_srp_pack
,
56 .unpack_func
= _gnutls_srp_unpack
,
57 .deinit_func
= _gnutls_srp_deinit_data
62 _gnutls_srp_recv_params (gnutls_session_t session
, const opaque
* data
,
66 ssize_t data_size
= _data_size
;
67 extension_priv_data_t epriv
;
70 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
75 DECR_LEN (data_size
, len
);
77 if (MAX_USERNAME_SIZE
< len
)
80 return GNUTLS_E_ILLEGAL_SRP_USERNAME
;
83 priv
= gnutls_calloc (1, sizeof (*priv
));
87 return GNUTLS_E_MEMORY_ERROR
;
90 priv
->username
= gnutls_malloc (len
+ 1);
93 memcpy (priv
->username
, &data
[1], len
);
95 priv
->username
[len
] = 0;
99 _gnutls_ext_set_session_data (session
, GNUTLS_EXTENSION_SRP
, epriv
);
105 /* returns data_size or a negative number on failure
106 * data is allocated locally
109 _gnutls_srp_send_params (gnutls_session_t session
, opaque
* data
,
113 extension_priv_data_t epriv
;
114 srp_ext_st
*priv
= NULL
;
115 char *username
= NULL
, *password
= NULL
;
118 if (_gnutls_kx_priority (session
, GNUTLS_KX_SRP
) < 0 &&
119 _gnutls_kx_priority (session
, GNUTLS_KX_SRP_DSS
) < 0 &&
120 _gnutls_kx_priority (session
, GNUTLS_KX_SRP_RSA
) < 0)
122 /* algorithm was not allowed in this session
127 /* this function sends the client extension data (username) */
128 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
130 gnutls_srp_client_credentials_t cred
= (gnutls_srp_client_credentials_t
)
131 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
136 priv
= gnutls_malloc (sizeof (*priv
));
140 return GNUTLS_E_MEMORY_ERROR
;
143 if (cred
->username
!= NULL
)
144 { /* send username */
145 len
= MIN (strlen (cred
->username
), 255);
147 if (data_size
< len
+ 1)
150 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
153 priv
->username
= strdup(cred
->username
);
154 if (priv
->username
== NULL
)
160 priv
->password
= strdup(cred
->password
);
161 if (priv
->password
== NULL
)
168 _gnutls_ext_set_session_data (session
, GNUTLS_EXTENSION_SRP
, epriv
);
170 data
[0] = (uint8_t) len
;
171 memcpy (&data
[1], cred
->username
, len
);
174 else if (cred
->get_function
!= NULL
)
179 if (cred
->get_function (session
, &username
, &password
) < 0
180 || username
== NULL
|| password
== NULL
)
183 return GNUTLS_E_ILLEGAL_SRP_USERNAME
;
186 len
= MIN (strlen (username
), 255);
188 if (data_size
< len
+ 1)
191 ret
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
195 priv
->username
= username
;
196 priv
->password
= password
;
199 _gnutls_ext_set_session_data (session
, GNUTLS_EXTENSION_SRP
, epriv
);
201 data
[0] = (uint8_t) len
;
202 memcpy (&data
[1], username
, len
);
209 gnutls_free(username
);
210 gnutls_free(password
);
217 _gnutls_srp_deinit_data (extension_priv_data_t epriv
)
219 srp_ext_st
*priv
= epriv
.ptr
;
221 gnutls_free (priv
->username
);
222 gnutls_free (priv
->password
);
227 _gnutls_srp_pack (extension_priv_data_t epriv
, gnutls_buffer_st
* ps
)
229 srp_ext_st
*priv
= epriv
.ptr
;
231 int password_len
= 0, username_len
= 0;
234 username_len
= strlen (priv
->username
);
237 password_len
= strlen (priv
->password
);
239 BUFFER_APPEND_PFX (ps
, priv
->username
, username_len
);
240 BUFFER_APPEND_PFX (ps
, priv
->password
, password_len
);
246 _gnutls_srp_unpack (gnutls_buffer_st
* ps
, extension_priv_data_t
* _priv
)
250 extension_priv_data_t epriv
;
251 gnutls_datum username
= { NULL
, 0 }, password
=
255 priv
= gnutls_calloc (1, sizeof (*priv
));
259 return GNUTLS_E_MEMORY_ERROR
;
262 BUFFER_POP_DATUM (ps
, &username
);
263 BUFFER_POP_DATUM (ps
, &password
);
265 priv
->username
= username
.data
;
266 priv
->password
= password
.data
;
274 _gnutls_free_datum (&username
);
275 _gnutls_free_datum (&password
);
280 #endif /* ENABLE_SRP */