summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/gnutls_errors.c1
-rw-r--r--lib/gnutls_errors_int.h1
-rw-r--r--lib/gnutls_mpi.h2
-rw-r--r--libextra/auth_srp.c28
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)