diff --git a/src/hostkey.c b/src/hostkey.c index 0f3c8b8..a8bd42b 100644 --- a/src/hostkey.c +++ b/src/hostkey.c @@ -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); diff --git a/src/kex.c b/src/kex.c index 94de578..cf9331b 100644 --- a/src/kex.c +++ b/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 */ diff --git a/src/misc.c b/src/misc.c index 76644a3..487a8df 100644 --- a/src/misc.c +++ b/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]; diff --git a/src/misc.h b/src/misc.h index cd86b26..47d42ec 100644 --- a/src/misc.h +++ b/src/misc.h @@ -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__) diff --git a/src/openssl.c b/src/openssl.c index 6a6c2a7..04d5ec2 100644 --- a/src/openssl.c +++ b/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) { diff --git a/src/pem.c b/src/pem.c index 89132b1..53f58c2 100644 --- a/src/pem.c +++ b/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); diff --git a/src/sftp.c b/src/sftp.c index 245f134..b4609bf 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -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");