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
Этот коммит содержится в:
родитель
a19d85319d
Коммит
8ab5c36a32
@ -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);
|
||||
|
32
src/kex.c
32
src/kex.c
@ -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 */
|
||||
|
29
src/misc.c
29
src/misc.c
@ -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__)
|
||||
|
109
src/openssl.c
109
src/openssl.c
@ -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) {
|
||||
|
26
src/pem.c
26
src/pem.c
@ -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");
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user