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 library 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>
27 #include <gnutls_errors.h>
29 #include <gnutls_state.h>
33 #include <gnutls_srp.h>
34 #include <auth_srp_passwd.h>
35 #include <gnutls_mpi.h>
36 #include <gnutls_num.h>
37 #include <gnutls_helper.h>
42 /* Here functions for SRP (like g^x mod n) are defined
46 _gnutls_srp_gx (opaque
* text
, size_t textsize
, opaque
** result
,
47 bigint_t g
, bigint_t prime
, gnutls_alloc_function galloc_func
)
52 if (_gnutls_mpi_scan_nz (&x
, text
, textsize
))
55 return GNUTLS_E_MPI_SCAN_FAILED
;
58 e
= _gnutls_mpi_alloc_like (prime
);
62 _gnutls_mpi_release (&x
);
63 return GNUTLS_E_MEMORY_ERROR
;
66 /* e = g^x mod prime (n) */
67 _gnutls_mpi_powm (e
, g
, x
, prime
);
68 _gnutls_mpi_release (&x
);
70 _gnutls_mpi_print (e
, NULL
, &result_size
);
73 *result
= galloc_func (result_size
);
74 if ((*result
) == NULL
)
75 return GNUTLS_E_MEMORY_ERROR
;
77 _gnutls_mpi_print (e
, *result
, &result_size
);
80 _gnutls_mpi_release (&e
);
88 * Choose a random value b and calculate B = (k* v + g^b) % N.
89 * where k == SHA1(N|g)
90 * Return: B and if ret_b is not NULL b.
93 _gnutls_calc_srp_B (bigint_t
* ret_b
, bigint_t g
, bigint_t n
, bigint_t v
)
95 bigint_t tmpB
= NULL
, tmpV
= NULL
;
96 bigint_t b
= NULL
, B
= NULL
, k
= NULL
;
100 /* calculate: B = (k*v + g^b) % N
102 bits
= _gnutls_mpi_get_nbits (n
);
104 tmpV
= _gnutls_mpi_alloc_like (n
);
112 b
= _gnutls_mpi_randomize (NULL
, bits
, GNUTLS_RND_RANDOM
);
114 tmpB
= _gnutls_mpi_new (bits
);
121 B
= _gnutls_mpi_new (bits
);
128 k
= _gnutls_calc_srp_u (n
, g
, n
);
135 _gnutls_mpi_mulm (tmpV
, k
, v
, n
);
136 _gnutls_mpi_powm (tmpB
, g
, b
, n
);
138 _gnutls_mpi_addm (B
, tmpV
, tmpB
, n
);
140 _gnutls_mpi_release (&k
);
141 _gnutls_mpi_release (&tmpB
);
142 _gnutls_mpi_release (&tmpV
);
147 _gnutls_mpi_release (&b
);
152 _gnutls_mpi_release (&b
);
153 _gnutls_mpi_release (&B
);
154 _gnutls_mpi_release (&k
);
155 _gnutls_mpi_release (&tmpB
);
156 _gnutls_mpi_release (&tmpV
);
161 /* This calculates the SHA1(A | B)
162 * A and B will be left-padded with zeros to fill n_size.
165 _gnutls_calc_srp_u (bigint_t A
, bigint_t B
, bigint_t n
)
167 size_t b_size
, a_size
;
168 opaque
*holder
, hd
[MAX_HASH_SIZE
];
169 size_t holder_size
, hash_size
, n_size
;
174 /* get the size of n in bytes */
175 _gnutls_mpi_print (n
, NULL
, &n_size
);
177 _gnutls_mpi_print (A
, NULL
, &a_size
);
178 _gnutls_mpi_print (B
, NULL
, &b_size
);
180 if (a_size
> n_size
|| b_size
> n_size
)
183 return NULL
; /* internal error */
186 holder_size
= n_size
+ n_size
;
188 holder
= gnutls_calloc (1, holder_size
);
192 _gnutls_mpi_print (A
, &holder
[n_size
- a_size
], &a_size
);
193 _gnutls_mpi_print (B
, &holder
[n_size
+ n_size
- b_size
], &b_size
);
195 ret
= _gnutls_hash_init (&td
, GNUTLS_MAC_SHA1
);
198 gnutls_free (holder
);
202 _gnutls_hash (&td
, holder
, holder_size
);
203 _gnutls_hash_deinit (&td
, hd
);
205 /* convert the bytes of hd to integer
207 hash_size
= 20; /* SHA */
208 ret
= _gnutls_mpi_scan_nz (&res
, hd
, hash_size
);
209 gnutls_free (holder
);
220 /* S = (A * v^u) ^ b % N
221 * this is our shared key (server premaster secret)
224 _gnutls_calc_srp_S1 (bigint_t A
, bigint_t b
, bigint_t u
, bigint_t v
,
227 bigint_t tmp1
= NULL
, tmp2
= NULL
;
230 S
= _gnutls_mpi_alloc_like (n
);
234 tmp1
= _gnutls_mpi_alloc_like (n
);
235 tmp2
= _gnutls_mpi_alloc_like (n
);
237 if (tmp1
== NULL
|| tmp2
== NULL
)
240 _gnutls_mpi_powm (tmp1
, v
, u
, n
);
241 _gnutls_mpi_mulm (tmp2
, A
, tmp1
, n
);
242 _gnutls_mpi_powm (S
, tmp2
, b
, n
);
244 _gnutls_mpi_release (&tmp1
);
245 _gnutls_mpi_release (&tmp2
);
250 _gnutls_mpi_release (&tmp1
);
251 _gnutls_mpi_release (&tmp2
);
256 * returns A and a (which is random)
259 _gnutls_calc_srp_A (bigint_t
* a
, bigint_t g
, bigint_t n
)
265 bits
= _gnutls_mpi_get_nbits (n
);
266 tmpa
= _gnutls_mpi_randomize (NULL
, bits
, GNUTLS_RND_RANDOM
);
268 A
= _gnutls_mpi_new (bits
);
272 _gnutls_mpi_release (&tmpa
);
275 _gnutls_mpi_powm (A
, g
, tmpa
, n
);
280 _gnutls_mpi_release (&tmpa
);
285 /* generate x = SHA(s | SHA(U | ":" | p))
286 * The output is exactly 20 bytes
289 _gnutls_calc_srp_sha (const char *username
, const char *password
,
290 opaque
* salt
, int salt_size
, size_t * size
,
294 opaque res
[MAX_HASH_SIZE
];
299 ret
= _gnutls_hash_init (&td
, GNUTLS_MAC_SHA1
);
302 return GNUTLS_E_MEMORY_ERROR
;
304 _gnutls_hash (&td
, username
, strlen (username
));
305 _gnutls_hash (&td
, ":", 1);
306 _gnutls_hash (&td
, password
, strlen (password
));
308 _gnutls_hash_deinit (&td
, res
);
310 ret
= _gnutls_hash_init (&td
, GNUTLS_MAC_SHA1
);
313 return GNUTLS_E_MEMORY_ERROR
;
316 _gnutls_hash (&td
, salt
, salt_size
);
317 _gnutls_hash (&td
, res
, 20); /* 20 bytes is the output of sha1 */
319 _gnutls_hash_deinit (&td
, digest
);
325 _gnutls_calc_srp_x (char *username
, char *password
, opaque
* salt
,
326 size_t salt_size
, size_t * size
, void *digest
)
329 return _gnutls_calc_srp_sha (username
, password
, salt
,
330 salt_size
, size
, digest
);
334 /* S = (B - k*g^x) ^ (a + u * x) % N
335 * this is our shared key (client premaster secret)
338 _gnutls_calc_srp_S2 (bigint_t B
, bigint_t g
, bigint_t x
, bigint_t a
,
339 bigint_t u
, bigint_t n
)
341 bigint_t S
= NULL
, tmp1
= NULL
, tmp2
= NULL
;
342 bigint_t tmp4
= NULL
, tmp3
= NULL
, k
= NULL
;
344 S
= _gnutls_mpi_alloc_like (n
);
348 tmp1
= _gnutls_mpi_alloc_like (n
);
349 tmp2
= _gnutls_mpi_alloc_like (n
);
350 tmp3
= _gnutls_mpi_alloc_like (n
);
351 if (tmp1
== NULL
|| tmp2
== NULL
|| tmp3
== NULL
)
356 k
= _gnutls_calc_srp_u (n
, g
, n
);
363 _gnutls_mpi_powm (tmp1
, g
, x
, n
); /* g^x */
364 _gnutls_mpi_mulm (tmp3
, tmp1
, k
, n
); /* k*g^x mod n */
365 _gnutls_mpi_subm (tmp2
, B
, tmp3
, n
);
367 tmp4
= _gnutls_mpi_alloc_like (n
);
371 _gnutls_mpi_mul (tmp1
, u
, x
);
372 _gnutls_mpi_add (tmp4
, a
, tmp1
);
373 _gnutls_mpi_powm (S
, tmp2
, tmp4
, n
);
375 _gnutls_mpi_release (&tmp1
);
376 _gnutls_mpi_release (&tmp2
);
377 _gnutls_mpi_release (&tmp3
);
378 _gnutls_mpi_release (&tmp4
);
379 _gnutls_mpi_release (&k
);
384 _gnutls_mpi_release (&k
);
385 _gnutls_mpi_release (&tmp1
);
386 _gnutls_mpi_release (&tmp2
);
387 _gnutls_mpi_release (&tmp3
);
388 _gnutls_mpi_release (&tmp4
);
389 _gnutls_mpi_release (&S
);
394 * gnutls_srp_free_client_credentials:
395 * @sc: is a #gnutls_srp_client_credentials_t structure.
397 * This structure is complex enough to manipulate directly thus
398 * this helper function is provided in order to free (deallocate) it.
401 gnutls_srp_free_client_credentials (gnutls_srp_client_credentials_t sc
)
403 gnutls_free (sc
->username
);
404 gnutls_free (sc
->password
);
409 * gnutls_srp_allocate_client_credentials:
410 * @sc: is a pointer to a #gnutls_srp_server_credentials_t structure.
412 * This structure is complex enough to manipulate directly thus
413 * this helper function is provided in order to allocate it.
415 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
419 gnutls_srp_allocate_client_credentials (gnutls_srp_client_credentials_t
* sc
)
421 *sc
= gnutls_calloc (1, sizeof (srp_client_credentials_st
));
424 return GNUTLS_E_MEMORY_ERROR
;
430 * gnutls_srp_set_client_credentials:
431 * @res: is a #gnutls_srp_client_credentials_t structure.
432 * @username: is the user's userid
433 * @password: is the user's password
435 * This function sets the username and password, in a
436 * #gnutls_srp_client_credentials_t structure. Those will be used in
437 * SRP authentication. @username and @password should be ASCII
438 * strings or UTF-8 strings prepared using the "SASLprep" profile of
441 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
445 gnutls_srp_set_client_credentials (gnutls_srp_client_credentials_t res
,
446 const char *username
, const char *password
)
449 if (username
== NULL
|| password
== NULL
)
452 return GNUTLS_E_INVALID_REQUEST
;
455 res
->username
= gnutls_strdup (username
);
456 if (res
->username
== NULL
)
457 return GNUTLS_E_MEMORY_ERROR
;
459 res
->password
= gnutls_strdup (password
);
460 if (res
->password
== NULL
)
462 gnutls_free (res
->username
);
463 return GNUTLS_E_MEMORY_ERROR
;
470 * gnutls_srp_free_server_credentials:
471 * @sc: is a #gnutls_srp_server_credentials_t structure.
473 * This structure is complex enough to manipulate directly thus
474 * this helper function is provided in order to free (deallocate) it.
477 gnutls_srp_free_server_credentials (gnutls_srp_server_credentials_t sc
)
479 gnutls_free (sc
->password_file
);
480 gnutls_free (sc
->password_conf_file
);
486 * gnutls_srp_allocate_server_credentials:
487 * @sc: is a pointer to a #gnutls_srp_server_credentials_t structure.
489 * This structure is complex enough to manipulate directly thus this
490 * helper function is provided in order to allocate it.
492 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
496 gnutls_srp_allocate_server_credentials (gnutls_srp_server_credentials_t
* sc
)
498 *sc
= gnutls_calloc (1, sizeof (srp_server_cred_st
));
501 return GNUTLS_E_MEMORY_ERROR
;
507 * gnutls_srp_set_server_credentials_file:
508 * @res: is a #gnutls_srp_server_credentials_t structure.
509 * @password_file: is the SRP password file (tpasswd)
510 * @password_conf_file: is the SRP password conf file (tpasswd.conf)
512 * This function sets the password files, in a
513 * #gnutls_srp_server_credentials_t structure. Those password files
514 * hold usernames and verifiers and will be used for SRP
517 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
521 gnutls_srp_set_server_credentials_file (gnutls_srp_server_credentials_t res
,
522 const char *password_file
,
523 const char *password_conf_file
)
526 if (password_file
== NULL
|| password_conf_file
== NULL
)
529 return GNUTLS_E_INVALID_REQUEST
;
532 /* Check if the files can be opened */
533 if (_gnutls_file_exists (password_file
) != 0)
536 return GNUTLS_E_FILE_ERROR
;
539 if (_gnutls_file_exists (password_conf_file
) != 0)
542 return GNUTLS_E_FILE_ERROR
;
545 res
->password_file
= gnutls_strdup (password_file
);
546 if (res
->password_file
== NULL
)
549 return GNUTLS_E_MEMORY_ERROR
;
552 res
->password_conf_file
= gnutls_strdup (password_conf_file
);
553 if (res
->password_conf_file
== NULL
)
556 gnutls_free (res
->password_file
);
557 res
->password_file
= NULL
;
558 return GNUTLS_E_MEMORY_ERROR
;
566 * gnutls_srp_set_server_credentials_function:
567 * @cred: is a #gnutls_srp_server_credentials_t structure.
568 * @func: is the callback function
570 * This function can be used to set a callback to retrieve the user's
571 * SRP credentials. The callback's function form is:
573 * int (*callback)(gnutls_session_t, const char* username,
574 * gnutls_datum_t* salt, gnutls_datum_t *verifier, gnutls_datum_t* g,
575 * gnutls_datum_t* n);
577 * @username contains the actual username.
578 * The @salt, @verifier, @generator and @prime must be filled
579 * in using the gnutls_malloc(). For convenience @prime and @generator
580 * may also be one of the static parameters defined in extra.h.
582 * In case the callback returned a negative number then gnutls will
583 * assume that the username does not exist.
585 * In order to prevent attackers from guessing valid usernames,
586 * if a user does not exist, g and n values should be filled in
587 * using a random user's parameters. In that case the callback must
588 * return the special value (1).
590 * The callback function will only be called once per handshake.
591 * The callback function should return 0 on success, while
592 * -1 indicates an error.
595 gnutls_srp_set_server_credentials_function (gnutls_srp_server_credentials_t
597 gnutls_srp_server_credentials_function
600 cred
->pwd_callback
= func
;
604 * gnutls_srp_set_client_credentials_function:
605 * @cred: is a #gnutls_srp_server_credentials_t structure.
606 * @func: is the callback function
608 * This function can be used to set a callback to retrieve the
609 * username and password for client SRP authentication. The
610 * callback's function form is:
612 * int (*callback)(gnutls_session_t, char** username, char**password);
614 * The @username and @password must be allocated using
615 * gnutls_malloc(). @username and @password should be ASCII strings
616 * or UTF-8 strings prepared using the "SASLprep" profile of
619 * The callback function will be called once per handshake before the
620 * initial hello message is sent.
622 * The callback should not return a negative error code the second
623 * time called, since the handshake procedure will be aborted.
625 * The callback function should return 0 on success.
626 * -1 indicates an error.
629 gnutls_srp_set_client_credentials_function (gnutls_srp_client_credentials_t
631 gnutls_srp_client_credentials_function
634 cred
->get_function
= func
;
639 * gnutls_srp_server_get_username:
640 * @session: is a gnutls session
642 * This function will return the username of the peer. This should
643 * only be called in case of SRP authentication and in case of a
644 * server. Returns NULL in case of an error.
646 * Returns: SRP username of the peer, or NULL in case of error.
649 gnutls_srp_server_get_username (gnutls_session_t session
)
651 srp_server_auth_info_t info
;
653 CHECK_AUTH (GNUTLS_CRD_SRP
, NULL
);
655 info
= _gnutls_get_auth_info (session
);
658 return info
->username
;
662 * gnutls_srp_verifier:
663 * @username: is the user's name
664 * @password: is the user's password
665 * @salt: should be some randomly generated bytes
666 * @generator: is the generator of the group
667 * @prime: is the group's prime
668 * @res: where the verifier will be stored.
670 * This function will create an SRP verifier, as specified in
671 * RFC2945. The @prime and @generator should be one of the static
672 * parameters defined in gnutls/extra.h or may be generated using the
673 * libgcrypt functions gcry_prime_generate() and
674 * gcry_prime_group_generator().
676 * The verifier will be allocated with @malloc and will be stored in
677 * @res using binary format.
679 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
683 gnutls_srp_verifier (const char *username
, const char *password
,
684 const gnutls_datum_t
* salt
,
685 const gnutls_datum_t
* generator
,
686 const gnutls_datum_t
* prime
, gnutls_datum_t
* res
)
690 size_t digest_size
= 20, size
;
693 ret
= _gnutls_calc_srp_sha (username
, password
, salt
->data
,
694 salt
->size
, &digest_size
, digest
);
702 if (_gnutls_mpi_scan_nz (&_n
, prime
->data
, size
))
705 return GNUTLS_E_MPI_SCAN_FAILED
;
708 size
= generator
->size
;
709 if (_gnutls_mpi_scan_nz (&_g
, generator
->data
, size
))
712 return GNUTLS_E_MPI_SCAN_FAILED
;
715 ret
= _gnutls_srp_gx (digest
, 20, &res
->data
, _g
, _n
, malloc
);
727 * gnutls_srp_set_prime_bits:
728 * @session: is a #gnutls_session_t structure.
729 * @bits: is the number of bits
731 * This function sets the minimum accepted number of bits, for use in
732 * an SRP key exchange. If zero, the default 2048 bits will be used.
734 * In the client side it sets the minimum accepted number of bits. If
735 * a server sends a prime with less bits than that
736 * %GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER will be returned by the
739 * This function has no effect in server side.
744 gnutls_srp_set_prime_bits (gnutls_session_t session
, unsigned int bits
)
746 session
->internals
.srp_prime_bits
= bits
;
749 #endif /* ENABLE_SRP */