2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010 Free
3 * Software Foundation, Inc.
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"
35 #include "gnutls_num.h"
37 #include <gnutls_str.h>
38 #include <gnutls_datum.h>
41 const mod_auth_st srp_auth_struct = {
45 _gnutls_gen_srp_server_kx,
46 _gnutls_gen_srp_client_kx,
51 NULL, /* certificate */
52 _gnutls_proc_srp_server_kx,
53 _gnutls_proc_srp_client_kx,
59 #define _b session->key->b
60 #define B session->key->B
61 #define _a session->key->a
62 #define A session->key->A
63 #define N session->key->client_p
64 #define G session->key->client_g
65 #define V session->key->x
66 #define S session->key->KEY
68 /* Checks if b%n==0 which is a fatal srp error.
69 * Returns a proper error code in that case, and 0 when
73 check_b_mod_n (bigint_t b, bigint_t n)
78 r = _gnutls_mpi_mod (b, n);
83 return GNUTLS_E_MEMORY_ERROR;
86 ret = _gnutls_mpi_cmp_ui (r, 0);
88 _gnutls_mpi_release (&r);
93 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
99 /* Checks if a%n==0,+1,-1%n which is a fatal srp error.
100 * Returns a proper error code in that case, and 0 when
104 check_a_mod_n (bigint_t a, bigint_t n)
109 r = _gnutls_mpi_mod (a, n);
113 return GNUTLS_E_MEMORY_ERROR;
116 ret = _gnutls_mpi_cmp_ui (r, 0);
117 if (ret == 0) err = 1;
119 ret = _gnutls_mpi_cmp_ui (r, 1);
120 if (ret == 0) err = 1;
122 _gnutls_mpi_add_ui(r, r, 1);
123 ret = _gnutls_mpi_cmp (r, n);
124 if (ret == 0) err = 1;
126 _gnutls_mpi_release (&r);
131 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
138 /* Send the first key exchange message ( g, n, s) and append the verifier algorithm number
139 * Data is allocated by the caller, and should have data_size size.
142 _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
145 uint8_t *data_n, *data_s;
148 SRP_PWD_ENTRY *pwd_entry;
149 srp_server_auth_info_t info;
151 size_t n_b, tmp_size;
154 extension_priv_data_t epriv;
157 ret = _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SRP, &epriv);
158 if (ret < 0) /* peer didn't send a username */
161 return GNUTLS_E_UNKNOWN_SRP_USERNAME;
166 _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
167 sizeof (srp_server_auth_info_st), 1)) < 0)
173 info = _gnutls_get_auth_info (session);
174 username = info->username;
176 _gnutls_str_cpy (username, MAX_USERNAME_SIZE, priv->username);
178 ret = _gnutls_srp_pwd_read_entry (session, username, &pwd_entry);
186 /* copy from pwd_entry to local variables (actually in session) */
187 tmp_size = pwd_entry->g.size;
188 if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, tmp_size) < 0)
191 return GNUTLS_E_MPI_SCAN_FAILED;
194 tmp_size = pwd_entry->n.size;
195 if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, tmp_size) < 0)
198 return GNUTLS_E_MPI_SCAN_FAILED;
201 tmp_size = pwd_entry->v.size;
202 if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, tmp_size) < 0)
205 return GNUTLS_E_MPI_SCAN_FAILED;
208 /* Calculate: B = (k*v + g^b) % N
210 B = _gnutls_calc_srp_B (&_b, G, N, V);
214 return GNUTLS_E_MEMORY_ERROR;
217 if (_gnutls_mpi_print (B, NULL, &n_b) != GNUTLS_E_SHORT_MEMORY_BUFFER)
220 return GNUTLS_E_MPI_PRINT_FAILED;
224 /* Allocate size to hold the N, g, s, B
227 data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 +
228 pwd_entry->salt.size + 1) + (n_b + 2);
230 (*data) = gnutls_malloc (data_size);
234 return GNUTLS_E_MEMORY_ERROR;
240 _gnutls_write_datum16 (data_n, pwd_entry->n);
243 /* copy G (generator) to data
245 data_g = &data_n[2 + pwd_entry->n.size];
246 _gnutls_write_datum16 (data_g, pwd_entry->g);
251 data_s = &data_g[2 + pwd_entry->g.size];
252 _gnutls_write_datum8 (data_s, pwd_entry->salt);
258 data_b = &data_s[1 + pwd_entry->salt.size];
259 if (_gnutls_mpi_print (B, &data_b[2], &n_b) != 0)
262 return GNUTLS_E_MPI_PRINT_FAILED;
265 _gnutls_write_uint16 (n_b, data_b);
267 _gnutls_hard_log ("INT: SRP B[%d]: %s\n", (int) n_b,
268 _gnutls_bin2hex (&data_b[2], n_b, buf, sizeof (buf),
271 _gnutls_srp_entry_free (pwd_entry);
276 /* return A = g^a % N */
278 _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data)
283 char *username, *password;
285 gnutls_srp_client_credentials_t cred;
286 extension_priv_data_t epriv;
289 ret = _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SRP, &epriv);
290 if (ret < 0) /* peer didn't send a username */
293 return GNUTLS_E_UNKNOWN_SRP_USERNAME;
297 cred = (gnutls_srp_client_credentials_t)
298 _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
303 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
306 if (priv->username == NULL)
308 username = cred->username;
309 password = cred->password;
314 username = priv->username;
315 password = priv->password;
318 if (username == NULL || password == NULL)
321 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
326 if (G == NULL || N == NULL)
329 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
332 A = _gnutls_calc_srp_A (&_a, G, N);
336 return GNUTLS_E_MEMORY_ERROR;
339 /* Rest of SRP calculations
343 session->key->u = _gnutls_calc_srp_u (A, B, N);
344 if (session->key->u == NULL)
347 return GNUTLS_E_MEMORY_ERROR;
350 _gnutls_mpi_log ("SRP U: ", session->key->u);
352 /* S = (B - g^x) ^ (a + u * x) % N */
353 S = _gnutls_calc_srp_S2 (B, G, session->key->x, _a, session->key->u, N);
357 return GNUTLS_E_MEMORY_ERROR;
360 _gnutls_mpi_log ("SRP B: ", B);
362 _gnutls_mpi_release (&_b);
363 _gnutls_mpi_release (&V);
364 _gnutls_mpi_release (&session->key->u);
365 _gnutls_mpi_release (&B);
367 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
368 _gnutls_mpi_release (&S);
376 if (_gnutls_mpi_print (A, NULL, &n_a) != GNUTLS_E_SHORT_MEMORY_BUFFER)
379 return GNUTLS_E_MPI_PRINT_FAILED;
382 (*data) = gnutls_malloc (n_a + 2);
386 return GNUTLS_E_MEMORY_ERROR;
391 if (_gnutls_mpi_print (A, &data_a[2], &n_a) != 0)
394 return GNUTLS_E_MPI_PRINT_FAILED;
397 _gnutls_hard_log ("INT: SRP A[%d]: %s\n", (int) n_a,
398 _gnutls_bin2hex (&data_a[2], n_a, buf, sizeof (buf),
401 _gnutls_mpi_release (&A);
403 _gnutls_write_uint16 (n_a, data_a);
409 /* just read A and put it to session */
411 _gnutls_proc_srp_client_kx (gnutls_session_t session, opaque * data,
415 ssize_t data_size = _data_size;
418 DECR_LEN (data_size, 2);
419 _n_A = _gnutls_read_uint16 (&data[0]);
421 DECR_LEN (data_size, _n_A);
422 if (_gnutls_mpi_scan_nz (&A, &data[2], _n_A) || A == NULL)
425 return GNUTLS_E_MPI_SCAN_FAILED;
428 _gnutls_mpi_log ("SRP A: ", A);
429 _gnutls_mpi_log ("SRP B: ", B);
431 /* Checks if A % n == 0.
433 if ((ret = check_a_mod_n (A, N)) < 0)
439 /* Start the SRP calculations.
442 session->key->u = _gnutls_calc_srp_u (A, B, N);
443 if (session->key->u == NULL)
446 return GNUTLS_E_MEMORY_ERROR;
449 _gnutls_mpi_log ("SRP U: ", session->key->u);
451 /* S = (A * v^u) ^ b % N
453 S = _gnutls_calc_srp_S1 (A, _b, session->key->u, V, N);
457 return GNUTLS_E_MEMORY_ERROR;
460 _gnutls_mpi_log ("SRP S: ", S);
462 _gnutls_mpi_release (&A);
463 _gnutls_mpi_release (&_b);
464 _gnutls_mpi_release (&V);
465 _gnutls_mpi_release (&session->key->u);
466 _gnutls_mpi_release (&B);
468 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
469 _gnutls_mpi_release (&S);
482 /* Static parameters according to draft-ietf-tls-srp-07
483 * Note that if more parameters are added check_g_n()
484 * and _gnutls_srp_entry_free() should be changed.
486 static const unsigned char srp_params_1024[] = {
487 0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6,
488 0x9C, 0x33, 0xF8, 0x0A, 0xFA, 0x8F, 0xC5, 0xE8,
489 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B,
490 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76,
491 0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3,
492 0x38, 0x3B, 0x48, 0x13, 0xD6, 0x92, 0xC6, 0xE0,
493 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4,
494 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1,
495 0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6,
496 0xCE, 0x8E, 0xF4, 0xAD, 0x69, 0xB1, 0x5D, 0x49,
497 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
498 0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC,
499 0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0,
500 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E, 0xAA, 0x9A,
501 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B,
502 0x9F, 0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
505 static const unsigned char srp_generator = 0x02;
507 const gnutls_datum_t gnutls_srp_1024_group_prime = {
508 (void *) srp_params_1024, sizeof (srp_params_1024)
511 const gnutls_datum_t gnutls_srp_1024_group_generator = {
512 (void *) &srp_generator, sizeof (srp_generator)
515 static const unsigned char srp_params_1536[] = {
516 0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1,
517 0xF1, 0x2A, 0x86, 0x17, 0xA4, 0x7B, 0xBB, 0xDB, 0xA5,
518 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9,
519 0x61, 0x4B, 0x19, 0xCC, 0x4D, 0x5F, 0x4F, 0x5F, 0x55,
520 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
521 0x60, 0x7A, 0x29, 0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0,
522 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A, 0x22, 0xE8,
523 0xDC, 0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0,
524 0x81, 0x34, 0xB1, 0xC8, 0xB9, 0x79, 0x89, 0x14, 0x9B,
525 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54,
526 0x83, 0x81, 0xDB, 0xC5, 0xB1, 0xFC, 0x76, 0x4E, 0x3F,
527 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E,
528 0x2B, 0x9C, 0x8C, 0xF5, 0x6E, 0xDF, 0x01, 0x95, 0x39,
529 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24, 0xB7,
530 0xC4, 0x86, 0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F,
531 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7, 0xCC, 0xB7, 0xAE,
532 0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F,
533 0x8A, 0x2F, 0xE9, 0xB8, 0xB5, 0x29, 0x2E, 0x5A, 0x02,
534 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2,
535 0x8C, 0x24, 0x42, 0xC6, 0xF3, 0x15, 0x18, 0x0F, 0x93,
536 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
540 const gnutls_datum_t gnutls_srp_1536_group_prime = {
541 (void *) srp_params_1536, sizeof (srp_params_1536)
544 const gnutls_datum_t gnutls_srp_1536_group_generator = {
545 (void *) &srp_generator, sizeof (srp_generator)
548 static const unsigned char srp_params_2048[] = {
549 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1,
550 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72,
551 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92,
552 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB,
553 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
554 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03,
555 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD,
556 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
557 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66,
558 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18,
559 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79,
560 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A,
561 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5,
562 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14,
563 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80,
564 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
565 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B,
566 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45,
567 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A,
568 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB,
569 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
570 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE,
571 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08,
572 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
573 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94,
574 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE,
575 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3,
576 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F,
577 0x9E, 0x4A, 0xFF, 0x73
580 const gnutls_datum_t gnutls_srp_2048_group_prime = {
581 (void *) srp_params_2048, sizeof (srp_params_2048)
584 const gnutls_datum_t gnutls_srp_2048_group_generator = {
585 (void *) &srp_generator, sizeof (srp_generator)
589 /* Check if G and N are parameters from the SRP draft.
592 check_g_n (const opaque * g, size_t n_g, const opaque * n, size_t n_n)
595 if (n_g != 1 || g[0] != srp_generator)
598 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
601 if (n_n == sizeof (srp_params_1024) &&
602 memcmp (srp_params_1024, n, n_n) == 0)
607 if (n_n == sizeof (srp_params_1536) &&
608 memcmp (srp_params_1536, n, n_n) == 0)
613 if (n_n == sizeof (srp_params_2048) &&
614 memcmp (srp_params_2048, n, n_n) == 0)
620 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
623 /* Check if N is a prime and G a generator of the
624 * group. This is check only done if N is big enough.
625 * Otherwise only the included parameters must be used.
628 group_check_g_n (gnutls_session_t session, bigint_t g, bigint_t n)
630 bigint_t q = NULL, two = NULL, w = NULL;
633 if (_gnutls_mpi_get_nbits (n) < (session->internals.srp_prime_bits
634 ? session->internals.srp_prime_bits
638 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
641 /* N must be of the form N=2q+1
642 * where q is also a prime.
644 if (_gnutls_prime_check (n) != 0)
646 _gnutls_mpi_log ("no prime N: ", n);
648 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
651 two = _gnutls_mpi_new (4);
655 return GNUTLS_E_MEMORY_ERROR;
658 q = _gnutls_mpi_alloc_like (n);
662 ret = GNUTLS_E_MEMORY_ERROR;
668 _gnutls_mpi_sub_ui (q, n, 1);
670 /* q = q/2, remember that q is divisible by 2 (prime - 1)
672 _gnutls_mpi_set_ui (two, 2);
673 _gnutls_mpi_div (q, q, two);
675 if (_gnutls_prime_check (q) != 0)
677 /* N was not on the form N=2q+1, where q = prime
679 _gnutls_mpi_log ("no prime Q: ", q);
681 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
684 /* We also check whether g is a generator,
687 /* check if g < q < N
689 if (_gnutls_mpi_cmp (g, q) >= 0)
692 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
696 w = _gnutls_mpi_alloc_like (q);
700 ret = GNUTLS_E_MEMORY_ERROR;
704 /* check if g^q mod N == N-1
707 _gnutls_mpi_powm (w, g, q, n);
711 _gnutls_mpi_add_ui (w, w, 1);
713 if (_gnutls_mpi_cmp (w, n) != 0)
716 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
723 _gnutls_mpi_release (&q);
724 _gnutls_mpi_release (&two);
725 _gnutls_mpi_release (&w);
731 /* receive the key exchange message ( n, g, s, B)
734 _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data,
738 uint16_t n_g, n_n, n_b;
739 size_t _n_g, _n_n, _n_b;
740 const uint8_t *data_n;
741 const uint8_t *data_g;
742 const uint8_t *data_s;
743 const uint8_t *data_b;
745 opaque hd[SRP_MAX_HASH_SIZE];
746 char *username, *password;
747 ssize_t data_size = _data_size;
748 gnutls_srp_client_credentials_t cred;
749 extension_priv_data_t epriv;
752 ret = _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SRP, &epriv);
756 return GNUTLS_E_UNKNOWN_SRP_USERNAME;
760 cred = (gnutls_srp_client_credentials_t)
761 _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
766 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
769 if (priv->username == NULL)
771 username = cred->username;
772 password = cred->password;
776 username = priv->username;
777 password = priv->password;
780 if (username == NULL || password == NULL)
783 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
790 DECR_LEN (data_size, 2);
791 n_n = _gnutls_read_uint16 (&data[i]);
794 DECR_LEN (data_size, n_n);
800 DECR_LEN (data_size, 2);
801 n_g = _gnutls_read_uint16 (&data[i]);
804 DECR_LEN (data_size, n_g);
810 DECR_LEN (data_size, 1);
814 DECR_LEN (data_size, n_s);
820 DECR_LEN (data_size, 2);
821 n_b = _gnutls_read_uint16 (&data[i]);
824 DECR_LEN (data_size, n_b);
832 if (_gnutls_mpi_scan_nz (&N, data_n, _n_n) != 0)
835 return GNUTLS_E_MPI_SCAN_FAILED;
838 if (_gnutls_mpi_scan_nz (&G, data_g, _n_g) != 0)
841 return GNUTLS_E_MPI_SCAN_FAILED;
844 if (_gnutls_mpi_scan_nz (&B, data_b, _n_b) != 0)
847 return GNUTLS_E_MPI_SCAN_FAILED;
851 /* Check if the g and n are from the SRP
852 * draft. Otherwise check if N is a prime and G
855 if ((ret = check_g_n (data_g, _n_g, data_n, _n_n)) < 0)
857 _gnutls_x509_log ("Checking the SRP group parameters.\n");
858 if ((ret = group_check_g_n (session, G, N)) < 0)
865 /* Checks if b % n == 0
867 if ((ret = check_b_mod_n (B, N)) < 0)
874 /* generate x = SHA(s | SHA(U | ":" | p))
875 * (or the equivalent using bcrypt)
878 _gnutls_calc_srp_x (username, password, (opaque *) data_s, n_s,
885 if (_gnutls_mpi_scan_nz (&session->key->x, hd, _n_g) != 0)
888 return GNUTLS_E_MPI_SCAN_FAILED;
892 return i; /* return the processed data
893 * needed in auth_srp_rsa.
897 #endif /* ENABLE_SRP */