1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-08-07 08:02:56 +03:00

switch to internal base64 decode that uses size_t

Make the public `libssh2_base64_decode()` a wrapper for that.
Bump up length sizes in callers.

Also fix output size calculation to first divide then multiply.

Closes #978
This commit is contained in:
Viktor Szakats
2023-04-17 14:30:51 +00:00
parent fe64bad58f
commit 739e41bf40
13 changed files with 110 additions and 87 deletions

View File

@@ -991,6 +991,7 @@ libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode,
#define libssh2_scp_send(session, path, mode, size) \
libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
/* DEPRECATED */
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest,
unsigned int *dest_len,
const char *src, unsigned int src_len);

View File

@@ -141,7 +141,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
size_t hostlen = strlen(host);
int rc;
char *ptr;
unsigned int ptrlen;
size_t ptrlen;
/* make sure we have a key type set */
if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK))
@@ -169,15 +169,15 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
entry->name_len = hostlen;
break;
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
host, (unsigned int)hostlen);
rc = _libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
host, hostlen);
if(rc)
goto error;
entry->name = ptr;
entry->name_len = ptrlen;
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
salt, (unsigned int)strlen(salt));
rc = _libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
salt, strlen(salt));
if(rc)
goto error;
entry->salt = ptr;

View File

@@ -171,7 +171,7 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
{
FILE *fp;
unsigned char *data, *save_data;
unsigned int datalen;
size_t datalen;
int ret;
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
@@ -288,7 +288,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
{
FILE *fp;
unsigned char *data, *save_data;
unsigned int datalen;
size_t datalen;
int ret;
unsigned char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen;

View File

@@ -1084,7 +1084,6 @@ int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
/* misc.c */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
@@ -1098,12 +1097,12 @@ int _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, unsigned int *datalen);
FILE * fp, unsigned char **data, size_t *datalen);
int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const char *filedata, size_t filedata_len,
unsigned char **data, unsigned int *datalen);
unsigned char **data, size_t *datalen);
/* OpenSSL keys */
int
_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
@@ -1115,8 +1114,8 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
struct string_buf **decrypted_buf);
int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
int _libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen);
int _libssh2_pem_decode_integer(unsigned char **data, size_t *datalen,
unsigned char **i, unsigned int *ilen);
/* global.c */

View File

@@ -317,27 +317,46 @@ static const short base64_reverse_table[256] = {
/* libssh2_base64_decode
*
* Decode a base64 chunk and store it into a newly alloc'd buffer
* Legacy public function. DEPRECATED.
*/
/* FIXME: datalen, src_len -> size_t */
LIBSSH2_API int
libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
unsigned int *datalen, const char *src,
unsigned int src_len)
{
unsigned char *s, *d;
short v;
int i = 0, len = 0;
int rc;
size_t dlen;
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
rc = _libssh2_base64_decode(session, data, &dlen, src, src_len);
if(datalen)
*datalen = (unsigned int)dlen;
return rc;
}
/* _libssh2_base64_decode
*
* Decode a base64 chunk and store it into a newly alloc'd buffer
*/
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len)
{
unsigned char *d;
const char *s;
short v;
ssize_t i = 0, len = 0;
*data = LIBSSH2_ALLOC(session, ((src_len / 4) * 3) + 1);
d = (unsigned char *) *data;
if(!d) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64 decoding");
}
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
v = base64_reverse_table[*s];
for(s = src; s < (src + src_len); s++) {
v = base64_reverse_table[(unsigned char)*s];
if(v < 0)
continue;
switch(i % 4) {

View File

@@ -98,6 +98,9 @@ void *_libssh2_list_prev(struct list_node *node);
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry);
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len);
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr);

View File

@@ -1995,7 +1995,7 @@ try_pem_load(LIBSSH2_SESSION *session, FILE *fp,
loadkeyproc proc, void *loadkeydata)
{
unsigned char *data = NULL;
unsigned int datalen = 0;
size_t datalen = 0;
int c;
int ret;
@@ -2159,7 +2159,7 @@ _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
{
libssh2_rsa_ctx *ctx = libssh2_init_crypto_ctx(NULL);
unsigned char *data = NULL;
unsigned int datalen = 0;
size_t datalen = 0;
int ret;
if(!ctx)
@@ -2232,7 +2232,7 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
{
loadpubkeydata p;
unsigned char *data = NULL;
unsigned int datalen = 0;
size_t datalen = 0;
const char *meth;
int ret;

View File

@@ -109,7 +109,7 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, unsigned int *datalen)
FILE * fp, unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
unsigned char iv[LINE_SIZE];
@@ -200,8 +200,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
return -1;
}
if(libssh2_base64_decode(session, (char **) data, datalen,
b64data, (unsigned int)b64datalen)) {
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
@@ -296,7 +296,7 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const char *filedata, size_t filedata_len,
unsigned char **data, unsigned int *datalen)
unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
char *b64data = NULL;
@@ -345,8 +345,8 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
return -1;
}
if(libssh2_base64_decode(session, (char **) data, datalen,
b64data, (unsigned int)b64datalen)) {
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
@@ -384,7 +384,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
unsigned char *key_part = NULL;
unsigned char *iv_part = NULL;
unsigned char *f = NULL;
unsigned int f_len = 0;
size_t f_len = 0;
int ret = 0, keylen = 0, ivlen = 0, total_len = 0;
size_t kdf_len = 0, tmp_len = 0, salt_len = 0;
@@ -392,8 +392,8 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
*decrypted_buf = NULL;
/* decode file */
if(libssh2_base64_decode(session, (char **)&f, &f_len,
b64data, (unsigned int)b64datalen)) {
if(_libssh2_base64_decode(session, (char **)&f, &f_len,
b64data, b64datalen)) {
ret = -1;
goto out;
}
@@ -816,7 +816,7 @@ out:
static int
read_asn1_length(const unsigned char *data,
unsigned int datalen, unsigned int *len)
size_t datalen, size_t *len)
{
unsigned int lenlen;
int nextpos;
@@ -850,9 +850,9 @@ read_asn1_length(const unsigned char *data,
}
int
_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
_libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen)
{
unsigned int len;
size_t len;
int lenlen;
if(*datalen < 1) {
@@ -878,10 +878,10 @@ _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
}
int
_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
_libssh2_pem_decode_integer(unsigned char **data, size_t *datalen,
unsigned char **i, unsigned int *ilen)
{
unsigned int len;
size_t len;
int lenlen;
if(*datalen < 1) {
@@ -904,7 +904,7 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
*datalen -= lenlen;
*i = *data;
*ilen = len;
*ilen = (unsigned int)len;
*data += len;
*datalen -= len;

View File

@@ -568,7 +568,7 @@ memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
{
unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
size_t pubkey_len = pubkeyfiledata_len;
unsigned int tmp_len;
size_t tmp_len;
if(pubkeyfiledata_len <= 1) {
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
@@ -610,12 +610,12 @@ memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
sp2 = pubkey + pubkey_len;
}
if(libssh2_base64_decode(session, (char **)&tmp, &tmp_len,
(const char *)sp1,
(unsigned int)(sp2 - sp1))) {
if(_libssh2_base64_decode(session, (char **)&tmp, &tmp_len,
(const char *)sp1,
sp2 - sp1)) {
LIBSSH2_FREE(session, pubkey);
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Invalid key data, not base64 encoded");
"Invalid key data, not base64 encoded");
}
/* Wasting some bytes here (okay, more than some), but since it's likely
@@ -652,7 +652,7 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
char c;
unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
size_t pubkey_len = 0, sp_len;
unsigned int tmp_len;
size_t tmp_len;
_libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
pubkeyfile));
@@ -715,9 +715,9 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
sp2 = pubkey + pubkey_len;
}
if(libssh2_base64_decode(session, (char **)&tmp, &tmp_len,
(const char *)sp1,
(unsigned int)(sp2 - sp1))) {
if(_libssh2_base64_decode(session, (char **)&tmp, &tmp_len,
(const char *)sp1,
sp2 - sp1)) {
LIBSSH2_FREE(session, pubkey);
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Invalid key data, not base64 encoded");

View File

@@ -693,7 +693,7 @@ _libssh2_wincng_load_pem(LIBSSH2_SESSION *session,
const char *headerbegin,
const char *headerend,
unsigned char **data,
unsigned int *datalen)
size_t *datalen)
{
FILE *fp;
int ret;
@@ -717,11 +717,11 @@ _libssh2_wincng_load_private(LIBSSH2_SESSION *session,
const char *filename,
const unsigned char *passphrase,
unsigned char **ppbEncoded,
unsigned long *pcbEncoded,
size_t *pcbEncoded,
int tryLoadRSA, int tryLoadDSA)
{
unsigned char *data = NULL;
unsigned int datalen = 0;
size_t datalen = 0;
int ret = -1;
if(ret && tryLoadRSA) {
@@ -750,11 +750,11 @@ _libssh2_wincng_load_private_memory(LIBSSH2_SESSION *session,
size_t privatekeydata_len,
const unsigned char *passphrase,
unsigned char **ppbEncoded,
unsigned long *pcbEncoded,
size_t *pcbEncoded,
int tryLoadRSA, int tryLoadDSA)
{
unsigned char *data = NULL;
unsigned int datalen = 0;
size_t datalen = 0;
int ret = -1;
(void)passphrase;
@@ -862,7 +862,7 @@ _libssh2_wincng_bn_ltob(unsigned char *pbInput,
static int
_libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded,
unsigned long cbEncoded,
size_t cbEncoded,
unsigned char **ppbDecoded,
unsigned long *pcbDecoded)
{
@@ -871,7 +871,7 @@ _libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded,
unsigned long cbDecoded = 0, cbInteger;
int ret;
ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded,
ret = _libssh2_wincng_asn_decode(pbEncoded, (unsigned long)cbEncoded,
X509_MULTI_BYTE_UINT,
(void *)&pbInteger, &cbInteger);
if(!ret) {
@@ -890,7 +890,7 @@ _libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded,
static int
_libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded,
unsigned long cbEncoded,
size_t cbEncoded,
unsigned char ***prpbDecoded,
unsigned long **prcbDecoded,
unsigned long *pcbCount)
@@ -901,7 +901,7 @@ _libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded,
unsigned long cbDecoded, *rcbDecoded, index, length;
int ret;
ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded,
ret = _libssh2_wincng_asn_decode(pbEncoded, (unsigned long)cbEncoded,
X509_SEQUENCE_OF_ANY,
(void *)&pbDecoded, &cbDecoded);
if(!ret) {
@@ -1127,7 +1127,7 @@ static int
_libssh2_wincng_rsa_new_private_parse(libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
unsigned char *pbEncoded,
unsigned long cbEncoded)
size_t cbEncoded)
{
BCRYPT_KEY_HANDLE hKey;
unsigned char *pbStructInfo;
@@ -1136,7 +1136,7 @@ _libssh2_wincng_rsa_new_private_parse(libssh2_rsa_ctx **rsa,
(void)session;
ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded,
ret = _libssh2_wincng_asn_decode(pbEncoded, (unsigned long)cbEncoded,
PKCS_RSA_PRIVATE_KEY,
&pbStructInfo, &cbStructInfo);
@@ -1179,7 +1179,7 @@ _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
{
#ifdef HAVE_LIBCRYPT32
unsigned char *pbEncoded;
unsigned long cbEncoded;
size_t cbEncoded;
int ret;
(void)session;
@@ -1212,7 +1212,7 @@ _libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
{
#ifdef HAVE_LIBCRYPT32
unsigned char *pbEncoded;
unsigned long cbEncoded;
size_t cbEncoded;
int ret;
(void)session;
@@ -1459,7 +1459,7 @@ static int
_libssh2_wincng_dsa_new_private_parse(libssh2_dsa_ctx **dsa,
LIBSSH2_SESSION *session,
unsigned char *pbEncoded,
unsigned long cbEncoded)
size_t cbEncoded)
{
unsigned char **rpbDecoded;
unsigned long *rcbDecoded, index, length;
@@ -1510,7 +1510,7 @@ _libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
{
#ifdef HAVE_LIBCRYPT32
unsigned char *pbEncoded;
unsigned long cbEncoded;
size_t cbEncoded;
int ret;
ret = _libssh2_wincng_load_private(session, filename, passphrase,
@@ -1541,7 +1541,7 @@ _libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa,
{
#ifdef HAVE_LIBCRYPT32
unsigned char *pbEncoded;
unsigned long cbEncoded;
size_t cbEncoded;
int ret;
ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len,
@@ -1663,7 +1663,7 @@ _libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
unsigned char *pbEncoded,
unsigned long cbEncoded)
size_t cbEncoded)
{
unsigned char **rpbDecoded;
unsigned long *rcbDecoded;
@@ -1791,7 +1791,7 @@ _libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
{
#ifdef HAVE_LIBCRYPT32
unsigned char *pbEncoded;
unsigned long cbEncoded;
size_t cbEncoded;
int ret;
ret = _libssh2_wincng_load_private(session, privatekey,
@@ -1830,7 +1830,7 @@ _libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
{
#ifdef HAVE_LIBCRYPT32
unsigned char *pbEncoded;
unsigned long cbEncoded;
size_t cbEncoded;
int ret;
ret = _libssh2_wincng_load_private_memory(session, privatekeydata,

View File

@@ -46,9 +46,11 @@ librunner_la_SOURCES = \
LDADD = librunner.la
check_LTLIBRARIES = librunner.la
# This program uses an internal libssh2 function so it needs to be statically
# These programs use internal libssh2 functions so they need to be statically
# linked against libssh2
test_auth_keyboard_info_request_LDFLAGS = -static
test_hostkey_LDFLAGS = -static
test_simple_LDFLAGS = -static
# This must be last in the list so it resolves symbols in previous libraries
LDADD += ../src/libssh2.la

View File

@@ -20,7 +20,7 @@ int test(LIBSSH2_SESSION *session)
int rc;
size_t len;
int type;
unsigned int expected_len = 0;
size_t expected_len = 0;
char *expected_hostkey = NULL;
const char *hostkey = libssh2_session_hostkey(session, &len, &type);
@@ -30,19 +30,19 @@ int test(LIBSSH2_SESSION *session)
}
if(type == LIBSSH2_HOSTKEY_TYPE_ED25519) {
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_ED25519_HOSTKEY,
(unsigned int)strlen(EXPECTED_ED25519_HOSTKEY));
rc = _libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_ED25519_HOSTKEY,
strlen(EXPECTED_ED25519_HOSTKEY));
}
else if(type == LIBSSH2_HOSTKEY_TYPE_ECDSA_256) {
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_ECDSA_HOSTKEY,
(unsigned int)strlen(EXPECTED_ECDSA_HOSTKEY));
rc = _libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_ECDSA_HOSTKEY,
strlen(EXPECTED_ECDSA_HOSTKEY));
}
else if(type == LIBSSH2_HOSTKEY_TYPE_RSA) {
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_RSA_HOSTKEY,
(unsigned int)strlen(EXPECTED_RSA_HOSTKEY));
rc = _libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_RSA_HOSTKEY,
strlen(EXPECTED_RSA_HOSTKEY));
}
else {
fprintf(stderr, "Unexpected type of hostkey: %i\n", type);
@@ -50,13 +50,13 @@ int test(LIBSSH2_SESSION *session)
}
if(rc) {
print_last_session_error("libssh2_base64_decode");
print_last_session_error("_libssh2_base64_decode");
return 1;
}
if(len != expected_len) {
fprintf(stderr, "Hostkey does not have the expected length %ld!=%d\n",
(unsigned long)len, expected_len);
fprintf(stderr, "Hostkey does not have the expected length %ld!=%ld\n",
(unsigned long)len, (unsigned long)expected_len);
return 1;
}

View File

@@ -36,7 +36,7 @@
* OF SUCH DAMAGE.
*/
#include <libssh2.h>
#include "libssh2_priv.h"
#include <stdio.h>
#include <stdlib.h>
@@ -44,20 +44,19 @@
static int test_libssh2_base64_decode(LIBSSH2_SESSION *session)
{
char *data;
unsigned int datalen;
size_t datalen;
const char *src = "Zm5vcmQ=";
size_t src_len = strlen(src);
int ret;
ret = libssh2_base64_decode(session, &data, &datalen,
src, (unsigned int)src_len);
ret = _libssh2_base64_decode(session, &data, &datalen,
src, strlen(src));
if(ret)
return ret;
if(datalen != 5 || strcmp(data, "fnord") != 0) {
fprintf(stderr,
"libssh2_base64_decode() failed (%d, %.*s)\n",
datalen, datalen, data);
"_libssh2_base64_decode() failed (%d, %.*s)\n",
(unsigned int)datalen, (unsigned int)datalen, data);
return 1;
}