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
;
116 if (_gnutls_kx_priority (session
, GNUTLS_KX_SRP
) < 0 &&
117 _gnutls_kx_priority (session
, GNUTLS_KX_SRP_DSS
) < 0 &&
118 _gnutls_kx_priority (session
, GNUTLS_KX_SRP_RSA
) < 0)
120 /* algorithm was not allowed in this session
125 /* this function sends the client extension data (username) */
126 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
128 gnutls_srp_client_credentials_t cred
= (gnutls_srp_client_credentials_t
)
129 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
134 if (cred
->username
!= NULL
)
135 { /* send username */
136 len
= MIN (strlen (cred
->username
), 255);
138 if (data_size
< len
+ 1)
141 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
144 data
[0] = (uint8_t) len
;
145 memcpy (&data
[1], cred
->username
, len
);
148 else if (cred
->get_function
!= NULL
)
152 char *username
= NULL
, *password
= NULL
;
154 if (cred
->get_function (session
, &username
, &password
) < 0
155 || username
== NULL
|| password
== NULL
)
158 return GNUTLS_E_ILLEGAL_SRP_USERNAME
;
161 len
= MIN (strlen (username
), 255);
163 if (data_size
< len
+ 1)
165 gnutls_free (username
);
166 gnutls_free (password
);
168 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
171 priv
= gnutls_malloc (sizeof (*priv
));
175 return GNUTLS_E_MEMORY_ERROR
;
178 priv
->username
= username
;
179 priv
->password
= password
;
182 _gnutls_ext_set_session_data (session
, GNUTLS_EXTENSION_SRP
, epriv
);
184 data
[0] = (uint8_t) len
;
185 memcpy (&data
[1], username
, len
);
193 _gnutls_srp_deinit_data (extension_priv_data_t epriv
)
195 srp_ext_st
*priv
= epriv
.ptr
;
197 gnutls_free (priv
->username
);
198 gnutls_free (priv
->password
);
203 _gnutls_srp_pack (extension_priv_data_t epriv
, gnutls_buffer_st
* ps
)
205 srp_ext_st
*priv
= epriv
.ptr
;
207 int password_len
= 0, username_len
= 0;
210 username_len
= strlen (priv
->username
);
213 password_len
= strlen (priv
->password
);
215 BUFFER_APPEND_PFX (ps
, priv
->username
, username_len
);
216 BUFFER_APPEND_PFX (ps
, priv
->password
, password_len
);
222 _gnutls_srp_unpack (gnutls_buffer_st
* ps
, extension_priv_data_t
* _priv
)
226 extension_priv_data_t epriv
;
227 gnutls_datum username
= { NULL
, 0 }, password
=
231 priv
= gnutls_calloc (1, sizeof (*priv
));
235 return GNUTLS_E_MEMORY_ERROR
;
238 BUFFER_POP_DATUM (ps
, &username
);
239 BUFFER_POP_DATUM (ps
, &password
);
241 priv
->username
= username
.data
;
242 priv
->password
= password
.data
;
250 _gnutls_free_datum (&username
);
251 _gnutls_free_datum (&password
);
256 #endif /* ENABLE_SRP */