Fix use of deprecated types, for now and the future.
[gnutls.git] / lib / auth_srp.c
blob634749c19642a5022e3c20c28e5abea8caddd984
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008, 2009 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 #include <gnutls_int.h>
27 #ifdef ENABLE_SRP
29 #include "gnutls_errors.h"
30 #include "auth_srp_passwd.h"
31 #include "gnutls_auth.h"
32 #include "gnutls_auth.h"
33 #include "gnutls_srp.h"
34 #include "gnutls_num.h"
35 #include "auth_srp.h"
36 #include <gnutls_str.h>
37 #include <gnutls_datum.h>
39 const mod_auth_st srp_auth_struct = {
40 "SRP",
41 NULL,
42 NULL,
43 _gnutls_gen_srp_server_kx,
44 _gnutls_gen_srp_client_kx,
45 NULL,
46 NULL,
48 NULL,
49 NULL, /* certificate */
50 _gnutls_proc_srp_server_kx,
51 _gnutls_proc_srp_client_kx,
52 NULL,
53 NULL
57 #define _b session->key->b
58 #define B session->key->B
59 #define _a session->key->a
60 #define A session->key->A
61 #define N session->key->client_p
62 #define G session->key->client_g
63 #define V session->key->x
64 #define S session->key->KEY
66 /* Checks if b%n==0 which is a fatal srp error.
67 * Returns a proper error code in that case, and 0 when
68 * all are ok.
70 inline static int
71 check_b_mod_n (bigint_t b, bigint_t n)
73 int ret;
74 bigint_t r;
76 r = _gnutls_mpi_mod (b, n);
78 if (r == NULL)
80 gnutls_assert ();
81 return GNUTLS_E_MEMORY_ERROR;
84 ret = _gnutls_mpi_cmp_ui (r, 0);
86 _gnutls_mpi_release (&r);
88 if (ret == 0)
90 gnutls_assert ();
91 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
94 return 0;
97 /* Checks if a%n==0,+1,-1%n which is a fatal srp error.
98 * Returns a proper error code in that case, and 0 when
99 * all are ok.
101 inline static int
102 check_a_mod_n (bigint_t a, bigint_t n)
104 int ret;
105 bigint_t r;
107 r = _gnutls_mpi_mod (a, n);
108 if (r == NULL)
110 gnutls_assert ();
111 return GNUTLS_E_MEMORY_ERROR;
114 ret = _gnutls_mpi_cmp_ui (r, 0);
116 _gnutls_mpi_release (&r);
118 if (ret == 0)
120 gnutls_assert ();
121 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
124 return 0;
128 /* Send the first key exchange message ( g, n, s) and append the verifier algorithm number
129 * Data is allocated by the caller, and should have data_size size.
132 _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
134 int ret;
135 uint8_t *data_n, *data_s;
136 uint8_t *data_g;
137 char *username;
138 SRP_PWD_ENTRY *pwd_entry;
139 srp_server_auth_info_t info;
140 ssize_t data_size;
141 size_t n_b, tmp_size;
142 char buf[64];
143 uint8_t *data_b;
145 if ((ret =
146 _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
147 sizeof (srp_server_auth_info_st), 1)) < 0)
149 gnutls_assert ();
150 return ret;
153 info = _gnutls_get_auth_info (session);
154 username = info->username;
156 _gnutls_str_cpy (username, MAX_SRP_USERNAME,
157 session->security_parameters.extensions.srp_username);
159 ret = _gnutls_srp_pwd_read_entry (session, username, &pwd_entry);
161 if (ret < 0)
163 gnutls_assert ();
164 return ret;
167 /* copy from pwd_entry to local variables (actually in session) */
168 tmp_size = pwd_entry->g.size;
169 if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, tmp_size) < 0)
171 gnutls_assert ();
172 return GNUTLS_E_MPI_SCAN_FAILED;
175 tmp_size = pwd_entry->n.size;
176 if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, tmp_size) < 0)
178 gnutls_assert ();
179 return GNUTLS_E_MPI_SCAN_FAILED;
182 tmp_size = pwd_entry->v.size;
183 if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, tmp_size) < 0)
185 gnutls_assert ();
186 return GNUTLS_E_MPI_SCAN_FAILED;
189 /* Calculate: B = (k*v + g^b) % N
191 B = _gnutls_calc_srp_B (&_b, G, N, V);
192 if (B == NULL)
194 gnutls_assert ();
195 return GNUTLS_E_MEMORY_ERROR;
198 if (_gnutls_mpi_print (B, NULL, &n_b) != 0)
200 gnutls_assert ();
201 return GNUTLS_E_MPI_PRINT_FAILED;
205 /* Allocate size to hold the N, g, s, B
208 data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 +
209 pwd_entry->salt.size + 1) + (n_b + 2);
211 (*data) = gnutls_malloc (data_size);
212 if ((*data) == NULL)
214 gnutls_assert ();
215 return GNUTLS_E_MEMORY_ERROR;
218 /* copy N (mod n)
220 data_n = *data;
221 _gnutls_write_datum16 (data_n, pwd_entry->n);
224 /* copy G (generator) to data
226 data_g = &data_n[2 + pwd_entry->n.size];
227 _gnutls_write_datum16 (data_g, pwd_entry->g);
230 /* copy the salt
232 data_s = &data_g[2 + pwd_entry->g.size];
233 _gnutls_write_datum8 (data_s, pwd_entry->salt);
236 /* Copy the B value
239 data_b = &data_s[1 + pwd_entry->salt.size];
240 if (_gnutls_mpi_print (B, &data_b[2], &n_b) != 0)
242 gnutls_assert ();
243 return GNUTLS_E_MPI_PRINT_FAILED;
246 _gnutls_write_uint16 (n_b, data_b);
248 _gnutls_hard_log ("INT: SRP B[%d]: %s\n", (int)n_b,
249 _gnutls_bin2hex (&data_b[2], n_b, buf, sizeof (buf)));
251 _gnutls_srp_entry_free (pwd_entry);
253 return data_size;
256 /* return A = g^a % N */
258 _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data)
260 size_t n_a;
261 int ret;
262 uint8_t *data_a;
263 char *username, *password;
264 char buf[64];
265 gnutls_srp_client_credentials_t cred;
268 cred = (gnutls_srp_client_credentials_t)
269 _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
271 if (cred == NULL)
273 gnutls_assert ();
274 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
277 if (session->internals.srp_username == NULL)
279 username = cred->username;
280 password = cred->password;
282 else
284 username = session->internals.srp_username;
285 password = session->internals.srp_password;
288 if (username == NULL || password == NULL)
290 gnutls_assert ();
291 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
294 /* calc A = g^a % N
296 if (G == NULL || N == NULL)
298 gnutls_assert ();
299 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
302 A = _gnutls_calc_srp_A (&_a, G, N);
303 if (A == NULL)
305 gnutls_assert ();
306 return GNUTLS_E_MEMORY_ERROR;
309 /* Rest of SRP calculations
312 /* calculate u */
313 session->key->u = _gnutls_calc_srp_u (A, B, N);
314 if (session->key->u == NULL)
316 gnutls_assert ();
317 return GNUTLS_E_MEMORY_ERROR;
320 _gnutls_mpi_log ("SRP U: ", session->key->u);
322 /* S = (B - g^x) ^ (a + u * x) % N */
323 S = _gnutls_calc_srp_S2 (B, G, session->key->x, _a, session->key->u, N);
324 if (S == NULL)
326 gnutls_assert ();
327 return GNUTLS_E_MEMORY_ERROR;
330 _gnutls_mpi_log ("SRP B: ", B);
332 _gnutls_mpi_release (&_b);
333 _gnutls_mpi_release (&V);
334 _gnutls_mpi_release (&session->key->u);
335 _gnutls_mpi_release (&B);
337 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
338 _gnutls_mpi_release (&S);
340 if (ret < 0)
342 gnutls_assert ();
343 return ret;
346 if (_gnutls_mpi_print (A, NULL, &n_a) != 0)
348 gnutls_assert ();
349 return GNUTLS_E_MPI_PRINT_FAILED;
352 (*data) = gnutls_malloc (n_a + 2);
353 if ((*data) == NULL)
355 gnutls_assert ();
356 return GNUTLS_E_MEMORY_ERROR;
359 /* copy A */
360 data_a = (*data);
361 if (_gnutls_mpi_print (A, &data_a[2], &n_a) != 0)
363 gnutls_free (*data);
364 return GNUTLS_E_MPI_PRINT_FAILED;
367 _gnutls_hard_log ("INT: SRP A[%d]: %s\n", (int)n_a,
368 _gnutls_bin2hex (&data_a[2], n_a, buf, sizeof (buf)));
370 _gnutls_mpi_release (&A);
372 _gnutls_write_uint16 (n_a, data_a);
374 return n_a + 2;
378 /* just read A and put it to session */
380 _gnutls_proc_srp_client_kx (gnutls_session_t session, opaque * data,
381 size_t _data_size)
383 size_t _n_A;
384 ssize_t data_size = _data_size;
385 int ret;
387 DECR_LEN (data_size, 2);
388 _n_A = _gnutls_read_uint16 (&data[0]);
390 DECR_LEN (data_size, _n_A);
391 if (_gnutls_mpi_scan_nz (&A, &data[2], _n_A) || A == NULL)
393 gnutls_assert ();
394 return GNUTLS_E_MPI_SCAN_FAILED;
397 _gnutls_mpi_log ("SRP A: ", A);
398 _gnutls_mpi_log ("SRP B: ", B);
400 /* Checks if A % n == 0.
402 if ((ret = check_a_mod_n (A, N)) < 0)
404 gnutls_assert ();
405 return ret;
408 /* Start the SRP calculations.
409 * - Calculate u
411 session->key->u = _gnutls_calc_srp_u (A, B, N);
412 if (session->key->u == NULL)
414 gnutls_assert ();
415 return GNUTLS_E_MEMORY_ERROR;
418 _gnutls_mpi_log ("SRP U: ", session->key->u);
420 /* S = (A * v^u) ^ b % N
422 S = _gnutls_calc_srp_S1 (A, _b, session->key->u, V, N);
423 if (S == NULL)
425 gnutls_assert ();
426 return GNUTLS_E_MEMORY_ERROR;
429 _gnutls_mpi_log ("SRP S: ", S);
431 _gnutls_mpi_release (&A);
432 _gnutls_mpi_release (&_b);
433 _gnutls_mpi_release (&V);
434 _gnutls_mpi_release (&session->key->u);
435 _gnutls_mpi_release (&B);
437 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
438 _gnutls_mpi_release (&S);
440 if (ret < 0)
442 gnutls_assert ();
443 return ret;
446 return 0;
451 /* Static parameters according to draft-ietf-tls-srp-07
452 * Note that if more parameters are added check_g_n()
453 * and _gnutls_srp_entry_free() should be changed.
455 static const unsigned char srp_params_1024[] = {
456 0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6,
457 0x9C, 0x33, 0xF8, 0x0A, 0xFA, 0x8F, 0xC5, 0xE8,
458 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B,
459 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76,
460 0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3,
461 0x38, 0x3B, 0x48, 0x13, 0xD6, 0x92, 0xC6, 0xE0,
462 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4,
463 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1,
464 0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6,
465 0xCE, 0x8E, 0xF4, 0xAD, 0x69, 0xB1, 0x5D, 0x49,
466 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
467 0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC,
468 0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0,
469 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E, 0xAA, 0x9A,
470 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B,
471 0x9F, 0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
474 static const unsigned char srp_generator = 0x02;
476 const gnutls_datum_t gnutls_srp_1024_group_prime = {
477 (void *) srp_params_1024, sizeof (srp_params_1024)
480 const gnutls_datum_t gnutls_srp_1024_group_generator = {
481 (void *) &srp_generator, sizeof (srp_generator)
484 static const unsigned char srp_params_1536[] = {
485 0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1,
486 0xF1, 0x2A, 0x86, 0x17, 0xA4, 0x7B, 0xBB, 0xDB, 0xA5,
487 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9,
488 0x61, 0x4B, 0x19, 0xCC, 0x4D, 0x5F, 0x4F, 0x5F, 0x55,
489 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
490 0x60, 0x7A, 0x29, 0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0,
491 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A, 0x22, 0xE8,
492 0xDC, 0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0,
493 0x81, 0x34, 0xB1, 0xC8, 0xB9, 0x79, 0x89, 0x14, 0x9B,
494 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54,
495 0x83, 0x81, 0xDB, 0xC5, 0xB1, 0xFC, 0x76, 0x4E, 0x3F,
496 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E,
497 0x2B, 0x9C, 0x8C, 0xF5, 0x6E, 0xDF, 0x01, 0x95, 0x39,
498 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24, 0xB7,
499 0xC4, 0x86, 0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F,
500 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7, 0xCC, 0xB7, 0xAE,
501 0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F,
502 0x8A, 0x2F, 0xE9, 0xB8, 0xB5, 0x29, 0x2E, 0x5A, 0x02,
503 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2,
504 0x8C, 0x24, 0x42, 0xC6, 0xF3, 0x15, 0x18, 0x0F, 0x93,
505 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
506 0x35, 0xF9, 0xBB
509 const gnutls_datum_t gnutls_srp_1536_group_prime = {
510 (void *) srp_params_1536, sizeof (srp_params_1536)
513 const gnutls_datum_t gnutls_srp_1536_group_generator = {
514 (void *) &srp_generator, sizeof (srp_generator)
517 static const unsigned char srp_params_2048[] = {
518 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1,
519 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72,
520 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92,
521 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB,
522 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
523 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03,
524 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD,
525 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
526 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66,
527 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18,
528 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79,
529 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A,
530 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5,
531 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14,
532 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80,
533 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
534 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B,
535 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45,
536 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A,
537 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB,
538 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
539 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE,
540 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08,
541 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
542 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94,
543 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE,
544 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3,
545 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F,
546 0x9E, 0x4A, 0xFF, 0x73
549 const gnutls_datum_t gnutls_srp_2048_group_prime = {
550 (void *) srp_params_2048, sizeof (srp_params_2048)
553 const gnutls_datum_t gnutls_srp_2048_group_generator = {
554 (void *) &srp_generator, sizeof (srp_generator)
558 /* Check if G and N are parameters from the SRP draft.
560 static int
561 check_g_n (const opaque * g, size_t n_g, const opaque * n, size_t n_n)
564 if (n_g != 1 || g[0] != srp_generator)
566 gnutls_assert ();
567 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
570 if (n_n == sizeof (srp_params_1024) &&
571 memcmp (srp_params_1024, n, n_n) == 0)
573 return 0;
576 if (n_n == sizeof (srp_params_1536) &&
577 memcmp (srp_params_1536, n, n_n) == 0)
579 return 0;
582 if (n_n == sizeof (srp_params_2048) &&
583 memcmp (srp_params_2048, n, n_n) == 0)
585 return 0;
588 gnutls_assert ();
589 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
592 /* Check if N is a prime and G a generator of the
593 * group. This is check only done if N is big enough.
594 * Otherwise only the included parameters must be used.
596 static int
597 group_check_g_n (gnutls_session_t session, bigint_t g, bigint_t n)
599 bigint_t q = NULL, two = NULL, w = NULL;
600 int ret;
602 if (_gnutls_mpi_get_nbits (n) < (session->internals.srp_prime_bits
603 ? session->internals.srp_prime_bits
604 : 2048))
606 gnutls_assert ();
607 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
610 /* N must be of the form N=2q+1
611 * where q is also a prime.
613 if (_gnutls_prime_check (n) != 0)
615 _gnutls_mpi_log ("no prime N: ", n);
616 gnutls_assert ();
617 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
620 two = _gnutls_mpi_new (4);
621 if (two == NULL)
623 gnutls_assert ();
624 return GNUTLS_E_MEMORY_ERROR;
627 q = _gnutls_mpi_alloc_like (n);
628 if (q == NULL)
630 gnutls_assert ();
631 ret = GNUTLS_E_MEMORY_ERROR;
632 goto error;
635 /* q = n-1
637 _gnutls_mpi_sub_ui (q, n, 1);
639 /* q = q/2, remember that q is divisible by 2 (prime - 1)
641 _gnutls_mpi_set_ui (two, 2);
642 _gnutls_mpi_div (q, q, two);
644 if (_gnutls_prime_check (q) != 0)
646 /* N was not on the form N=2q+1, where q = prime
648 _gnutls_mpi_log ("no prime Q: ", q);
649 gnutls_assert ();
650 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
653 /* We also check whether g is a generator,
656 /* check if g < q < N
658 if (_gnutls_mpi_cmp (g, q) >= 0)
660 gnutls_assert ();
661 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
662 goto error;
665 w = _gnutls_mpi_alloc_like (q);
666 if (w == NULL)
668 gnutls_assert ();
669 ret = GNUTLS_E_MEMORY_ERROR;
670 goto error;
673 /* check if g^q mod N == N-1
674 * w = g^q mod N
676 _gnutls_mpi_powm (w, g, q, n);
678 /* w++
680 _gnutls_mpi_add_ui (w, w, 1);
682 if (_gnutls_mpi_cmp (w, n) != 0)
684 gnutls_assert ();
685 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
686 goto error;
689 ret = 0;
691 error:
692 _gnutls_mpi_release (&q);
693 _gnutls_mpi_release (&two);
694 _gnutls_mpi_release (&w);
696 return ret;
700 /* receive the key exchange message ( n, g, s, B)
703 _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data,
704 size_t _data_size)
706 uint8_t n_s;
707 uint16_t n_g, n_n, n_b;
708 size_t _n_s, _n_g, _n_n, _n_b;
709 const uint8_t *data_n;
710 const uint8_t *data_g;
711 const uint8_t *data_s;
712 const uint8_t *data_b;
713 int i, ret;
714 opaque hd[SRP_MAX_HASH_SIZE];
715 char *username, *password;
716 ssize_t data_size = _data_size;
717 gnutls_srp_client_credentials_t cred;
719 cred = (gnutls_srp_client_credentials_t)
720 _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
722 if (cred == NULL)
724 gnutls_assert ();
725 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
728 if (session->internals.srp_username == NULL)
730 username = cred->username;
731 password = cred->password;
733 else
735 username = session->internals.srp_username;
736 password = session->internals.srp_password;
739 if (username == NULL || password == NULL)
741 gnutls_assert ();
742 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
745 i = 0;
747 /* Read N
749 DECR_LEN (data_size, 2);
750 n_n = _gnutls_read_uint16 (&data[i]);
751 i += 2;
753 DECR_LEN (data_size, n_n);
754 data_n = &data[i];
755 i += n_n;
757 /* Read G
759 DECR_LEN (data_size, 2);
760 n_g = _gnutls_read_uint16 (&data[i]);
761 i += 2;
763 DECR_LEN (data_size, n_g);
764 data_g = &data[i];
765 i += n_g;
767 /* Read salt
769 DECR_LEN (data_size, 1);
770 n_s = data[i];
771 i += 1;
773 DECR_LEN (data_size, n_s);
774 data_s = &data[i];
775 i += n_s;
777 /* Read B
779 DECR_LEN (data_size, 2);
780 n_b = _gnutls_read_uint16 (&data[i]);
781 i += 2;
783 DECR_LEN (data_size, n_b);
784 data_b = &data[i];
785 i += n_b;
787 _n_s = n_s;
788 _n_g = n_g;
789 _n_n = n_n;
790 _n_b = n_b;
792 if (_gnutls_mpi_scan_nz (&N, data_n, _n_n) != 0)
794 gnutls_assert ();
795 return GNUTLS_E_MPI_SCAN_FAILED;
798 if (_gnutls_mpi_scan_nz (&G, data_g, _n_g) != 0)
800 gnutls_assert ();
801 return GNUTLS_E_MPI_SCAN_FAILED;
804 if (_gnutls_mpi_scan_nz (&B, data_b, _n_b) != 0)
806 gnutls_assert ();
807 return GNUTLS_E_MPI_SCAN_FAILED;
811 /* Check if the g and n are from the SRP
812 * draft. Otherwise check if N is a prime and G
813 * a generator.
815 if ((ret = check_g_n (data_g, _n_g, data_n, _n_n)) < 0)
817 _gnutls_x509_log ("Checking the SRP group parameters.\n");
818 if ((ret = group_check_g_n (session, G, N)) < 0)
820 gnutls_assert ();
821 return ret;
825 /* Checks if b % n == 0
827 if ((ret = check_b_mod_n (B, N)) < 0)
829 gnutls_assert ();
830 return ret;
834 /* generate x = SHA(s | SHA(U | ":" | p))
835 * (or the equivalent using bcrypt)
837 if ((ret =
838 _gnutls_calc_srp_x (username, password, (opaque *) data_s, n_s,
839 &_n_g, hd)) < 0)
841 gnutls_assert ();
842 return ret;
845 if (_gnutls_mpi_scan_nz (&session->key->x, hd, _n_g) != 0)
847 gnutls_assert ();
848 return GNUTLS_E_MPI_SCAN_FAILED;
852 return i; /* return the processed data
853 * needed in auth_srp_rsa.
857 #endif /* ENABLE_SRP */