diff options
-rw-r--r-- | lib/gnutls_errors.c | 1 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_mpi.h | 2 | ||||
-rw-r--r-- | libextra/auth_srp.c | 28 |
4 files changed, 32 insertions, 0 deletions
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index bb58bb1fef..dfcc5c6667 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -127,6 +127,7 @@ static gnutls_error_entry error_algorithms[] = { ERROR_ENTRY("No supported cipher suites have been found.", GNUTLS_E_NO_CIPHER_SUITES, 1 ), ERROR_ENTRY("Could not get OpenPGP key.", GNUTLS_E_OPENPGP_GETKEY_FAILED, 1), + ERROR_ENTRY("Error in the SRP protocol negotiation.", GNUTLS_E_SRP_PROTOCOL_FAILURE, 1), ERROR_ENTRY("The SRP username supplied by the peer is illegal.", GNUTLS_E_ILLEGAL_SRP_USERNAME, 1), ERROR_ENTRY("The peer advertized SRP but did not supply any SRP username.", GNUTLS_E_EMPTY_SRP_USERNAME, 1), {0, 0, 0, 0} diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index 2d393b7c61..8e722b81d7 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -98,6 +98,7 @@ #define GNUTLS_E_ILLEGAL_SRP_USERNAME -90 #define GNUTLS_E_SRP_PWD_PARSING_ERROR -91 #define GNUTLS_E_EMPTY_SRP_USERNAME -92 +#define GNUTLS_E_SRP_PROTOCOL_FAILURE -93 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250 diff --git a/lib/gnutls_mpi.h b/lib/gnutls_mpi.h index 37d1963b2e..3dea6971aa 100644 --- a/lib/gnutls_mpi.h +++ b/lib/gnutls_mpi.h @@ -6,6 +6,8 @@ #define GNUTLS_MPI GCRY_MPI +#define _gnutls_mpi_cmp_ui gcry_mpi_cmp_ui +#define _gnutls_mpi_mod gcry_mpi_mod #define _gnutls_mpi_new gcry_mpi_new #define _gnutls_mpi_snew gcry_mpi_snew #define _gnutls_mpi_copy gcry_mpi_copy diff --git a/libextra/auth_srp.c b/libextra/auth_srp.c index 84d47cb49b..0ca1ebd53c 100644 --- a/libextra/auth_srp.c +++ b/libextra/auth_srp.c @@ -345,6 +345,28 @@ int _gnutls_proc_srp_client_kx(gnutls_session state, opaque * data, size_t _data return 0; } +/* Checks if b%n==0 which is a fatal srp error. + * Returns a proper error code in that case, and 0 when + * all are ok. + */ +static int check_b_mod_n( GNUTLS_MPI b, GNUTLS_MPI n) +{ +int ret; +GNUTLS_MPI r = _gnutls_mpi_alloc_like(b); + + _gnutls_mpi_mod( r, b, n); + ret = _gnutls_mpi_cmp_ui(r, 0); + + _gnutls_mpi_release( &r); + + if (ret == 0) { + gnutls_assert(); + return GNUTLS_E_SRP_PROTOCOL_FAILURE; + } + + return 0; +} + /* receive the key exchange message ( n, g, s, B) */ int _gnutls_proc_srp_server_kx(gnutls_session state, opaque * data, size_t _data_size) @@ -438,6 +460,12 @@ int _gnutls_proc_srp_server_kx(gnutls_session state, opaque * data, size_t _data gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } + + if ( (ret = check_b_mod_n( B, N)) < 0) { + gnutls_assert(); + return ret; + } + /* generate x = SHA(s | SHA(U | ":" | p)) * (or the equivalent using bcrypt) |