1
1

misc.c : String buffer API improvements (#332)

Files : misc.c, hostkey.c, kex.c, misc.h, openssl.c, sftp.c

Notes : 
* updated _libssh2_get_bignum_bytes and _libssh2_get_string. Now pass in length as an argument instead of returning it to keep signedness correct. Now returns -1 for failure, 0 for success.

_libssh2_check_length now returns 0 on success and -1 on failure to match the other string_buf functions. Added comment to _libssh2_check_length.

Credit : Will Cosgrove
Этот коммит содержится в:
Will Cosgrove 2019-04-23 10:28:01 -07:00 коммит произвёл GitHub
родитель a19d85319d
Коммит 8ab5c36a32
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 121 добавлений и 131 удалений

Просмотреть файл

@ -65,7 +65,7 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
{
libssh2_rsa_ctx *rsactx;
unsigned char *e, *n;
int e_len, n_len;
size_t e_len, n_len;
struct string_buf buf;
if(*abstract) {
@ -83,15 +83,13 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = hostkey_data_len;
if(_libssh2_match_string(&buf, "ssh-rsa") != 0)
if(_libssh2_match_string(&buf, "ssh-rsa"))
return -1;
e_len = _libssh2_get_c_string(&buf, &e);
if(e_len <= 0)
if(_libssh2_get_string(&buf, &e, &e_len))
return -1;
n_len = _libssh2_get_c_string(&buf, &n);
if(n_len <= 0)
if(_libssh2_get_string(&buf, &n, &n_len))
return -1;
if(_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
@ -285,7 +283,7 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
{
libssh2_dsa_ctx *dsactx;
unsigned char *p, *q, *g, *y;
int p_len, q_len, g_len, y_len;
size_t p_len, q_len, g_len, y_len;
struct string_buf buf;
if(*abstract) {
@ -303,23 +301,19 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = hostkey_data_len;
if(_libssh2_match_string(&buf, "ssh-dss") != 0)
if(_libssh2_match_string(&buf, "ssh-dss"))
return -1;
p_len = _libssh2_get_c_string(&buf, &p);
if(p_len < 0)
if(_libssh2_get_string(&buf, &p, &p_len))
return -1;
q_len = _libssh2_get_c_string(&buf, &q);
if(q_len < 0)
if(_libssh2_get_string(&buf, &q, &q_len))
return -1;
g_len = _libssh2_get_c_string(&buf, &g);
if(g_len < 0)
if(_libssh2_get_string(&buf, &g, &g_len))
return -1;
y_len = _libssh2_get_c_string(&buf, &y);
if(y_len < 0)
if(_libssh2_get_string(&buf, &y, &y_len))
return -1;
if(_libssh2_dsa_new(&dsactx, p, p_len, q, q_len,
@ -512,7 +506,7 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
{
libssh2_ecdsa_ctx *ecdsactx = NULL;
unsigned char *type_str, *domain, *public_key;
int key_len;
size_t key_len, len;
libssh2_curve_type type;
struct string_buf buf;
@ -531,7 +525,7 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = hostkey_data_len;
if(_libssh2_get_c_string(&buf, &type_str) != 19)
if(_libssh2_get_string(&buf, &type_str, &len) || len != 19)
return -1;
if(strncmp((char *) type_str, "ecdsa-sha2-nistp256", 19) == 0) {
@ -547,7 +541,7 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
return -1;
}
if(_libssh2_get_c_string(&buf, &domain) != 8)
if(_libssh2_get_string(&buf, &domain, &len) || len != 8)
return -1;
if(type == LIBSSH2_EC_CURVE_NISTP256 &&
@ -564,8 +558,7 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
}
/* public key */
key_len = _libssh2_get_c_string(&buf, &public_key);
if(key_len <= 0)
if(_libssh2_get_string(&buf, &public_key, &key_len))
return -1;
if(_libssh2_ecdsa_curve_name_with_octal_new(&ecdsactx, public_key,
@ -653,7 +646,8 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
size_t m_len, void **abstract)
{
unsigned char *r, *s, *name;
unsigned int r_len, s_len, len;
size_t r_len, s_len, name_len;
unsigned int len;
struct string_buf buf;
libssh2_ecdsa_ctx *ctx = (libssh2_ecdsa_ctx *) (*abstract);
@ -668,18 +662,16 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = sig_len;
if(_libssh2_get_c_string(&buf, &name) != 19)
if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19)
return -1;
if(_libssh2_get_u32(&buf, &len) != 0 || len < 8)
return -1;
r_len = _libssh2_get_c_string(&buf, &r);
if(r_len <= 0)
if(_libssh2_get_string(&buf, &r, &r_len))
return -1;
s_len = _libssh2_get_c_string(&buf, &s);
if(s_len <= 0)
if(_libssh2_get_string(&buf, &s, &s_len))
return -1;
return _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len);

Просмотреть файл

@ -1705,7 +1705,7 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
}
if(key_state->state == libssh2_NB_state_sent1) {
unsigned int p_len, g_len;
size_t p_len, g_len;
unsigned char *p, *g;
struct string_buf buf;
@ -1721,15 +1721,13 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
buf.dataptr++; /* increment to big num */
p_len = _libssh2_get_bignum_bytes(&buf, &p);
if(p_len <= 0) {
if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unexpected value");
goto dh_gex_clean_exit;
}
g_len = _libssh2_get_bignum_bytes(&buf, &g);
if(g_len <= 0) {
if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unexpected value");
goto dh_gex_clean_exit;
@ -1833,7 +1831,7 @@ kex_method_diffie_hellman_group_exchange_sha256_key_exchange
if(key_state->state == libssh2_NB_state_sent1) {
unsigned char *p, *g;
unsigned long p_len, g_len;
size_t p_len, g_len;
struct string_buf buf;
if(key_state->data_len < 9) {
@ -1848,15 +1846,13 @@ kex_method_diffie_hellman_group_exchange_sha256_key_exchange
buf.dataptr++; /* increment to big num */
p_len = _libssh2_get_bignum_bytes(&buf, &p);
if(p_len <= 0) {
if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unexpected value");
goto dh_gex_clean_exit;
}
g_len = _libssh2_get_bignum_bytes(&buf, &g);
if(g_len <= 0) {
if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unexpected value");
goto dh_gex_clean_exit;
@ -2675,7 +2671,7 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
if(exchange_state->state == libssh2_NB_state_created) {
/* parse INIT reply data */
unsigned char *server_public_key, *server_host_key;
unsigned int server_public_key_len;
size_t server_public_key_len, hostkey_len;
struct string_buf buf;
if(data_len < 5) {
@ -2689,14 +2685,13 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
buf.dataptr = buf.data;
buf.dataptr++; /* advance past packet type */
session->server_hostkey_len =
_libssh2_get_c_string(&buf, &server_host_key);
if(session->server_hostkey_len <= 0) {
if(_libssh2_get_string(&buf, &server_host_key, &hostkey_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unexpected key length");
goto clean_exit;
}
session->server_hostkey_len = (u_int32_t)hostkey_len;
session->server_hostkey = LIBSSH2_ALLOC(session,
session->server_hostkey_len);
if(!session->server_hostkey) {
@ -2806,8 +2801,8 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
}
/* server public key Q_S */
if((server_public_key_len =
_libssh2_get_c_string(&buf, &server_public_key)) <= 0) {
if(_libssh2_get_string(&buf, &server_public_key,
&server_public_key_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unexpected key length");
goto clean_exit;
@ -2821,12 +2816,11 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
}
/* server signature */
if((exchange_state->h_sig_len =
_libssh2_get_c_string(&buf, &exchange_state->h_sig)) <= 0) {
if(_libssh2_get_string(&buf, &exchange_state->h_sig,
&(exchange_state->h_sig_len))) {
ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
"Unexpected curve25519 server sig length");
goto clean_exit;
}
/* Compute the shared secret K */

Просмотреть файл

@ -759,14 +759,16 @@ int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out)
int _libssh2_match_string(struct string_buf *buf, const char *match)
{
unsigned char *out;
if((size_t)_libssh2_get_c_string(buf, &out) != strlen(match) ||
strncmp((char *)out, match, strlen(match)) != 0) {
size_t len = 0;
if(_libssh2_get_string(buf, &out, &len) || len != strlen(match) ||
strncmp((char *)out, match, strlen(match)) != 0) {
return -1;
}
return 0;
}
int _libssh2_get_c_string(struct string_buf *buf, unsigned char **outbuf)
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
if(_libssh2_get_u32(buf, &data_len) != 0) {
@ -777,16 +779,21 @@ int _libssh2_get_c_string(struct string_buf *buf, unsigned char **outbuf)
}
*outbuf = buf->dataptr;
buf->dataptr += data_len;
return data_len;
if(outlen)
*outlen = (size_t)data_len;
return 0;
}
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf)
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
uint32_t bn_len;
unsigned char *bnptr;
if(_libssh2_get_u32(buf, &data_len) != 0) {
if(_libssh2_get_u32(buf, &data_len)) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
@ -803,12 +810,18 @@ int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf)
}
*outbuf = bnptr;
buf->dataptr += data_len;
return bn_len;
if(outlen)
*outlen = (size_t)bn_len;
return 0;
}
/* Given the current location in buf, _libssh2_check_length ensures
callers can read the next len number of bytes out of the buffer
before reading the buffer content */
int _libssh2_check_length(struct string_buf *buf, size_t len)
{
unsigned char *endp = &buf->data[buf->len];

Просмотреть файл

@ -94,8 +94,10 @@ void _libssh2_string_buf_free(LIBSSH2_SESSION *session,
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out);
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out);
int _libssh2_match_string(struct string_buf *buf, const char *match);
int _libssh2_get_c_string(struct string_buf *buf, unsigned char **outbuf);
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf);
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_check_length(struct string_buf *buf, size_t requested_len);
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)

Просмотреть файл

@ -955,9 +955,8 @@ gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session,
libssh2_rsa_ctx **rsa_ctx)
{
int rc = 0;
int nlen, elen, dlen, plen, qlen, coefflen;
size_t nlen, elen, dlen, plen, qlen, coefflen, commentlen;
unsigned char *n, *e, *d, *p, *q, *coeff, *comment;
int commentlen;
RSA *rsa = NULL;
_libssh2_debug(session,
@ -965,51 +964,44 @@ gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session,
"Computing RSA keys from private key data");
/* public key data */
nlen = _libssh2_get_bignum_bytes(decrypted, &n);
if(nlen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &n, &nlen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"RSA no n");
return -1;
}
elen = _libssh2_get_bignum_bytes(decrypted, &e);
if(elen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &e, &elen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"RSA no e");
return -1;
}
/* private key data */
dlen = _libssh2_get_bignum_bytes(decrypted, &d);
if(dlen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &d, &dlen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"RSA no d");
return -1;
}
coefflen = _libssh2_get_bignum_bytes(decrypted, &coeff);
if(coefflen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &coeff, &coefflen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"RSA no coeff");
return -1;
}
plen = _libssh2_get_bignum_bytes(decrypted, &p);
if(plen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"RSA no p");
return -1;
}
qlen = _libssh2_get_bignum_bytes(decrypted, &q);
if(qlen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"RSA no q");
return -1;
}
commentlen = _libssh2_get_c_string(decrypted, &comment);
if(commentlen < 0) {
if(_libssh2_get_string(decrypted, &comment, &commentlen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"RSA no comment");
return -1;
@ -1089,9 +1081,9 @@ _libssh2_rsa_new_openssh_private(libssh2_rsa_ctx ** rsa,
}
/* We have a new key file, now try and parse it using supported types */
rc = _libssh2_get_c_string(decrypted, &buf);
rc = _libssh2_get_string(decrypted, &buf, NULL);
if(rc < 1 || buf == NULL) {
if(rc != 0 || buf == NULL) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Public key type in decrypted key data not found");
return -1;
@ -1282,7 +1274,7 @@ gen_publickey_from_dsa_openssh_priv_data(LIBSSH2_SESSION *session,
libssh2_dsa_ctx **dsa_ctx)
{
int rc = 0;
int plen, qlen, glen, pub_len, priv_len;
size_t plen, qlen, glen, pub_len, priv_len;
unsigned char *p, *q, *g, *pub_key, *priv_key;
DSA *dsa = NULL;
@ -1290,36 +1282,31 @@ gen_publickey_from_dsa_openssh_priv_data(LIBSSH2_SESSION *session,
LIBSSH2_TRACE_AUTH,
"Computing DSA keys from private key data");
plen = _libssh2_get_bignum_bytes(decrypted, &p);
if(plen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"DSA no p");
return -1;
}
qlen = _libssh2_get_bignum_bytes(decrypted, &q);
if(qlen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"DSA no q");
return -1;
}
glen = _libssh2_get_bignum_bytes(decrypted, &g);
if(glen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &g, &glen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"DSA no g");
return -1;
}
pub_len = _libssh2_get_bignum_bytes(decrypted, &pub_key);
if(pub_len <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &pub_key, &pub_len)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"DSA no public key");
return -1;
}
priv_len = _libssh2_get_bignum_bytes(decrypted, &priv_key);
if(priv_len <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &priv_key, &priv_len)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"DSA no private key");
return -1;
@ -1396,9 +1383,9 @@ _libssh2_dsa_new_openssh_private(libssh2_dsa_ctx ** dsa,
}
/* We have a new key file, now try and parse it using supported types */
rc = _libssh2_get_c_string(decrypted, &buf);
rc = _libssh2_get_string(decrypted, &buf, NULL);
if(rc < 1 || buf == NULL) {
if(rc != 0 || buf == NULL) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Public key type in decrypted key data not found");
return -1;
@ -1595,23 +1582,24 @@ gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
libssh2_ed25519_ctx *ctx = NULL;
unsigned char *method_buf = NULL;
unsigned char *key = NULL;
int i, rc, ret = 0;
int i, ret = 0;
unsigned char *pub_key, *priv_key, *buf;
size_t key_len = 0;
size_t key_len = 0, tmp_len = 0;
unsigned char *p;
_libssh2_debug(session,
LIBSSH2_TRACE_AUTH,
"Computing ED25519 keys from private key data");
if(_libssh2_get_c_string(decrypted, &pub_key) != LIBSSH2_ED25519_KEY_LEN) {
if(_libssh2_get_string(decrypted, &pub_key, &tmp_len) ||
tmp_len != LIBSSH2_ED25519_KEY_LEN) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Wrong public key length");
return -1;
}
if(_libssh2_get_c_string(decrypted, &priv_key) !=
LIBSSH2_ED25519_PRIVATE_KEY_LEN) {
if(_libssh2_get_string(decrypted, &priv_key, &tmp_len) ||
tmp_len != LIBSSH2_ED25519_PRIVATE_KEY_LEN) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Wrong private key length");
ret = -1;
@ -1639,19 +1627,18 @@ gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
LIBSSH2_ED25519_KEY_LEN);
/* comment */
rc = _libssh2_get_c_string(decrypted, &buf);
if(rc < 0) {
if(_libssh2_get_string(decrypted, &buf, &tmp_len)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unable to read comment");
ret = -1;
goto clean_exit;
}
if(rc > 0) {
unsigned char *comment = LIBSSH2_CALLOC(session, rc + 1);
if(tmp_len > 0) {
unsigned char *comment = LIBSSH2_CALLOC(session, tmp_len + 1);
if(comment != NULL) {
memcpy(comment, buf, rc);
memcpy(comment + rc, "\0", 1);
memcpy(comment, buf, tmp_len);
memcpy(comment + tmp_len, "\0", 1);
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Key comment: %s",
comment);
@ -1770,9 +1757,9 @@ _libssh2_ed25519_new_private(libssh2_ed25519_ctx ** ed_ctx,
}
/* We have a new key file, now try and parse it using supported types */
rc = _libssh2_get_c_string(decrypted, &buf);
rc = _libssh2_get_string(decrypted, &buf, NULL);
if(rc < 1 || buf == NULL) {
if(rc != 0 || buf == NULL) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Public key type in decrypted key data not found");
return -1;
@ -1787,6 +1774,9 @@ _libssh2_ed25519_new_private(libssh2_ed25519_ctx ** ed_ctx,
NULL,
&ctx);
}
else {
rc = -1;
}
if(decrypted)
_libssh2_string_buf_free(session, decrypted);
@ -2363,7 +2353,7 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
libssh2_ecdsa_ctx **ec_ctx)
{
int rc = 0;
int curvelen, exponentlen, pointlen;
size_t curvelen, exponentlen, pointlen;
unsigned char *curve, *exponent, *point_buf;
EC_KEY *ec_key = NULL;
BIGNUM *bn_exponent;
@ -2372,30 +2362,27 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
LIBSSH2_TRACE_AUTH,
"Computing ECDSA keys from private key data");
curvelen = _libssh2_get_c_string(decrypted, &curve);
if(curvelen <= 0) {
if(_libssh2_get_string(decrypted, &curve, &curvelen) ||
curvelen == 0) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ECDSA no curve");
return -1;
}
pointlen = _libssh2_get_c_string(decrypted, &point_buf);
if(pointlen <= 0) {
if(_libssh2_get_string(decrypted, &point_buf, &pointlen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ECDSA no point");
return -1;
}
exponentlen = _libssh2_get_bignum_bytes(decrypted, &exponent);
if(exponentlen <= 0) {
if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ECDSA no exponent");
return -1;
}
rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf,
pointlen, curve_type);
if(rc != 0) {
if((rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf,
pointlen, curve_type)) != 0) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ECDSA could not create key");
goto fail;
@ -2475,9 +2462,9 @@ _libssh2_ecdsa_new_openssh_private(libssh2_ecdsa_ctx ** ec_ctx,
}
/* We have a new key file, now try and parse it using supported types */
rc = _libssh2_get_c_string(decrypted, &buf);
rc = _libssh2_get_string(decrypted, &buf, NULL);
if(rc < 1 || buf == NULL) {
if(rc != 0 || buf == NULL) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Public key type in decrypted key data not found");
return -1;
@ -2852,9 +2839,9 @@ _libssh2_pub_priv_openssh_keyfile(LIBSSH2_SESSION *session,
}
/* We have a new key file, now try and parse it using supported types */
rc = _libssh2_get_c_string(decrypted, &buf);
rc = _libssh2_get_string(decrypted, &buf, NULL);
if(rc < 1 || buf == NULL) {
if(rc != 0 || buf == NULL) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Public key type in decrypted key data not found");
return -1;
@ -3049,14 +3036,16 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
}
/* We have a new key file, now try and parse it using supported types */
rc = _libssh2_get_c_string(decrypted, &buf);
rc = _libssh2_get_string(decrypted, &buf, NULL);
if(rc < 1 || buf == NULL) {
if(rc != 0 || buf == NULL) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Public key type in decrypted key data not found");
return -1;
}
rc = -1;
#if LIBSSH2_ED25519
if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
if(key_type == NULL || strcmp("ssh-ed25519", key_type) == 0) {

Просмотреть файл

@ -372,14 +372,15 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
unsigned char *kdf = NULL;
unsigned char *buf = NULL;
unsigned char *salt = NULL;
uint32_t nkeys, check1, check2, salt_len;
uint32_t nkeys, check1, check2;
uint32_t rounds = 0;
unsigned char *key = NULL;
unsigned char *key_part = NULL;
unsigned char *iv_part = NULL;
unsigned char *f = NULL;
unsigned int f_len = 0;
int ret = 0, rc = 0, kdf_len = 0, keylen = 0, ivlen = 0, total_len = 0;
int ret = 0, keylen = 0, ivlen = 0, total_len = 0;
size_t kdf_len = 0, tmp_len = 0, salt_len = 0;
if(decrypted_buf)
*decrypted_buf = NULL;
@ -410,20 +411,21 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
decoded.dataptr += strlen(AUTH_MAGIC) + 1;
if(_libssh2_get_c_string(&decoded, &ciphername) == 0) {
if(_libssh2_get_string(&decoded, &ciphername, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ciphername is missing");
goto out;
}
if(_libssh2_get_c_string(&decoded, &kdfname) == 0) {
if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdfname is missing");
goto out;
}
kdf_len = _libssh2_get_c_string(&decoded, &kdf);
if(kdf == NULL) {
if(_libssh2_get_string(&decoded, &kdf, &kdf_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf is missing");
goto out;
@ -463,15 +465,14 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
/* unencrypted public key */
if(_libssh2_get_c_string(&decoded, &buf) < 0) {
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid private key; "
"expect embedded public key");
goto out;
}
rc = _libssh2_get_c_string(&decoded, &buf);
if(rc <= 0) {
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key data not found");
goto out;
@ -479,7 +480,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
/* decode encrypted private key */
decrypted.data = decrypted.dataptr = buf;
decrypted.len = rc;
decrypted.len = tmp_len;
if(ciphername && strcmp((const char *)ciphername, "none") != 0) {
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
@ -520,9 +521,8 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
if(strcmp((const char *)kdfname, "bcrypt") == 0 &&
passphrase != NULL) {
salt_len = _libssh2_get_c_string(&kdf_buf, &salt);
if((salt_len <= 0) ||
(_libssh2_get_u32(&kdf_buf, &rounds) != 0) ) {
if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) ||
(_libssh2_get_u32(&kdf_buf, &rounds) != 0) ) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf contains unexpected values");
LIBSSH2_FREE(session, key);

Просмотреть файл

@ -940,14 +940,14 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
while(buf.dataptr < endp) {
unsigned char *extname, *extdata;
if(_libssh2_get_c_string(&buf, &extname) < 0) {
if(_libssh2_get_string(&buf, &extname, NULL)) {
LIBSSH2_FREE(session, data);
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Data too short when extracting extname");
goto sftp_init_error;
}
if(_libssh2_get_c_string(&buf, &extdata) < 0) {
if(_libssh2_get_string(&buf, &extdata, NULL)) {
LIBSSH2_FREE(session, data);
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Data too short when extracting extdata");