mirror of
https://github.com/libssh2/libssh2.git
synced 2025-11-02 10:53:16 +03:00
Pass private-key to OpenSSL as a filename with BIO_new_file().
This keeps all FILE* handling on the OpenSSL side of the DLL boundary avoiding crashes on Windows while removing the need for libssh2 to read the private key file into memory. This is now done by OpenSSL which is likely to do a better job of it.
This commit is contained in:
@@ -43,9 +43,6 @@
|
||||
#define EVP_MAX_BLOCK_LENGTH 32
|
||||
#endif
|
||||
|
||||
/* Ridiculously large key-file size cap (512KB) */
|
||||
#define MAX_KEY_FILE_LENGTH 524288
|
||||
|
||||
int
|
||||
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||
const unsigned char *edata,
|
||||
@@ -215,61 +212,21 @@ passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
|
||||
return passphrase_len;
|
||||
}
|
||||
|
||||
static int
|
||||
read_file_into_string(char ** key, LIBSSH2_SESSION * session, FILE * fp)
|
||||
{
|
||||
long size;
|
||||
size_t read;
|
||||
|
||||
*key = NULL;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
if (size < 0) {
|
||||
return -1;
|
||||
}
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
size *= sizeof(char);
|
||||
if (size > MAX_KEY_FILE_LENGTH) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*key = LIBSSH2_ALLOC(session, size + 1);
|
||||
if (!*key) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
read = fread(*key, 1, size, fp);
|
||||
if (read != (size_t) size) {
|
||||
LIBSSH2_FREE(session, *key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*key)[size] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *,
|
||||
void * u);
|
||||
|
||||
static int
|
||||
read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
|
||||
pem_read_bio_func read_private_key,
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
const char * filename,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
char * key;
|
||||
BIO * bp;
|
||||
|
||||
*key_ctx = NULL;
|
||||
|
||||
if(read_file_into_string(&key, session, fp)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bp = BIO_new_mem_buf(key, -1);
|
||||
bp = BIO_new_file(filename, "r");
|
||||
if (!bp) {
|
||||
LIBSSH2_FREE(session, key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -277,14 +234,13 @@ read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
|
||||
(void *) passphrase);
|
||||
|
||||
BIO_free(bp);
|
||||
LIBSSH2_FREE(session, key);
|
||||
return (*key_ctx) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
const char *filename, unsigned const char *passphrase)
|
||||
{
|
||||
pem_read_bio_func read_rsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
|
||||
@@ -297,14 +253,14 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
OpenSSL_add_all_ciphers();
|
||||
}
|
||||
|
||||
return read_private_key_from_file((void **) rsa, session, read_rsa, fp,
|
||||
passphrase);
|
||||
return read_private_key_from_file((void **) rsa, session, read_rsa,
|
||||
filename, passphrase);
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
const char *filename, unsigned const char *passphrase)
|
||||
{
|
||||
pem_read_bio_func read_dsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
|
||||
@@ -317,8 +273,8 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
OpenSSL_add_all_ciphers();
|
||||
}
|
||||
|
||||
return read_private_key_from_file((void **) dsa, session, read_dsa, fp,
|
||||
passphrase);
|
||||
return read_private_key_from_file((void **) dsa, session, read_dsa,
|
||||
filename, passphrase);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user