From a19d85319dfc950462721497f937ee1442f0ab00 Mon Sep 17 00:00:00 2001 From: doublex Date: Fri, 19 Apr 2019 23:26:03 +0200 Subject: [PATCH] mbedtls.c : _libssh2_mbedtls_rsa_new_private_frommemory() allow private-key from memory (#359) File : mbedtls.c Notes: _libssh2_mbedtls_rsa_new_private_frommemory() fixes private-key from memory reading to by adding NULL terminator before parsing; adds passphrase support. Credit: doublex --- src/mbedtls.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/mbedtls.c b/src/mbedtls.c index e2b307af..8bbcfd8d 100644 --- a/src/mbedtls.c +++ b/src/mbedtls.c @@ -414,15 +414,31 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, int ret; mbedtls_pk_context pkey; mbedtls_rsa_context *pk_rsa; + void *filedata_nullterm; + size_t pwd_len; *rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); if(*rsa == NULL) return -1; + /* + mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" + private-key from memory will fail if the last byte is not a null byte + */ + filedata_nullterm = mbedtls_calloc(filedata_len + 1, 1); + if(filedata_nullterm == NULL) { + return -1; + } + memcpy(filedata_nullterm, filedata, filedata_len); + mbedtls_pk_init(&pkey); - ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata, - filedata_len, NULL, 0); + pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0; + ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm, + filedata_len + 1, + passphrase, pwd_len); + _libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len); + if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) { mbedtls_pk_free(&pkey); mbedtls_rsa_free(*rsa); @@ -635,10 +651,28 @@ _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session, mbedtls_pk_context pkey; char buf[1024]; int ret; + void *privatekeydata_nullterm; + size_t pwd_len; + + /* + mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" + private-key from memory will fail if the last byte is not a null byte + */ + privatekeydata_nullterm = mbedtls_calloc(privatekeydata_len + 1, 1); + if(privatekeydata_nullterm == NULL) { + return -1; + } + memcpy(privatekeydata_nullterm, privatekeydata, privatekeydata_len); mbedtls_pk_init(&pkey); - ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)privatekeydata, - privatekeydata_len, NULL, 0); + + pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0; + ret = mbedtls_pk_parse_key(&pkey, + (unsigned char *)privatekeydata_nullterm, + privatekeydata_len + 1, + (const unsigned char *)passphrase, pwd_len); + _libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len); + if(ret != 0) { mbedtls_strerror(ret, (char *)buf, sizeof(buf)); mbedtls_pk_free(&pkey);