2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 3 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 License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
28 #include "gnutls_auth.h"
30 #include "gnutls_errors.h"
31 #include "algorithms.h"
32 #include <gnutls_num.h>
33 #include <gnutls_extensions.h>
35 static int _gnutls_srp_unpack (gnutls_buffer_st
* ps
,
36 extension_priv_data_t
* _priv
);
37 static int _gnutls_srp_pack (extension_priv_data_t epriv
,
38 gnutls_buffer_st
* ps
);
39 static void _gnutls_srp_deinit_data (extension_priv_data_t epriv
);
40 static int _gnutls_srp_recv_params (gnutls_session_t state
,
41 const uint8_t * data
, size_t data_size
);
42 static int _gnutls_srp_send_params (gnutls_session_t state
, gnutls_buffer_st
* extdata
);
44 extension_entry_st ext_mod_srp
= {
46 .type
= GNUTLS_EXTENSION_SRP
,
47 .parse_type
= GNUTLS_EXT_TLS
,
49 .recv_func
= _gnutls_srp_recv_params
,
50 .send_func
= _gnutls_srp_send_params
,
51 .pack_func
= _gnutls_srp_pack
,
52 .unpack_func
= _gnutls_srp_unpack
,
53 .deinit_func
= _gnutls_srp_deinit_data
58 _gnutls_srp_recv_params (gnutls_session_t session
, const uint8_t * data
,
62 ssize_t data_size
= _data_size
;
63 extension_priv_data_t epriv
;
66 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
71 DECR_LEN (data_size
, len
);
73 if (MAX_USERNAME_SIZE
< len
)
76 return GNUTLS_E_ILLEGAL_SRP_USERNAME
;
79 priv
= gnutls_calloc (1, sizeof (*priv
));
83 return GNUTLS_E_MEMORY_ERROR
;
86 priv
->username
= gnutls_malloc (len
+ 1);
89 memcpy (priv
->username
, &data
[1], len
);
91 priv
->username
[len
] = 0;
95 _gnutls_ext_set_session_data (session
, GNUTLS_EXTENSION_SRP
, epriv
);
101 /* returns data_size or a negative number on failure
102 * data is allocated locally
105 _gnutls_srp_send_params (gnutls_session_t session
,
106 gnutls_buffer_st
* extdata
)
110 extension_priv_data_t epriv
;
111 srp_ext_st
*priv
= NULL
;
112 char *username
= NULL
, *password
= NULL
;
114 if (_gnutls_kx_priority (session
, GNUTLS_KX_SRP
) < 0 &&
115 _gnutls_kx_priority (session
, GNUTLS_KX_SRP_DSS
) < 0 &&
116 _gnutls_kx_priority (session
, GNUTLS_KX_SRP_RSA
) < 0)
118 /* algorithm was not allowed in this session
123 /* this function sends the client extension data (username) */
124 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
126 gnutls_srp_client_credentials_t cred
= (gnutls_srp_client_credentials_t
)
127 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
132 priv
= gnutls_malloc (sizeof (*priv
));
134 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
136 if (cred
->username
!= NULL
)
137 { /* send username */
138 len
= MIN (strlen (cred
->username
), 255);
140 ret
= _gnutls_buffer_append_data_prefix(extdata
, 8, cred
->username
, len
);
147 priv
->username
= strdup(cred
->username
);
148 if (priv
->username
== NULL
)
154 priv
->password
= strdup(cred
->password
);
155 if (priv
->password
== NULL
)
162 _gnutls_ext_set_session_data (session
, GNUTLS_EXTENSION_SRP
, epriv
);
166 else if (cred
->get_function
!= NULL
)
171 if (cred
->get_function (session
, &username
, &password
) < 0
172 || username
== NULL
|| password
== NULL
)
175 return GNUTLS_E_ILLEGAL_SRP_USERNAME
;
178 len
= MIN (strlen (username
), 255);
180 priv
->username
= username
;
181 priv
->password
= password
;
183 ret
= _gnutls_buffer_append_data_prefix(extdata
, 8, username
, len
);
186 ret
= gnutls_assert_val(ret
);
191 _gnutls_ext_set_session_data (session
, GNUTLS_EXTENSION_SRP
, epriv
);
199 gnutls_free (username
);
200 gnutls_free (password
);
207 _gnutls_srp_deinit_data (extension_priv_data_t epriv
)
209 srp_ext_st
*priv
= epriv
.ptr
;
211 gnutls_free (priv
->username
);
212 gnutls_free (priv
->password
);
217 _gnutls_srp_pack (extension_priv_data_t epriv
, gnutls_buffer_st
* ps
)
219 srp_ext_st
*priv
= epriv
.ptr
;
221 int password_len
= 0, username_len
= 0;
224 username_len
= strlen (priv
->username
);
227 password_len
= strlen (priv
->password
);
229 BUFFER_APPEND_PFX4 (ps
, priv
->username
, username_len
);
230 BUFFER_APPEND_PFX4 (ps
, priv
->password
, password_len
);
236 _gnutls_srp_unpack (gnutls_buffer_st
* ps
, extension_priv_data_t
* _priv
)
240 extension_priv_data_t epriv
;
241 gnutls_datum_t username
= { NULL
, 0 };
242 gnutls_datum_t password
= { NULL
, 0 };
244 priv
= gnutls_calloc (1, sizeof (*priv
));
248 return GNUTLS_E_MEMORY_ERROR
;
251 BUFFER_POP_DATUM (ps
, &username
);
252 BUFFER_POP_DATUM (ps
, &password
);
254 priv
->username
= (char*)username
.data
;
255 priv
->password
= (char*)password
.data
;
263 _gnutls_free_datum (&username
);
264 _gnutls_free_datum (&password
);
269 #endif /* ENABLE_SRP */