2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
26 #include <gnutls_state.h>
30 #include <gnutls_srp.h>
31 #include <auth/srp_passwd.h>
32 #include <gnutls_mpi.h>
33 #include <gnutls_num.h>
34 #include <gnutls_helper.h>
35 #include <algorithms.h>
41 /* Here functions for SRP (like g^x mod n) are defined
45 _gnutls_srp_gx(uint8_t * text, size_t textsize, uint8_t ** result,
46 bigint_t g, bigint_t prime)
52 if (_gnutls_mpi_init_scan_nz(&x, text, textsize)) {
54 return GNUTLS_E_MPI_SCAN_FAILED;
57 ret = _gnutls_mpi_init(&e);
61 /* e = g^x mod prime (n) */
62 ret = _gnutls_mpi_powm(e, g, x, prime);
66 ret = _gnutls_mpi_print(e, NULL, &result_size);
67 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
68 *result = gnutls_malloc(result_size);
69 if ((*result) == NULL) {
70 ret = GNUTLS_E_MEMORY_ERROR;
74 ret = _gnutls_mpi_print(e, *result, &result_size);
81 ret = GNUTLS_E_MPI_PRINT_FAILED;
85 _gnutls_mpi_release(&e);
86 _gnutls_mpi_release(&x);
94 * Choose a random value b and calculate B = (k* v + g^b) % N.
95 * where k == SHA1(N|g)
96 * Return: B and if ret_b is not NULL b.
99 _gnutls_calc_srp_B(bigint_t * ret_b, bigint_t g, bigint_t n, bigint_t v)
101 bigint_t tmpB = NULL, tmpV = NULL;
102 bigint_t b = NULL, B = NULL, k = NULL;
105 /* calculate: B = (k*v + g^b) % N
107 ret = _gnutls_mpi_init_multi(&tmpV, &tmpB, &B, &b, NULL);
111 _gnutls_mpi_random_modp(b, n, GNUTLS_RND_RANDOM);
113 k = _gnutls_calc_srp_u(n, g, n);
119 ret = _gnutls_mpi_mulm(tmpV, k, v, n);
125 ret = _gnutls_mpi_powm(tmpB, g, b, n);
131 ret = _gnutls_mpi_addm(B, tmpV, tmpB, n);
137 _gnutls_mpi_release(&k);
138 _gnutls_mpi_release(&tmpB);
139 _gnutls_mpi_release(&tmpV);
144 _gnutls_mpi_release(&b);
149 _gnutls_mpi_release(&b);
150 _gnutls_mpi_release(&B);
151 _gnutls_mpi_release(&k);
152 _gnutls_mpi_release(&tmpB);
153 _gnutls_mpi_release(&tmpV);
158 /* This calculates the SHA1(A | B)
159 * A and B will be left-padded with zeros to fill n_size.
161 bigint_t _gnutls_calc_srp_u(bigint_t A, bigint_t B, bigint_t n)
163 size_t b_size, a_size;
164 uint8_t *holder, hd[MAX_HASH_SIZE];
165 size_t holder_size, hash_size, n_size;
169 /* get the size of n in bytes */
170 _gnutls_mpi_print(n, NULL, &n_size);
172 _gnutls_mpi_print(A, NULL, &a_size);
173 _gnutls_mpi_print(B, NULL, &b_size);
175 if (a_size > n_size || b_size > n_size) {
177 return NULL; /* internal error */
180 holder_size = n_size + n_size;
182 holder = gnutls_calloc(1, holder_size);
186 _gnutls_mpi_print(A, &holder[n_size - a_size], &a_size);
187 _gnutls_mpi_print(B, &holder[n_size + n_size - b_size], &b_size);
189 ret = _gnutls_hash_fast(GNUTLS_DIG_SHA1, holder, holder_size, hd);
196 /* convert the bytes of hd to integer
198 hash_size = 20; /* SHA */
199 ret = _gnutls_mpi_init_scan_nz(&res, hd, hash_size);
210 /* S = (A * v^u) ^ b % N
211 * this is our shared key (server premaster secret)
214 _gnutls_calc_srp_S1(bigint_t A, bigint_t b, bigint_t u, bigint_t v,
217 bigint_t tmp1 = NULL, tmp2 = NULL;
221 ret = _gnutls_mpi_init_multi(&S, &tmp1, &tmp2, NULL);
225 ret = _gnutls_mpi_powm(tmp1, v, u, n);
231 ret = _gnutls_mpi_mulm(tmp2, A, tmp1, n);
237 _gnutls_mpi_powm(S, tmp2, b, n);
239 _gnutls_mpi_release(&tmp1);
240 _gnutls_mpi_release(&tmp2);
245 _gnutls_mpi_release(&S);
246 _gnutls_mpi_release(&tmp1);
247 _gnutls_mpi_release(&tmp2);
252 * returns A and a (which is random)
254 bigint_t _gnutls_calc_srp_A(bigint_t * a, bigint_t g, bigint_t n)
260 ret = _gnutls_mpi_init_multi(&A, &tmpa, NULL);
266 _gnutls_mpi_random_modp(tmpa, n, GNUTLS_RND_RANDOM);
268 ret = _gnutls_mpi_powm(A, g, tmpa, n);
275 _gnutls_mpi_release(&tmpa);
279 _gnutls_mpi_release(&tmpa);
280 _gnutls_mpi_release(&A);
284 /* generate x = SHA(s | SHA(U | ":" | p))
285 * The output is exactly 20 bytes
288 _gnutls_calc_srp_sha(const char *username, const char *password,
289 uint8_t * salt, int salt_size, size_t * size,
293 uint8_t res[MAX_HASH_SIZE];
295 const mac_entry_st *me = mac_to_entry(GNUTLS_MAC_SHA1);
299 ret = _gnutls_hash_init(&td, me);
301 return GNUTLS_E_MEMORY_ERROR;
303 _gnutls_hash(&td, username, strlen(username));
304 _gnutls_hash(&td, ":", 1);
305 _gnutls_hash(&td, password, strlen(password));
307 _gnutls_hash_deinit(&td, res);
309 ret = _gnutls_hash_init(&td, me);
311 return GNUTLS_E_MEMORY_ERROR;
314 _gnutls_hash(&td, salt, salt_size);
315 _gnutls_hash(&td, res, 20); /* 20 bytes is the output of sha1 */
317 _gnutls_hash_deinit(&td, digest);
323 _gnutls_calc_srp_x(char *username, char *password, uint8_t * salt,
324 size_t salt_size, size_t * size, void *digest)
327 return _gnutls_calc_srp_sha(username, password, salt,
328 salt_size, size, digest);
332 /* S = (B - k*g^x) ^ (a + u * x) % N
333 * this is our shared key (client premaster secret)
336 _gnutls_calc_srp_S2(bigint_t B, bigint_t g, bigint_t x, bigint_t a,
337 bigint_t u, bigint_t n)
339 bigint_t S = NULL, tmp1 = NULL, tmp2 = NULL;
340 bigint_t tmp4 = NULL, tmp3 = NULL, k = NULL;
343 ret = _gnutls_mpi_init_multi(&S, &tmp1, &tmp2, &tmp3, &tmp4, NULL);
347 k = _gnutls_calc_srp_u(n, g, n);
353 ret = _gnutls_mpi_powm(tmp1, g, x, n); /* g^x */
359 ret = _gnutls_mpi_mulm(tmp3, tmp1, k, n); /* k*g^x mod n */
365 ret = _gnutls_mpi_subm(tmp2, B, tmp3, n);
371 ret = _gnutls_mpi_mul(tmp1, u, x);
377 ret = _gnutls_mpi_add(tmp4, a, tmp1);
383 ret = _gnutls_mpi_powm(S, tmp2, tmp4, n);
389 _gnutls_mpi_release(&tmp1);
390 _gnutls_mpi_release(&tmp2);
391 _gnutls_mpi_release(&tmp3);
392 _gnutls_mpi_release(&tmp4);
393 _gnutls_mpi_release(&k);
398 _gnutls_mpi_release(&k);
399 _gnutls_mpi_release(&tmp1);
400 _gnutls_mpi_release(&tmp2);
401 _gnutls_mpi_release(&tmp3);
402 _gnutls_mpi_release(&tmp4);
403 _gnutls_mpi_release(&S);
408 * gnutls_srp_free_client_credentials:
409 * @sc: is a #gnutls_srp_client_credentials_t structure.
411 * This structure is complex enough to manipulate directly thus
412 * this helper function is provided in order to free (deallocate) it.
414 void gnutls_srp_free_client_credentials(gnutls_srp_client_credentials_t sc)
416 gnutls_free(sc->username);
417 gnutls_free(sc->password);
422 * gnutls_srp_allocate_client_credentials:
423 * @sc: is a pointer to a #gnutls_srp_server_credentials_t structure.
425 * This structure is complex enough to manipulate directly thus
426 * this helper function is provided in order to allocate it.
428 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
432 gnutls_srp_allocate_client_credentials(gnutls_srp_client_credentials_t *
435 *sc = gnutls_calloc(1, sizeof(srp_client_credentials_st));
438 return GNUTLS_E_MEMORY_ERROR;
444 * gnutls_srp_set_client_credentials:
445 * @res: is a #gnutls_srp_client_credentials_t structure.
446 * @username: is the user's userid
447 * @password: is the user's password
449 * This function sets the username and password, in a
450 * #gnutls_srp_client_credentials_t structure. Those will be used in
451 * SRP authentication. @username and @password should be ASCII
452 * strings or UTF-8 strings prepared using the "SASLprep" profile of
455 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
459 gnutls_srp_set_client_credentials(gnutls_srp_client_credentials_t res,
460 const char *username,
461 const char *password)
464 if (username == NULL || password == NULL) {
466 return GNUTLS_E_INVALID_REQUEST;
469 res->username = gnutls_strdup(username);
470 if (res->username == NULL)
471 return GNUTLS_E_MEMORY_ERROR;
473 res->password = gnutls_strdup(password);
474 if (res->password == NULL) {
475 gnutls_free(res->username);
476 return GNUTLS_E_MEMORY_ERROR;
483 * gnutls_srp_free_server_credentials:
484 * @sc: is a #gnutls_srp_server_credentials_t structure.
486 * This structure is complex enough to manipulate directly thus
487 * this helper function is provided in order to free (deallocate) it.
489 void gnutls_srp_free_server_credentials(gnutls_srp_server_credentials_t sc)
491 gnutls_free(sc->password_file);
492 gnutls_free(sc->password_conf_file);
493 _gnutls_free_datum(&sc->fake_salt_seed);
498 /* Size of the default (random) seed if
499 * gnutls_srp_set_server_fake_salt_seed() is not called to set
502 #define DEFAULT_FAKE_SALT_SEED_SIZE 20
504 /* Size of the fake salts generated if
505 * gnutls_srp_set_server_fake_salt_seed() is not called to set
508 #define DEFAULT_FAKE_SALT_SIZE 16
511 * gnutls_srp_allocate_server_credentials:
512 * @sc: is a pointer to a #gnutls_srp_server_credentials_t structure.
514 * This structure is complex enough to manipulate directly thus this
515 * helper function is provided in order to allocate it.
517 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
521 gnutls_srp_allocate_server_credentials(gnutls_srp_server_credentials_t *
525 *sc = gnutls_calloc(1, sizeof(srp_server_cred_st));
528 return GNUTLS_E_MEMORY_ERROR;
530 (*sc)->fake_salt_seed.size = DEFAULT_FAKE_SALT_SEED_SIZE;
531 (*sc)->fake_salt_seed.data = gnutls_malloc(
532 DEFAULT_FAKE_SALT_SEED_SIZE);
533 if ((*sc)->fake_salt_seed.data == NULL) {
534 ret = GNUTLS_E_MEMORY_ERROR;
539 ret = _gnutls_rnd(GNUTLS_RND_RANDOM, (*sc)->fake_salt_seed.data,
540 DEFAULT_FAKE_SALT_SEED_SIZE);
547 (*sc)->fake_salt_length = DEFAULT_FAKE_SALT_SIZE;
551 _gnutls_free_datum(&(*sc)->fake_salt_seed);
557 * gnutls_srp_set_server_credentials_file:
558 * @res: is a #gnutls_srp_server_credentials_t structure.
559 * @password_file: is the SRP password file (tpasswd)
560 * @password_conf_file: is the SRP password conf file (tpasswd.conf)
562 * This function sets the password files, in a
563 * #gnutls_srp_server_credentials_t structure. Those password files
564 * hold usernames and verifiers and will be used for SRP
567 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
571 gnutls_srp_set_server_credentials_file(gnutls_srp_server_credentials_t res,
572 const char *password_file,
573 const char *password_conf_file)
576 if (password_file == NULL || password_conf_file == NULL) {
578 return GNUTLS_E_INVALID_REQUEST;
581 /* Check if the files can be opened */
582 if (_gnutls_file_exists(password_file) != 0) {
584 return GNUTLS_E_FILE_ERROR;
587 if (_gnutls_file_exists(password_conf_file) != 0) {
589 return GNUTLS_E_FILE_ERROR;
592 res->password_file = gnutls_strdup(password_file);
593 if (res->password_file == NULL) {
595 return GNUTLS_E_MEMORY_ERROR;
598 res->password_conf_file = gnutls_strdup(password_conf_file);
599 if (res->password_conf_file == NULL) {
601 gnutls_free(res->password_file);
602 res->password_file = NULL;
603 return GNUTLS_E_MEMORY_ERROR;
611 * gnutls_srp_set_server_credentials_function:
612 * @cred: is a #gnutls_srp_server_credentials_t structure.
613 * @func: is the callback function
615 * This function can be used to set a callback to retrieve the user's
616 * SRP credentials. The callback's function form is:
618 * int (*callback)(gnutls_session_t, const char* username,
619 * gnutls_datum_t *salt, gnutls_datum_t *verifier, gnutls_datum_t *generator,
620 * gnutls_datum_t *prime);
622 * @username contains the actual username.
623 * The @salt, @verifier, @generator and @prime must be filled
624 * in using the gnutls_malloc(). For convenience @prime and @generator
625 * may also be one of the static parameters defined in gnutls.h.
627 * Initially, the data field is NULL in every #gnutls_datum_t
628 * structure that the callback has to fill in. When the
629 * callback is done GnuTLS deallocates all of those buffers
630 * which are non-NULL, regardless of the return value.
632 * In order to prevent attackers from guessing valid usernames,
633 * if a user does not exist, g and n values should be filled in
634 * using a random user's parameters. In that case the callback must
635 * return the special value (1).
636 * See #gnutls_srp_set_server_fake_salt_seed too.
637 * If this is not required for your application, return a negative
638 * number from the callback to abort the handshake.
640 * The callback function will only be called once per handshake.
641 * The callback function should return 0 on success, while
642 * -1 indicates an error.
645 gnutls_srp_set_server_credentials_function(gnutls_srp_server_credentials_t
647 gnutls_srp_server_credentials_function
650 cred->pwd_callback = func;
654 * gnutls_srp_set_client_credentials_function:
655 * @cred: is a #gnutls_srp_server_credentials_t structure.
656 * @func: is the callback function
658 * This function can be used to set a callback to retrieve the
659 * username and password for client SRP authentication. The
660 * callback's function form is:
662 * int (*callback)(gnutls_session_t, char** username, char**password);
664 * The @username and @password must be allocated using
665 * gnutls_malloc(). @username and @password should be ASCII strings
666 * or UTF-8 strings prepared using the "SASLprep" profile of
669 * The callback function will be called once per handshake before the
670 * initial hello message is sent.
672 * The callback should not return a negative error code the second
673 * time called, since the handshake procedure will be aborted.
675 * The callback function should return 0 on success.
676 * -1 indicates an error.
679 gnutls_srp_set_client_credentials_function(gnutls_srp_client_credentials_t
681 gnutls_srp_client_credentials_function
684 cred->get_function = func;
689 * gnutls_srp_server_get_username:
690 * @session: is a gnutls session
692 * This function will return the username of the peer. This should
693 * only be called in case of SRP authentication and in case of a
694 * server. Returns NULL in case of an error.
696 * Returns: SRP username of the peer, or NULL in case of error.
698 const char *gnutls_srp_server_get_username(gnutls_session_t session)
700 srp_server_auth_info_t info;
702 CHECK_AUTH(GNUTLS_CRD_SRP, NULL);
704 info = _gnutls_get_auth_info(session, GNUTLS_CRD_SRP);
707 return info->username;
711 * gnutls_srp_verifier:
712 * @username: is the user's name
713 * @password: is the user's password
714 * @salt: should be some randomly generated bytes
715 * @generator: is the generator of the group
716 * @prime: is the group's prime
717 * @res: where the verifier will be stored.
719 * This function will create an SRP verifier, as specified in
720 * RFC2945. The @prime and @generator should be one of the static
721 * parameters defined in gnutls/gnutls.h or may be generated.
723 * The verifier will be allocated with @gnutls_malloc() and will be stored in
724 * @res using binary format.
726 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
730 gnutls_srp_verifier(const char *username, const char *password,
731 const gnutls_datum_t * salt,
732 const gnutls_datum_t * generator,
733 const gnutls_datum_t * prime, gnutls_datum_t * res)
737 size_t digest_size = 20, size;
740 ret = _gnutls_calc_srp_sha(username, password, salt->data,
741 salt->size, &digest_size, digest);
748 if (_gnutls_mpi_init_scan_nz(&_n, prime->data, size)) {
750 return GNUTLS_E_MPI_SCAN_FAILED;
753 size = generator->size;
754 if (_gnutls_mpi_init_scan_nz(&_g, generator->data, size)) {
756 return GNUTLS_E_MPI_SCAN_FAILED;
759 ret = _gnutls_srp_gx(digest, 20, &res->data, _g, _n);
770 * gnutls_srp_set_prime_bits:
771 * @session: is a #gnutls_session_t structure.
772 * @bits: is the number of bits
774 * This function sets the minimum accepted number of bits, for use in
775 * an SRP key exchange. If zero, the default 2048 bits will be used.
777 * In the client side it sets the minimum accepted number of bits. If
778 * a server sends a prime with less bits than that
779 * %GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER will be returned by the
782 * This function has no effect in server side.
786 void gnutls_srp_set_prime_bits(gnutls_session_t session, unsigned int bits)
788 session->internals.srp_prime_bits = bits;
792 * gnutls_srp_set_server_fake_salt_seed:
793 * @cred: is a #gnutls_srp_server_credentials_t structure
794 * @seed: is the seed data, only needs to be valid until the function
795 * returns; size of the seed must be greater than zero
796 * @salt_length: is the length of the generated fake salts
798 * This function sets the seed that is used to generate salts for
799 * invalid (non-existent) usernames.
801 * In order to prevent attackers from guessing valid usernames,
802 * when a user does not exist gnutls generates a salt and a verifier
803 * and proceeds with the protocol as usual.
804 * The authentication will ultimately fail, but the client cannot tell
805 * whether the username is valid (exists) or invalid.
807 * If an attacker learns the seed, given a salt (which is part of the
808 * handshake) which was generated when the seed was in use, it can tell
809 * whether or not the authentication failed because of an unknown username.
810 * This seed cannot be used to reveal application data or passwords.
812 * @salt_length should represent the salt length your application uses.
813 * Generating fake salts longer than 20 bytes is not supported.
815 * By default the seed is a random value, different each time a
816 * #gnutls_srp_server_credentials_t is allocated and fake salts are
822 gnutls_srp_set_server_fake_salt_seed(gnutls_srp_server_credentials_t cred,
823 const gnutls_datum_t * seed,
824 unsigned int salt_length)
826 _gnutls_free_datum(&cred->fake_salt_seed);
827 _gnutls_set_datum(&cred->fake_salt_seed, seed->data, seed->size);
829 /* Cap the salt length at the output size of the MAC algorithm
830 * we are using to generate the fake salts.
832 const mac_entry_st * me = mac_to_entry(SRP_FAKE_SALT_MAC);
833 const size_t mac_len = me->output_size;
835 cred->fake_salt_length = (salt_length < mac_len ? salt_length : mac_len);
838 #endif /* ENABLE_SRP */