Guile: Fix `x509-certificate-dn-oid' and related functions.
[gnutls.git] / lib / auth_srp.c
blobe30c069caadb7b96abff700d2f101f5f1ccecebe
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
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_int.h"
33 #include "gnutls_srp.h"
34 #include "debug.h"
35 #include "gnutls_num.h"
36 #include "auth_srp.h"
37 #include <gnutls_str.h>
38 #include <gnutls_datum.h>
40 int _gnutls_gen_srp_server_kx (gnutls_session_t, opaque **);
41 int _gnutls_gen_srp_client_kx (gnutls_session_t, opaque **);
43 int _gnutls_proc_srp_server_kx (gnutls_session_t, opaque *, size_t);
44 int _gnutls_proc_srp_client_kx (gnutls_session_t, opaque *, size_t);
46 const mod_auth_st srp_auth_struct = {
47 "SRP",
48 NULL,
49 NULL,
50 _gnutls_gen_srp_server_kx,
51 _gnutls_gen_srp_client_kx,
52 NULL,
53 NULL,
55 NULL,
56 NULL, /* certificate */
57 _gnutls_proc_srp_server_kx,
58 _gnutls_proc_srp_client_kx,
59 NULL,
60 NULL
64 #define _b session->key->b
65 #define B session->key->B
66 #define _a session->key->a
67 #define A session->key->A
68 #define N session->key->client_p
69 #define G session->key->client_g
70 #define V session->key->x
71 #define S session->key->KEY
73 /* Checks if b%n==0 which is a fatal srp error.
74 * Returns a proper error code in that case, and 0 when
75 * all are ok.
77 inline static int
78 check_b_mod_n (mpi_t b, mpi_t n)
80 int ret;
81 mpi_t r = _gnutls_mpi_alloc_like (b);
83 if (r == NULL)
85 gnutls_assert ();
86 return GNUTLS_E_MEMORY_ERROR;
89 _gnutls_mpi_mod (r, b, n);
90 ret = _gnutls_mpi_cmp_ui (r, 0);
92 _gnutls_mpi_release (&r);
94 if (ret == 0)
96 gnutls_assert ();
97 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
100 return 0;
103 /* Checks if a%n==0,+1,-1%n which is a fatal srp error.
104 * Returns a proper error code in that case, and 0 when
105 * all are ok.
107 inline static int
108 check_a_mod_n (mpi_t a, mpi_t n)
110 int ret;
111 mpi_t r = _gnutls_mpi_alloc_like (a);
113 if (r == NULL)
115 gnutls_assert ();
116 return GNUTLS_E_MEMORY_ERROR;
119 _gnutls_mpi_mod (r, a, n);
120 ret = _gnutls_mpi_cmp_ui (r, 0);
122 _gnutls_mpi_release (&r);
124 if (ret == 0)
126 gnutls_assert ();
127 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
130 return 0;
134 /* Send the first key exchange message ( g, n, s) and append the verifier algorithm number
135 * Data is allocated by the caller, and should have data_size size.
138 _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
140 int ret;
141 uint8_t *data_n, *data_s;
142 uint8_t *data_g;
143 char *username;
144 SRP_PWD_ENTRY *pwd_entry;
145 srp_server_auth_info_t info;
146 ssize_t data_size;
147 size_t n_b, tmp_size;
148 char buf[64];
149 uint8_t *data_b;
151 if ((ret =
152 _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
153 sizeof (srp_server_auth_info_st), 1)) < 0)
155 gnutls_assert ();
156 return ret;
159 info = _gnutls_get_auth_info (session);
160 username = info->username;
162 _gnutls_str_cpy (username, MAX_SRP_USERNAME,
163 session->security_parameters.extensions.srp_username);
165 ret = _gnutls_srp_pwd_read_entry (session, username, &pwd_entry);
167 if (ret < 0)
169 gnutls_assert ();
170 return ret;
173 /* copy from pwd_entry to local variables (actually in session) */
174 if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, &pwd_entry->g.size) < 0)
176 gnutls_assert ();
177 return GNUTLS_E_MPI_SCAN_FAILED;
180 tmp_size = pwd_entry->n.size;
181 if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, &tmp_size) < 0)
183 gnutls_assert ();
184 return GNUTLS_E_MPI_SCAN_FAILED;
187 tmp_size = pwd_entry->v.size;
188 if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, &tmp_size) < 0)
190 gnutls_assert ();
191 return GNUTLS_E_MPI_SCAN_FAILED;
194 /* Calculate: B = (k*v + g^b) % N
196 B = _gnutls_calc_srp_B (&_b, G, N, V);
197 if (B == NULL)
199 gnutls_assert ();
200 return GNUTLS_E_MEMORY_ERROR;
203 if (_gnutls_mpi_print (NULL, &n_b, B) != 0)
205 gnutls_assert ();
206 return GNUTLS_E_MPI_PRINT_FAILED;
210 /* Allocate size to hold the N, g, s, B
213 data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 +
214 pwd_entry->salt.size + 1) + (n_b + 2);
216 (*data) = gnutls_malloc (data_size);
217 if ((*data) == NULL)
219 gnutls_assert ();
220 return GNUTLS_E_MEMORY_ERROR;
223 /* copy N (mod n)
225 data_n = *data;
226 _gnutls_write_datum16 (data_n, pwd_entry->n);
229 /* copy G (generator) to data
231 data_g = &data_n[2 + pwd_entry->n.size];
232 _gnutls_write_datum16 (data_g, pwd_entry->g);
235 /* copy the salt
237 data_s = &data_g[2 + pwd_entry->g.size];
238 _gnutls_write_datum8 (data_s, pwd_entry->salt);
241 /* Copy the B value
244 data_b = &data_s[1 + pwd_entry->salt.size];
245 if (_gnutls_mpi_print (&data_b[2], &n_b, B) != 0)
246 return GNUTLS_E_MPI_PRINT_FAILED;
247 _gnutls_write_uint16 (n_b, data_b);
249 _gnutls_hard_log ("INT: SRP B[%d]: %s\n", n_b,
250 _gnutls_bin2hex (&data_b[2], n_b, buf, sizeof (buf)));
252 _gnutls_srp_entry_free (pwd_entry);
254 return data_size;
257 /* return A = g^a % N */
259 _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data)
261 size_t n_a;
262 int ret;
263 uint8_t *data_a;
264 char *username, *password;
265 char buf[64];
266 gnutls_srp_client_credentials_t cred;
269 cred = (gnutls_srp_client_credentials_t)
270 _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
272 if (cred == NULL)
274 gnutls_assert ();
275 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
278 if (session->internals.srp_username == NULL)
280 username = cred->username;
281 password = cred->password;
283 else
285 username = session->internals.srp_username;
286 password = session->internals.srp_password;
289 if (username == NULL || password == NULL)
291 gnutls_assert ();
292 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
295 /* calc A = g^a % N
297 if (G == NULL || N == NULL)
299 gnutls_assert ();
300 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
303 A = _gnutls_calc_srp_A (&_a, G, N);
304 if (A == NULL)
306 gnutls_assert ();
307 return GNUTLS_E_MEMORY_ERROR;
310 /* Rest of SRP calculations
313 /* calculate u */
314 session->key->u = _gnutls_calc_srp_u (A, B, N);
315 if (session->key->u == NULL)
317 gnutls_assert ();
318 return GNUTLS_E_MEMORY_ERROR;
321 _gnutls_dump_mpi ("SRP U: ", session->key->u);
323 /* S = (B - g^x) ^ (a + u * x) % N */
324 S = _gnutls_calc_srp_S2 (B, G, session->key->x, _a, session->key->u, N);
325 if (S == NULL)
327 gnutls_assert ();
328 return GNUTLS_E_MEMORY_ERROR;
331 _gnutls_dump_mpi ("SRP B: ", B);
333 _gnutls_mpi_release (&_b);
334 _gnutls_mpi_release (&V);
335 _gnutls_mpi_release (&session->key->u);
336 _gnutls_mpi_release (&B);
338 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
339 _gnutls_mpi_release (&S);
341 if (ret < 0)
342 return ret;
344 if (_gnutls_mpi_print (NULL, &n_a, A) != 0)
346 gnutls_assert ();
347 return GNUTLS_E_MPI_PRINT_FAILED;
350 (*data) = gnutls_malloc (n_a + 2);
351 if ((*data) == NULL)
353 gnutls_assert ();
354 return GNUTLS_E_MEMORY_ERROR;
357 /* copy A */
358 data_a = (*data);
359 if (_gnutls_mpi_print (&data_a[2], &n_a, A) != 0)
361 gnutls_free (*data);
362 return GNUTLS_E_MPI_PRINT_FAILED;
364 _gnutls_hard_log ("INT: SRP A[%d]: %s\n", n_a,
365 _gnutls_bin2hex (&data_a[2], n_a, buf, sizeof (buf)));
367 _gnutls_mpi_release (&A);
369 _gnutls_write_uint16 (n_a, data_a);
371 return n_a + 2;
375 /* just read A and put it to session */
377 _gnutls_proc_srp_client_kx (gnutls_session_t session, opaque * data,
378 size_t _data_size)
380 size_t _n_A;
381 ssize_t data_size = _data_size;
382 int ret;
384 DECR_LEN (data_size, 2);
385 _n_A = _gnutls_read_uint16 (&data[0]);
387 DECR_LEN (data_size, _n_A);
388 if (_gnutls_mpi_scan_nz (&A, &data[2], &_n_A) || A == NULL)
390 gnutls_assert ();
391 return GNUTLS_E_MPI_SCAN_FAILED;
394 _gnutls_dump_mpi ("SRP A: ", A);
395 _gnutls_dump_mpi ("SRP B: ", B);
397 /* Checks if A % n == 0.
399 if ((ret = check_a_mod_n (A, N)) < 0)
401 gnutls_assert ();
402 return ret;
405 /* Start the SRP calculations.
406 * - Calculate u
408 session->key->u = _gnutls_calc_srp_u (A, B, N);
409 if (session->key->u == NULL)
411 gnutls_assert ();
412 return GNUTLS_E_MEMORY_ERROR;
415 _gnutls_dump_mpi ("SRP U: ", session->key->u);
417 /* S = (A * v^u) ^ b % N
419 S = _gnutls_calc_srp_S1 (A, _b, session->key->u, V, N);
420 if (S == NULL)
422 gnutls_assert ();
423 return GNUTLS_E_MEMORY_ERROR;
426 _gnutls_dump_mpi ("SRP S: ", S);
428 _gnutls_mpi_release (&A);
429 _gnutls_mpi_release (&_b);
430 _gnutls_mpi_release (&V);
431 _gnutls_mpi_release (&session->key->u);
432 _gnutls_mpi_release (&B);
434 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
435 _gnutls_mpi_release (&S);
437 if (ret < 0)
439 gnutls_assert ();
440 return ret;
443 return 0;
448 /* Static parameters according to draft-ietf-tls-srp-07
449 * Note that if more parameters are added check_g_n()
450 * and _gnutls_srp_entry_free() should be changed.
452 static const unsigned char srp_params_1024[] = {
453 0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6,
454 0x9C, 0x33, 0xF8, 0x0A, 0xFA, 0x8F, 0xC5, 0xE8,
455 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B,
456 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76,
457 0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3,
458 0x38, 0x3B, 0x48, 0x13, 0xD6, 0x92, 0xC6, 0xE0,
459 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4,
460 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1,
461 0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6,
462 0xCE, 0x8E, 0xF4, 0xAD, 0x69, 0xB1, 0x5D, 0x49,
463 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
464 0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC,
465 0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0,
466 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E, 0xAA, 0x9A,
467 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B,
468 0x9F, 0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
471 static const unsigned char srp_generator = 0x02;
473 const gnutls_datum_t gnutls_srp_1024_group_prime = {
474 (void *) srp_params_1024, sizeof (srp_params_1024)
476 const gnutls_datum_t gnutls_srp_1024_group_generator = {
477 (void *) &srp_generator, sizeof (srp_generator)
480 static const unsigned char srp_params_1536[] = {
481 0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1,
482 0xF1, 0x2A, 0x86, 0x17, 0xA4, 0x7B, 0xBB, 0xDB, 0xA5,
483 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9,
484 0x61, 0x4B, 0x19, 0xCC, 0x4D, 0x5F, 0x4F, 0x5F, 0x55,
485 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
486 0x60, 0x7A, 0x29, 0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0,
487 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A, 0x22, 0xE8,
488 0xDC, 0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0,
489 0x81, 0x34, 0xB1, 0xC8, 0xB9, 0x79, 0x89, 0x14, 0x9B,
490 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54,
491 0x83, 0x81, 0xDB, 0xC5, 0xB1, 0xFC, 0x76, 0x4E, 0x3F,
492 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E,
493 0x2B, 0x9C, 0x8C, 0xF5, 0x6E, 0xDF, 0x01, 0x95, 0x39,
494 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24, 0xB7,
495 0xC4, 0x86, 0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F,
496 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7, 0xCC, 0xB7, 0xAE,
497 0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F,
498 0x8A, 0x2F, 0xE9, 0xB8, 0xB5, 0x29, 0x2E, 0x5A, 0x02,
499 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2,
500 0x8C, 0x24, 0x42, 0xC6, 0xF3, 0x15, 0x18, 0x0F, 0x93,
501 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
502 0x35, 0xF9, 0xBB
505 const gnutls_datum_t gnutls_srp_1536_group_prime = {
506 (void *) srp_params_1536, sizeof (srp_params_1536)
508 const gnutls_datum_t gnutls_srp_1536_group_generator = {
509 (void *) &srp_generator, sizeof (srp_generator)
512 static const unsigned char srp_params_2048[] = {
513 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1,
514 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72,
515 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92,
516 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB,
517 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
518 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03,
519 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD,
520 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
521 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66,
522 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18,
523 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79,
524 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A,
525 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5,
526 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14,
527 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80,
528 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
529 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B,
530 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45,
531 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A,
532 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB,
533 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
534 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE,
535 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08,
536 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
537 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94,
538 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE,
539 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3,
540 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F,
541 0x9E, 0x4A, 0xFF, 0x73
544 const gnutls_datum_t gnutls_srp_2048_group_prime = {
545 (void *) srp_params_2048, sizeof (srp_params_2048)
547 const gnutls_datum_t gnutls_srp_2048_group_generator = {
548 (void *) &srp_generator, sizeof (srp_generator)
552 /* Check if G and N are parameters from the SRP draft.
554 static int
555 check_g_n (const opaque * g, size_t n_g, const opaque * n, size_t n_n)
558 if (n_g != 1 || g[0] != srp_generator)
559 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
561 if (n_n == sizeof (srp_params_1024) &&
562 memcmp (srp_params_1024, n, n_n) == 0)
564 return 0;
567 if (n_n == sizeof (srp_params_1536) &&
568 memcmp (srp_params_1536, n, n_n) == 0)
570 return 0;
573 if (n_n == sizeof (srp_params_2048) &&
574 memcmp (srp_params_2048, n, n_n) == 0)
576 return 0;
579 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
582 /* Check if N is a prime and G a generator of the
583 * group. This is check only done if N is big enough.
584 * Otherwise only the included parameters must be used.
586 static int
587 group_check_g_n (mpi_t g, mpi_t n)
589 mpi_t q = NULL, two = NULL, w = NULL;
590 int ret;
592 if (_gnutls_mpi_get_nbits (n) < 2048)
594 gnutls_assert ();
595 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
598 /* N must be of the form N=2q+1
599 * where q is also a prime.
601 if (_gnutls_prime_check (n, 0) != 0)
603 _gnutls_dump_mpi ("no prime N: ", n);
604 gnutls_assert ();
605 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
608 two = _gnutls_mpi_new (4);
609 if (two == NULL)
611 gnutls_assert ();
612 return GNUTLS_E_MEMORY_ERROR;
615 q = _gnutls_mpi_alloc_like (n);
616 if (q == NULL)
618 gnutls_assert ();
619 ret = GNUTLS_E_MEMORY_ERROR;
620 goto error;
623 /* q = n-1
625 _gnutls_mpi_sub_ui (q, n, 1);
627 /* q = q/2, remember that q is divisible by 2 (prime - 1)
629 _gnutls_mpi_set_ui (two, 2);
630 _gnutls_mpi_div (q, NULL, q, two, 0);
632 if (_gnutls_prime_check (q, 0) != 0)
634 /* N was not on the form N=2q+1, where q = prime
636 _gnutls_dump_mpi ("no prime Q: ", q);
637 gnutls_assert ();
638 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
641 /* We also check whether g is a generator,
644 /* check if g < q < N
646 if (_gnutls_mpi_cmp (g, q) >= 0)
648 gnutls_assert ();
649 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
650 goto error;
653 w = _gnutls_mpi_alloc_like (q);
654 if (w == NULL)
656 gnutls_assert ();
657 ret = GNUTLS_E_MEMORY_ERROR;
658 goto error;
661 /* check if g^q mod N == N-1
662 * w = g^q mod N
664 _gnutls_mpi_powm (w, g, q, n);
666 /* w++
668 _gnutls_mpi_add_ui (w, w, 1);
670 if (_gnutls_mpi_cmp (w, n) != 0)
672 gnutls_assert ();
673 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
674 goto error;
677 ret = 0;
679 error:
680 _gnutls_mpi_release (&q);
681 _gnutls_mpi_release (&two);
682 _gnutls_mpi_release (&w);
684 return ret;
688 /* receive the key exchange message ( n, g, s, B)
691 _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data,
692 size_t _data_size)
694 uint8_t n_s;
695 uint16_t n_g, n_n, n_b;
696 size_t _n_s, _n_g, _n_n, _n_b;
697 const uint8_t *data_n;
698 const uint8_t *data_g;
699 const uint8_t *data_s;
700 const uint8_t *data_b;
701 int i, ret;
702 opaque hd[SRP_MAX_HASH_SIZE];
703 char *username, *password;
704 ssize_t data_size = _data_size;
705 gnutls_srp_client_credentials_t cred;
707 cred = (gnutls_srp_client_credentials_t)
708 _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);
710 if (cred == NULL)
712 gnutls_assert ();
713 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
716 if (session->internals.srp_username == NULL)
718 username = cred->username;
719 password = cred->password;
721 else
723 username = session->internals.srp_username;
724 password = session->internals.srp_password;
727 if (username == NULL || password == NULL)
729 gnutls_assert ();
730 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
733 i = 0;
735 /* Read N
737 DECR_LEN (data_size, 2);
738 n_n = _gnutls_read_uint16 (&data[i]);
739 i += 2;
741 DECR_LEN (data_size, n_n);
742 data_n = &data[i];
743 i += n_n;
745 /* Read G
747 DECR_LEN (data_size, 2);
748 n_g = _gnutls_read_uint16 (&data[i]);
749 i += 2;
751 DECR_LEN (data_size, n_g);
752 data_g = &data[i];
753 i += n_g;
755 /* Read salt
757 DECR_LEN (data_size, 1);
758 n_s = data[i];
759 i += 1;
761 DECR_LEN (data_size, n_s);
762 data_s = &data[i];
763 i += n_s;
765 /* Read B
767 DECR_LEN (data_size, 2);
768 n_b = _gnutls_read_uint16 (&data[i]);
769 i += 2;
771 DECR_LEN (data_size, n_b);
772 data_b = &data[i];
773 i += n_b;
775 _n_s = n_s;
776 _n_g = n_g;
777 _n_n = n_n;
778 _n_b = n_b;
780 if (_gnutls_mpi_scan_nz (&N, data_n, &_n_n) != 0)
782 gnutls_assert ();
783 return GNUTLS_E_MPI_SCAN_FAILED;
786 if (_gnutls_mpi_scan_nz (&G, data_g, &_n_g) != 0)
788 gnutls_assert ();
789 return GNUTLS_E_MPI_SCAN_FAILED;
792 if (_gnutls_mpi_scan_nz (&B, data_b, &_n_b) != 0)
794 gnutls_assert ();
795 return GNUTLS_E_MPI_SCAN_FAILED;
799 /* Check if the g and n are from the SRP
800 * draft. Otherwise check if N is a prime and G
801 * a generator.
803 if ((ret = check_g_n (data_g, _n_g, data_n, _n_n)) < 0)
805 _gnutls_x509_log ("Checking the SRP group parameters.\n");
806 if ((ret = group_check_g_n (G, N)) < 0)
808 gnutls_assert ();
809 return ret;
813 /* Checks if b % n == 0
815 if ((ret = check_b_mod_n (B, N)) < 0)
817 gnutls_assert ();
818 return ret;
822 /* generate x = SHA(s | SHA(U | ":" | p))
823 * (or the equivalent using bcrypt)
825 if ((ret =
826 _gnutls_calc_srp_x (username, password, (opaque *) data_s, n_s,
827 &_n_g, hd)) < 0)
829 gnutls_assert ();
830 return ret;
833 if (_gnutls_mpi_scan_nz (&session->key->x, hd, &_n_g) != 0)
835 gnutls_assert ();
836 return GNUTLS_E_MPI_SCAN_FAILED;
840 return i; /* return the processed data
841 * needed in auth_srp_rsa.
845 #endif /* ENABLE_SRP */