From: Nikos Mavrogiannopoulos Date: Sat, 26 May 2001 12:19:48 +0000 (+0000) Subject: Added decoding function for the base64 encoding used in SRP. X-Git-Tag: gnutls_0_1_4~63 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b1063775c6dedf0330dd24ada3d50bf705ae02fc;p=thirdparty%2Fgnutls.git Added decoding function for the base64 encoding used in SRP. (this function is more strict in characters than the previous one) --- diff --git a/lib/auth_srp_passwd.c b/lib/auth_srp_passwd.c index 977290c201..e7bf585cb0 100644 --- a/lib/auth_srp_passwd.c +++ b/lib/auth_srp_passwd.c @@ -68,6 +68,7 @@ int indx; p++; len = strlen(p); + entry->salt_size = _gnutls_sbase64_decode( p, len, &entry->salt); if (entry->salt_size <= 0) { @@ -143,11 +144,11 @@ int tmp_size; /* read the generator */ len = strlen(p); + if (p[len-1]=='\n' || p[len-1]==' ') len--; tmp_size = _gnutls_sbase64_decode( p, len, &tmp); if (tmp_size < 0) { gnutls_assert(); - gnutls_free(tmp); return GNUTLS_E_PARSING_ERROR; } if (gcry_mpi_scan(&entry->g, GCRYMPI_FMT_USG, tmp, &tmp_size)) { @@ -176,7 +177,6 @@ int tmp_size; if (tmp_size < 0) { gnutls_assert(); mpi_release(entry->g); - gnutls_free(tmp); return GNUTLS_E_PARSING_ERROR; } if (gcry_mpi_scan(&entry->n, GCRYMPI_FMT_USG, tmp, &tmp_size)) { diff --git a/lib/cert_sb64.c b/lib/cert_sb64.c index aa388b3c19..89d97771d9 100644 --- a/lib/cert_sb64.c +++ b/lib/cert_sb64.c @@ -154,8 +154,10 @@ int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result) */ if (mod > 0) { tmp = encode(tmpres, &data[0], mod); - if (tmp == -1) - return -1; + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } memcpy(&(*result)[0], tmpres, tmp); i = mod; @@ -165,8 +167,10 @@ int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result) */ for (; i < data_size; i += 3, j += 4) { tmp = encode(tmpres, &data[i], data_size - i); - if (tmp == -1) - return -1; + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } memcpy(&(*result)[j], tmpres, tmp); (*result)[j+tmp] = 0; } @@ -174,60 +178,94 @@ int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result) return ret; } -#define TOASCII(c) (c<127 ? asciitable[c] : 0xff) -int _gnutls_sbase64_decode(uint8 * data, int data_size, uint8 ** result) + +/* data must be 4 bytes + * result should be 3 bytes + */ +#define TOASCII(c) (c < 127 ? asciitable[c] : 0xff) +inline static int decode(uint8 * result, const uint8 * data) { - uint8 *a, loc; - int i, j; + uint8 a1, a2; + int ret = 3; + + memset( result, 0, 3); + + a1 = TOASCII(data[3]); + a2 = TOASCII(data[2]); + if (a1 != 0xff) result[2] = a1 & 0xff; + else return -1; + if (a2 != 0xff) result[2] |= ((a2 & 0x03) << 6) & 0xff; + + a1 = a2; + a2 = TOASCII(data[1]); + if (a1 != 0xff) result[1] = ((a1 & 0x3c) >> 2); + if (a2 != 0xff) result[1] |= ((a2 & 0x0f) << 4); + else ret--; + + a1 = a2; + a2 = TOASCII(data[0]); + if (a1 != 0xff) result[0] = (((a1 & 0x30) >> 4) & 0xff); + if (a2 != 0xff) result[0] |= ((a2 << 2) & 0xff); + else ret--; - while (*data && (*data == ' ' || *data == '\t' || *data == '\n')) - ++data; + return ret; +} - a = gnutls_malloc(data_size + 1); - if (a == (unsigned char *) 0) - return -1; +/* decodes data and puts the result into result (localy alocated) + * The result_size is the return value. + * That function does not ignore newlines tabs etc. You should remove them + * before calling it. + */ +int _gnutls_sbase64_decode(uint8 * data, int idata_size, uint8 ** result) +{ + int i, ret, j, left; + int data_size, tmp; + uint8 datrev[4]; + uint8 tmpres[3]; - i = 0; - while ( i < data_size && (loc = TOASCII(data[i])) != 0xff) { - a[i++] = loc; - } - data_size = i; - - i = data_size - 1; - j = data_size; - while (1) { - a[j] = a[i]; - if (--i < 0) - break; - a[j] |= (a[i] & 3) << 6; - --j; - a[j] = (uint8) ((a[i] & 0x3c) >> 2); - if (--i < 0) - break; - a[j] |= (a[i] & 0xf) << 4; - --j; - a[j] = (uint8) ((a[i] & 0x30) >> 4); - if (--i < 0) - break; - a[j] |= (a[i] << 2); - - a[--j] = 0; - if (--i < 0) - break; - } + data_size = (idata_size/4)*4; + left = idata_size % 4; - while (a[j] == 0 && j <= data_size) - j++; + ret = (data_size / 4) * 3; - (*result) = gnutls_malloc(data_size - j + 1); + if (left > 0) + ret += 3; - memcpy((*result), a + j, data_size - j + 1); + (*result) = gnutls_malloc(ret+1); + if ((*result) == NULL) + return -1; - gnutls_free(a); - return data_size - j + 1; -} + /* the first "block" is treated with special care */ + tmp = 0; + if (left > 0) { + memset( datrev, 0, 4); + memcpy( &datrev[4-left], data, left); + + tmp = decode( tmpres, datrev); + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } + memcpy(&(*result)[0], &tmpres[3-tmp], tmp); + if (tmp < 3) + ret -= (3 - tmp); + } + /* rest data */ + for (i = left, j = tmp; i < idata_size; i += 4) { + tmp = decode(tmpres, &data[i]); + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } + memcpy(&(*result)[j], tmpres, tmp); + if (tmp < 3) + ret -= (3 - tmp); + j += 3; + } + return ret; +} #ifdef B64_TEST int main() @@ -251,14 +289,15 @@ int main() return 0;*/ siz = fread(x, 1, sizeof(x), stdin); - siz = _gnutls_sbase64_encode(x, siz, &b64); -// siz = _gnutls_sbase64_decode(x, siz, &b64); +// siz = _gnutls_sbase64_encode(x, siz, &b64); + siz = _gnutls_sbase64_decode(x, siz, &b64); if (siz < 0) { fprintf(stderr, "ERROR %d\n", siz); exit(1); } + fwrite(b64, siz, 1, stdout); return 0; diff --git a/lib/crypt_bcrypt.c b/lib/crypt_bcrypt.c index aade53b2a9..f24c605330 100644 --- a/lib/crypt_bcrypt.c +++ b/lib/crypt_bcrypt.c @@ -615,7 +615,10 @@ char *crypt_bcrypt(const char *passwd, const char *salt, MPI g, MPI n) } sp++; - _gnutls_sbase64_decode(sp, strlen(sp), &csalt); + if (_gnutls_sbase64_decode(sp, strlen(sp), &csalt) < 0) { + gnutls_assert(); + return NULL; + } cost = (uint8) csalt[0]; ctx = _blf_init(&csalt[1], passwd, passwd_len, cost); @@ -634,7 +637,11 @@ char *crypt_bcrypt(const char *passwd, const char *salt, MPI g, MPI n) return NULL; } - _gnutls_sbase64_encode(v, vsize, &rtext); + if (_gnutls_sbase64_encode(v, vsize, &rtext) < 0) { + gnutls_free(v); + gnutls_assert(); + return NULL; + } gnutls_free(v); tmp = @@ -669,6 +676,7 @@ char *crypt_bcrypt_wrapper(const char *pass_new, int cost, MPI g, MPI n) rand[0] = (uint8) cost; result_size = _gnutls_sbase64_encode(rand, 17, &result); if (result_size < 0) { + _gnutls_free_rand(rand); gnutls_assert(); return NULL; } diff --git a/lib/crypt_srpsha1.c b/lib/crypt_srpsha1.c index c7ab337f66..98cdd7139f 100644 --- a/lib/crypt_srpsha1.c +++ b/lib/crypt_srpsha1.c @@ -63,6 +63,10 @@ char *crypt_srpsha1(const char *username, const char *passwd, sp++; rsalt_size = _gnutls_sbase64_decode(sp, strlen(sp), &csalt); + if (rsalt_size < 0) { + gnutls_assert(); + return NULL; + } h1 = gnutls_hash_init(GNUTLS_MAC_SHA); gnutls_hash(h1, csalt, rsalt_size); @@ -81,7 +85,11 @@ char *crypt_srpsha1(const char *username, const char *passwd, return NULL; } - _gnutls_sbase64_encode(v, vsize, &rtext); + if (_gnutls_sbase64_encode(v, vsize, &rtext) < 0) { + gnutls_free(v); + gnutls_assert(); + return NULL; + } gnutls_free(v); tmp = @@ -113,6 +121,7 @@ char *crypt_srpsha1_wrapper(const char *username, const char *pass_new, result_size = _gnutls_sbase64_encode(rand, salt, &result); if (result_size < 0) { + _gnutls_free_rand(rand); gnutls_assert(); return NULL; } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 561cbfa154..9fea5a5be9 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -28,8 +28,8 @@ #define BUFFERS_DEBUG #define HANDSHAKE_DEBUG #define HARD_DEBUG -#define DEBUG -*/ +*/#define DEBUG + #define MAX32 4294967295 #define MAX24 16777215 diff --git a/src/crypt.c b/src/crypt.c index 634609cede..ac55d36588 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -416,6 +416,7 @@ static int read_conf_values(MPI * g, MPI * n, char *str, int str_size) /* read the generator */ len = strlen(p); + if (p[len-1]=='\n') len--; tmp_size = _gnutls_sbase64_decode(p, len, &tmp); if (tmp_size < 0) {