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);
118 _gnutls_mpi_release (&r
);
123 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
130 /* Send the first key exchange message ( g, n, s) and append the verifier algorithm number
131 * Data is allocated by the caller, and should have data_size size.
134 _gnutls_gen_srp_server_kx (gnutls_session_t session
, opaque
** data
)
137 uint8_t *data_n
, *data_s
;
140 SRP_PWD_ENTRY
*pwd_entry
;
141 srp_server_auth_info_t info
;
143 size_t n_b
, tmp_size
;
146 extension_priv_data_t epriv
;
149 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
150 if (ret
< 0) /* peer didn't send a username */
153 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
158 _gnutls_auth_info_set (session
, GNUTLS_CRD_SRP
,
159 sizeof (srp_server_auth_info_st
), 1)) < 0)
165 info
= _gnutls_get_auth_info (session
);
166 username
= info
->username
;
168 _gnutls_str_cpy (username
, MAX_USERNAME_SIZE
, priv
->username
);
170 ret
= _gnutls_srp_pwd_read_entry (session
, username
, &pwd_entry
);
178 /* copy from pwd_entry to local variables (actually in session) */
179 tmp_size
= pwd_entry
->g
.size
;
180 if (_gnutls_mpi_scan_nz (&G
, pwd_entry
->g
.data
, tmp_size
) < 0)
183 return GNUTLS_E_MPI_SCAN_FAILED
;
186 tmp_size
= pwd_entry
->n
.size
;
187 if (_gnutls_mpi_scan_nz (&N
, pwd_entry
->n
.data
, tmp_size
) < 0)
190 return GNUTLS_E_MPI_SCAN_FAILED
;
193 tmp_size
= pwd_entry
->v
.size
;
194 if (_gnutls_mpi_scan_nz (&V
, pwd_entry
->v
.data
, tmp_size
) < 0)
197 return GNUTLS_E_MPI_SCAN_FAILED
;
200 /* Calculate: B = (k*v + g^b) % N
202 B
= _gnutls_calc_srp_B (&_b
, G
, N
, V
);
206 return GNUTLS_E_MEMORY_ERROR
;
209 if (_gnutls_mpi_print (B
, NULL
, &n_b
) != GNUTLS_E_SHORT_MEMORY_BUFFER
)
212 return GNUTLS_E_MPI_PRINT_FAILED
;
216 /* Allocate size to hold the N, g, s, B
219 data_size
= (pwd_entry
->n
.size
+ 2 + pwd_entry
->g
.size
+ 2 +
220 pwd_entry
->salt
.size
+ 1) + (n_b
+ 2);
222 (*data
) = gnutls_malloc (data_size
);
226 return GNUTLS_E_MEMORY_ERROR
;
232 _gnutls_write_datum16 (data_n
, pwd_entry
->n
);
235 /* copy G (generator) to data
237 data_g
= &data_n
[2 + pwd_entry
->n
.size
];
238 _gnutls_write_datum16 (data_g
, pwd_entry
->g
);
243 data_s
= &data_g
[2 + pwd_entry
->g
.size
];
244 _gnutls_write_datum8 (data_s
, pwd_entry
->salt
);
250 data_b
= &data_s
[1 + pwd_entry
->salt
.size
];
251 if (_gnutls_mpi_print (B
, &data_b
[2], &n_b
) != 0)
254 return GNUTLS_E_MPI_PRINT_FAILED
;
257 _gnutls_write_uint16 (n_b
, data_b
);
259 _gnutls_hard_log ("INT: SRP B[%d]: %s\n", (int) n_b
,
260 _gnutls_bin2hex (&data_b
[2], n_b
, buf
, sizeof (buf
),
263 _gnutls_srp_entry_free (pwd_entry
);
268 /* return A = g^a % N */
270 _gnutls_gen_srp_client_kx (gnutls_session_t session
, opaque
** data
)
275 char *username
, *password
;
277 gnutls_srp_client_credentials_t cred
;
278 extension_priv_data_t epriv
;
281 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
282 if (ret
< 0) /* peer didn't send a username */
285 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
289 cred
= (gnutls_srp_client_credentials_t
)
290 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
295 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
298 if (priv
->username
== NULL
)
300 username
= cred
->username
;
301 password
= cred
->password
;
306 username
= priv
->username
;
307 password
= priv
->password
;
310 if (username
== NULL
|| password
== NULL
)
313 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
318 if (G
== NULL
|| N
== NULL
)
321 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
324 A
= _gnutls_calc_srp_A (&_a
, G
, N
);
328 return GNUTLS_E_MEMORY_ERROR
;
331 /* Rest of SRP calculations
335 session
->key
->u
= _gnutls_calc_srp_u (A
, B
, N
);
336 if (session
->key
->u
== NULL
)
339 return GNUTLS_E_MEMORY_ERROR
;
342 _gnutls_mpi_log ("SRP U: ", session
->key
->u
);
344 /* S = (B - g^x) ^ (a + u * x) % N */
345 S
= _gnutls_calc_srp_S2 (B
, G
, session
->key
->x
, _a
, session
->key
->u
, N
);
349 return GNUTLS_E_MEMORY_ERROR
;
352 _gnutls_mpi_log ("SRP B: ", B
);
354 _gnutls_mpi_release (&_b
);
355 _gnutls_mpi_release (&V
);
356 _gnutls_mpi_release (&session
->key
->u
);
357 _gnutls_mpi_release (&B
);
359 ret
= _gnutls_mpi_dprint (session
->key
->KEY
, &session
->key
->key
);
360 _gnutls_mpi_release (&S
);
368 if (_gnutls_mpi_print (A
, NULL
, &n_a
) != GNUTLS_E_SHORT_MEMORY_BUFFER
)
371 return GNUTLS_E_MPI_PRINT_FAILED
;
374 (*data
) = gnutls_malloc (n_a
+ 2);
378 return GNUTLS_E_MEMORY_ERROR
;
383 if (_gnutls_mpi_print (A
, &data_a
[2], &n_a
) != 0)
386 return GNUTLS_E_MPI_PRINT_FAILED
;
389 _gnutls_hard_log ("INT: SRP A[%d]: %s\n", (int) n_a
,
390 _gnutls_bin2hex (&data_a
[2], n_a
, buf
, sizeof (buf
),
393 _gnutls_mpi_release (&A
);
395 _gnutls_write_uint16 (n_a
, data_a
);
401 /* just read A and put it to session */
403 _gnutls_proc_srp_client_kx (gnutls_session_t session
, opaque
* data
,
407 ssize_t data_size
= _data_size
;
410 DECR_LEN (data_size
, 2);
411 _n_A
= _gnutls_read_uint16 (&data
[0]);
413 DECR_LEN (data_size
, _n_A
);
414 if (_gnutls_mpi_scan_nz (&A
, &data
[2], _n_A
) || A
== NULL
)
417 return GNUTLS_E_MPI_SCAN_FAILED
;
420 _gnutls_mpi_log ("SRP A: ", A
);
421 _gnutls_mpi_log ("SRP B: ", B
);
423 /* Checks if A % n == 0.
425 if ((ret
= check_a_mod_n (A
, N
)) < 0)
431 /* Start the SRP calculations.
434 session
->key
->u
= _gnutls_calc_srp_u (A
, B
, N
);
435 if (session
->key
->u
== NULL
)
438 return GNUTLS_E_MEMORY_ERROR
;
441 _gnutls_mpi_log ("SRP U: ", session
->key
->u
);
443 /* S = (A * v^u) ^ b % N
445 S
= _gnutls_calc_srp_S1 (A
, _b
, session
->key
->u
, V
, N
);
449 return GNUTLS_E_MEMORY_ERROR
;
452 _gnutls_mpi_log ("SRP S: ", S
);
454 _gnutls_mpi_release (&A
);
455 _gnutls_mpi_release (&_b
);
456 _gnutls_mpi_release (&V
);
457 _gnutls_mpi_release (&session
->key
->u
);
458 _gnutls_mpi_release (&B
);
460 ret
= _gnutls_mpi_dprint (session
->key
->KEY
, &session
->key
->key
);
461 _gnutls_mpi_release (&S
);
474 /* Static parameters according to draft-ietf-tls-srp-07
475 * Note that if more parameters are added check_g_n()
476 * and _gnutls_srp_entry_free() should be changed.
478 static const unsigned char srp_params_1024
[] = {
479 0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6,
480 0x9C, 0x33, 0xF8, 0x0A, 0xFA, 0x8F, 0xC5, 0xE8,
481 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B,
482 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76,
483 0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3,
484 0x38, 0x3B, 0x48, 0x13, 0xD6, 0x92, 0xC6, 0xE0,
485 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4,
486 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1,
487 0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6,
488 0xCE, 0x8E, 0xF4, 0xAD, 0x69, 0xB1, 0x5D, 0x49,
489 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
490 0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC,
491 0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0,
492 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E, 0xAA, 0x9A,
493 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B,
494 0x9F, 0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
497 static const unsigned char srp_generator
= 0x02;
499 const gnutls_datum_t gnutls_srp_1024_group_prime
= {
500 (void *) srp_params_1024
, sizeof (srp_params_1024
)
503 const gnutls_datum_t gnutls_srp_1024_group_generator
= {
504 (void *) &srp_generator
, sizeof (srp_generator
)
507 static const unsigned char srp_params_1536
[] = {
508 0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1,
509 0xF1, 0x2A, 0x86, 0x17, 0xA4, 0x7B, 0xBB, 0xDB, 0xA5,
510 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9,
511 0x61, 0x4B, 0x19, 0xCC, 0x4D, 0x5F, 0x4F, 0x5F, 0x55,
512 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
513 0x60, 0x7A, 0x29, 0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0,
514 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A, 0x22, 0xE8,
515 0xDC, 0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0,
516 0x81, 0x34, 0xB1, 0xC8, 0xB9, 0x79, 0x89, 0x14, 0x9B,
517 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54,
518 0x83, 0x81, 0xDB, 0xC5, 0xB1, 0xFC, 0x76, 0x4E, 0x3F,
519 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E,
520 0x2B, 0x9C, 0x8C, 0xF5, 0x6E, 0xDF, 0x01, 0x95, 0x39,
521 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24, 0xB7,
522 0xC4, 0x86, 0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F,
523 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7, 0xCC, 0xB7, 0xAE,
524 0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F,
525 0x8A, 0x2F, 0xE9, 0xB8, 0xB5, 0x29, 0x2E, 0x5A, 0x02,
526 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2,
527 0x8C, 0x24, 0x42, 0xC6, 0xF3, 0x15, 0x18, 0x0F, 0x93,
528 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
532 const gnutls_datum_t gnutls_srp_1536_group_prime
= {
533 (void *) srp_params_1536
, sizeof (srp_params_1536
)
536 const gnutls_datum_t gnutls_srp_1536_group_generator
= {
537 (void *) &srp_generator
, sizeof (srp_generator
)
540 static const unsigned char srp_params_2048
[] = {
541 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1,
542 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72,
543 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92,
544 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB,
545 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
546 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03,
547 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD,
548 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
549 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66,
550 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18,
551 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79,
552 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A,
553 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5,
554 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14,
555 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80,
556 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
557 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B,
558 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45,
559 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A,
560 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB,
561 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
562 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE,
563 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08,
564 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
565 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94,
566 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE,
567 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3,
568 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F,
569 0x9E, 0x4A, 0xFF, 0x73
572 const gnutls_datum_t gnutls_srp_2048_group_prime
= {
573 (void *) srp_params_2048
, sizeof (srp_params_2048
)
576 const gnutls_datum_t gnutls_srp_2048_group_generator
= {
577 (void *) &srp_generator
, sizeof (srp_generator
)
581 /* Check if G and N are parameters from the SRP draft.
584 check_g_n (const opaque
* g
, size_t n_g
, const opaque
* n
, size_t n_n
)
587 if (n_g
!= 1 || g
[0] != srp_generator
)
590 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
593 if (n_n
== sizeof (srp_params_1024
) &&
594 memcmp (srp_params_1024
, n
, n_n
) == 0)
599 if (n_n
== sizeof (srp_params_1536
) &&
600 memcmp (srp_params_1536
, n
, n_n
) == 0)
605 if (n_n
== sizeof (srp_params_2048
) &&
606 memcmp (srp_params_2048
, n
, n_n
) == 0)
612 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
615 /* Check if N is a prime and G a generator of the
616 * group. This is check only done if N is big enough.
617 * Otherwise only the included parameters must be used.
620 group_check_g_n (gnutls_session_t session
, bigint_t g
, bigint_t n
)
622 bigint_t q
= NULL
, two
= NULL
, w
= NULL
;
625 if (_gnutls_mpi_get_nbits (n
) < (session
->internals
.srp_prime_bits
626 ? session
->internals
.srp_prime_bits
630 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
633 /* N must be of the form N=2q+1
634 * where q is also a prime.
636 if (_gnutls_prime_check (n
) != 0)
638 _gnutls_mpi_log ("no prime N: ", n
);
640 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
643 two
= _gnutls_mpi_new (4);
647 return GNUTLS_E_MEMORY_ERROR
;
650 q
= _gnutls_mpi_alloc_like (n
);
654 ret
= GNUTLS_E_MEMORY_ERROR
;
660 _gnutls_mpi_sub_ui (q
, n
, 1);
662 /* q = q/2, remember that q is divisible by 2 (prime - 1)
664 _gnutls_mpi_set_ui (two
, 2);
665 _gnutls_mpi_div (q
, q
, two
);
667 if (_gnutls_prime_check (q
) != 0)
669 /* N was not on the form N=2q+1, where q = prime
671 _gnutls_mpi_log ("no prime Q: ", q
);
673 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
676 /* We also check whether g is a generator,
679 /* check if g < q < N
681 if (_gnutls_mpi_cmp (g
, q
) >= 0)
684 ret
= GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
688 w
= _gnutls_mpi_alloc_like (q
);
692 ret
= GNUTLS_E_MEMORY_ERROR
;
696 /* check if g^q mod N == N-1
699 _gnutls_mpi_powm (w
, g
, q
, n
);
703 _gnutls_mpi_add_ui (w
, w
, 1);
705 if (_gnutls_mpi_cmp (w
, n
) != 0)
708 ret
= GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
715 _gnutls_mpi_release (&q
);
716 _gnutls_mpi_release (&two
);
717 _gnutls_mpi_release (&w
);
723 /* receive the key exchange message ( n, g, s, B)
726 _gnutls_proc_srp_server_kx (gnutls_session_t session
, opaque
* data
,
730 uint16_t n_g
, n_n
, n_b
;
731 size_t _n_g
, _n_n
, _n_b
;
732 const uint8_t *data_n
;
733 const uint8_t *data_g
;
734 const uint8_t *data_s
;
735 const uint8_t *data_b
;
737 opaque hd
[SRP_MAX_HASH_SIZE
];
738 char *username
, *password
;
739 ssize_t data_size
= _data_size
;
740 gnutls_srp_client_credentials_t cred
;
741 extension_priv_data_t epriv
;
744 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
748 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
752 cred
= (gnutls_srp_client_credentials_t
)
753 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
758 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
761 if (priv
->username
== NULL
)
763 username
= cred
->username
;
764 password
= cred
->password
;
768 username
= priv
->username
;
769 password
= priv
->password
;
772 if (username
== NULL
|| password
== NULL
)
775 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
782 DECR_LEN (data_size
, 2);
783 n_n
= _gnutls_read_uint16 (&data
[i
]);
786 DECR_LEN (data_size
, n_n
);
792 DECR_LEN (data_size
, 2);
793 n_g
= _gnutls_read_uint16 (&data
[i
]);
796 DECR_LEN (data_size
, n_g
);
802 DECR_LEN (data_size
, 1);
806 DECR_LEN (data_size
, n_s
);
812 DECR_LEN (data_size
, 2);
813 n_b
= _gnutls_read_uint16 (&data
[i
]);
816 DECR_LEN (data_size
, n_b
);
824 if (_gnutls_mpi_scan_nz (&N
, data_n
, _n_n
) != 0)
827 return GNUTLS_E_MPI_SCAN_FAILED
;
830 if (_gnutls_mpi_scan_nz (&G
, data_g
, _n_g
) != 0)
833 return GNUTLS_E_MPI_SCAN_FAILED
;
836 if (_gnutls_mpi_scan_nz (&B
, data_b
, _n_b
) != 0)
839 return GNUTLS_E_MPI_SCAN_FAILED
;
843 /* Check if the g and n are from the SRP
844 * draft. Otherwise check if N is a prime and G
847 if ((ret
= check_g_n (data_g
, _n_g
, data_n
, _n_n
)) < 0)
849 _gnutls_x509_log ("Checking the SRP group parameters.\n");
850 if ((ret
= group_check_g_n (session
, G
, N
)) < 0)
857 /* Checks if b % n == 0
859 if ((ret
= check_b_mod_n (B
, N
)) < 0)
866 /* generate x = SHA(s | SHA(U | ":" | p))
867 * (or the equivalent using bcrypt)
870 _gnutls_calc_srp_x (username
, password
, (opaque
*) data_s
, n_s
,
877 if (_gnutls_mpi_scan_nz (&session
->key
->x
, hd
, _n_g
) != 0)
880 return GNUTLS_E_MPI_SCAN_FAILED
;
884 return i
; /* return the processed data
885 * needed in auth_srp_rsa.
889 #endif /* ENABLE_SRP */