mirror of
https://github.com/libssh2/libssh2.git
synced 2025-11-20 02:42:09 +03:00
Fix detailed _libssh2_error being overwritten (#473)
Files: openssl.c, pem.c, userauth.c Notes: * Fix detailed _libssh2_error being overwritten by generic errors * Unified error handling Credit: Zenju
This commit is contained in:
@@ -1690,6 +1690,8 @@ gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
|
|||||||
|
|
||||||
method_buf = LIBSSH2_ALLOC(session, 11); /* ssh-ed25519. */
|
method_buf = LIBSSH2_ALLOC(session, 11); /* ssh-ed25519. */
|
||||||
if(method_buf == NULL) {
|
if(method_buf == NULL) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for ED25519 key");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1698,6 +1700,8 @@ gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
|
|||||||
key_len = LIBSSH2_ED25519_KEY_LEN + 19;
|
key_len = LIBSSH2_ED25519_KEY_LEN + 19;
|
||||||
key = LIBSSH2_CALLOC(session, key_len);
|
key = LIBSSH2_CALLOC(session, key_len);
|
||||||
if(key == NULL) {
|
if(key == NULL) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for ED25519 key");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2418,6 +2422,7 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
|
|||||||
|
|
||||||
if((rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf,
|
if((rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf,
|
||||||
pointlen, curve_type)) != 0) {
|
pointlen, curve_type)) != 0) {
|
||||||
|
rc = -1;
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
"ECDSA could not create key");
|
"ECDSA could not create key");
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -2426,6 +2431,8 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
|
|||||||
bn_exponent = BN_new();
|
bn_exponent = BN_new();
|
||||||
if(bn_exponent == NULL) {
|
if(bn_exponent == NULL) {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for private key data");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2452,15 +2459,10 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
if(ec_key != NULL)
|
if(ec_key != NULL)
|
||||||
EC_KEY_free(ec_key);
|
EC_KEY_free(ec_key);
|
||||||
|
|
||||||
return _libssh2_error(session,
|
return rc;
|
||||||
LIBSSH2_ERROR_ALLOC,
|
|
||||||
"Unable to allocate memory for private key data");
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -3053,17 +3055,13 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
|
|||||||
if(key_ctx != NULL)
|
if(key_ctx != NULL)
|
||||||
*key_ctx = NULL;
|
*key_ctx = NULL;
|
||||||
|
|
||||||
if(session == NULL) {
|
if(session == NULL)
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
"Session is required");
|
"Session is required");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(key_type != NULL && (strlen(key_type) > 11 || strlen(key_type) < 7)) {
|
if(key_type != NULL && (strlen(key_type) > 11 || strlen(key_type) < 7))
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
"type is invalid");
|
"type is invalid");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_libssh2_init_if_needed();
|
_libssh2_init_if_needed();
|
||||||
|
|
||||||
@@ -3071,20 +3069,18 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
|
|||||||
privatekeydata,
|
privatekeydata,
|
||||||
privatekeydata_len, &decrypted);
|
privatekeydata_len, &decrypted);
|
||||||
|
|
||||||
if(rc) {
|
if(rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
/* We have a new key file, now try and parse it using supported types */
|
/* We have a new key file, now try and parse it using supported types */
|
||||||
rc = _libssh2_get_string(decrypted, &buf, NULL);
|
rc = _libssh2_get_string(decrypted, &buf, NULL);
|
||||||
|
|
||||||
if(rc != 0 || buf == NULL) {
|
if(rc != 0 || buf == NULL)
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
"Public key type in decrypted key data not found");
|
"Public key type in decrypted "
|
||||||
return -1;
|
"key data not found");
|
||||||
}
|
|
||||||
|
|
||||||
rc = -1;
|
rc = LIBSSH2_ERROR_FILE;
|
||||||
|
|
||||||
#if LIBSSH2_ED25519
|
#if LIBSSH2_ED25519
|
||||||
if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
|
if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
|
||||||
@@ -3138,6 +3134,11 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(rc == LIBSSH2_ERROR_FILE)
|
||||||
|
rc = _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||||
|
"Unable to extract public key from private key file: "
|
||||||
|
"invalid/unrecognized private key file format");
|
||||||
|
|
||||||
if(decrypted)
|
if(decrypted)
|
||||||
_libssh2_string_buf_free(session, decrypted);
|
_libssh2_string_buf_free(session, decrypted);
|
||||||
|
|
||||||
@@ -3177,10 +3178,10 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
|||||||
"Computing public key from private key.");
|
"Computing public key from private key.");
|
||||||
|
|
||||||
bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len);
|
bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len);
|
||||||
if(!bp) {
|
if(!bp)
|
||||||
return -1;
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
}
|
"Unable to allocate memory when"
|
||||||
|
"computing public key");
|
||||||
BIO_reset(bp);
|
BIO_reset(bp);
|
||||||
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
|
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
|
||||||
BIO_free(bp);
|
BIO_free(bp);
|
||||||
@@ -3195,15 +3196,8 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
|||||||
privatekeydata,
|
privatekeydata,
|
||||||
privatekeydata_len,
|
privatekeydata_len,
|
||||||
(unsigned const char *)passphrase);
|
(unsigned const char *)passphrase);
|
||||||
if(st != 0) {
|
if(st != 0)
|
||||||
return _libssh2_error(session,
|
return st;
|
||||||
LIBSSH2_ERROR_FILE,
|
|
||||||
"Unable to extract public key "
|
|
||||||
"from private key file: "
|
|
||||||
"Wrong passphrase or invalid/unrecognized "
|
|
||||||
"private key file format");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
src/pem.c
31
src/pem.c
@@ -176,6 +176,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
|||||||
linelen = strlen(line);
|
linelen = strlen(line);
|
||||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||||
if(!tmp) {
|
if(!tmp) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for PEM parsing");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -319,6 +321,8 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
|
|||||||
linelen = strlen(line);
|
linelen = strlen(line);
|
||||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||||
if(!tmp) {
|
if(!tmp) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for PEM parsing");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -690,6 +694,8 @@ _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
|
|||||||
linelen = strlen(line);
|
linelen = strlen(line);
|
||||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||||
if(!tmp) {
|
if(!tmp) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for PEM parsing");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -738,17 +744,17 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
|||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if(filedata == NULL || filedata_len <= 0) {
|
if(filedata == NULL || filedata_len <= 0)
|
||||||
return -1;
|
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
}
|
"Error parsing PEM: filedata missing");
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
*line = '\0';
|
*line = '\0';
|
||||||
|
|
||||||
if(off >= filedata_len) {
|
if(off >= filedata_len)
|
||||||
return -1;
|
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
}
|
"Error parsing PEM: offset out of bounds");
|
||||||
|
|
||||||
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -766,7 +772,9 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
|||||||
linelen = strlen(line);
|
linelen = strlen(line);
|
||||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||||
if(!tmp) {
|
if(!tmp) {
|
||||||
ret = -1;
|
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for "
|
||||||
|
"PEM parsing");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
memcpy(tmp + b64datalen, line, linelen);
|
memcpy(tmp + b64datalen, line, linelen);
|
||||||
@@ -777,7 +785,8 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
|||||||
*line = '\0';
|
*line = '\0';
|
||||||
|
|
||||||
if(off >= filedata_len) {
|
if(off >= filedata_len) {
|
||||||
ret = -1;
|
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
|
"Error parsing PEM: offset out of bounds");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,9 +796,9 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
|||||||
}
|
}
|
||||||
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
|
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
|
||||||
|
|
||||||
if(!b64data) {
|
if(!b64data)
|
||||||
return -1;
|
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
}
|
"Error parsing PEM: base 64 data missing");
|
||||||
|
|
||||||
ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data,
|
ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data,
|
||||||
b64datalen, decrypted_buf);
|
b64datalen, decrypted_buf);
|
||||||
|
|||||||
@@ -1447,15 +1447,14 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
|||||||
}
|
}
|
||||||
else if(privatekeydata_len && privatekeydata) {
|
else if(privatekeydata_len && privatekeydata) {
|
||||||
/* Compute public key from private key. */
|
/* Compute public key from private key. */
|
||||||
if(_libssh2_pub_priv_keyfilememory(session,
|
rc = _libssh2_pub_priv_keyfilememory(session,
|
||||||
&session->userauth_pblc_method,
|
&session->userauth_pblc_method,
|
||||||
&session->userauth_pblc_method_len,
|
&session->userauth_pblc_method_len,
|
||||||
&pubkeydata, &pubkeydata_len,
|
&pubkeydata, &pubkeydata_len,
|
||||||
privatekeydata, privatekeydata_len,
|
privatekeydata, privatekeydata_len,
|
||||||
passphrase))
|
passphrase);
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
if(rc)
|
||||||
"Unable to extract public key "
|
return rc;
|
||||||
"from private key.");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||||
|
|||||||
Reference in New Issue
Block a user