mbedtls.c : _libssh2_mbedtls_rsa_new_private_frommemory() allow private-key from memory
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
@@ -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);
