mirror of
https://github.com/libssh2/libssh2.git
synced 2025-11-20 02:42:09 +03:00
add mbedTLS 3.x support
Make libssh2 compile cleanly with mbedTLS 3.x and later. This patch makes use of `MBEDTLS_PRIVATE()`, which is not the recommended, future-proof way to access mbedTLS data structures. This method may break with a minor upgrade, according to the authors. This is also the method used by libcurl. Also: - Fix a potentially uninitialized variable in `libssh2_mbedtls_rsa_sha2_sign()`. This happened in an error path, resulting in an unnecessary mbedTLS API call, with an uninitialized `md_type`. - Bump mbedTLS version used in CI tests to 3.2.1. Fixes #751
This commit is contained in:
committed by
Viktor Szakats
parent
e9561dd66e
commit
048a6b411f
156
src/mbedtls.c
156
src/mbedtls.c
@@ -122,10 +122,14 @@ _libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx,
|
||||
mbedtls_cipher_init(ctx);
|
||||
ret = mbedtls_cipher_setup(ctx, cipher_info);
|
||||
if(!ret)
|
||||
ret = mbedtls_cipher_setkey(ctx, secret, cipher_info->key_bitlen, op);
|
||||
ret = mbedtls_cipher_setkey(ctx,
|
||||
secret,
|
||||
mbedtls_cipher_info_get_key_bitlen(cipher_info),
|
||||
op);
|
||||
|
||||
if(!ret)
|
||||
ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->iv_size);
|
||||
ret = mbedtls_cipher_set_iv(ctx, iv,
|
||||
mbedtls_cipher_info_get_iv_size(cipher_info));
|
||||
|
||||
return ret == 0 ? 0 : -1;
|
||||
}
|
||||
@@ -331,29 +335,33 @@ _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
|
||||
ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
|
||||
if(ctx != NULL) {
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
mbedtls_rsa_init(ctx);
|
||||
#else
|
||||
mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
/* !checksrc! disable ASSIGNWITHINCONDITION 1 */
|
||||
if((ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0) {
|
||||
if((ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(E)), edata, elen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(N)), ndata, nlen) ) != 0) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if(!ret) {
|
||||
ctx->len = mbedtls_mpi_size(&(ctx->N));
|
||||
ctx->MBEDTLS_PRIVATE(len) = mbedtls_mpi_size(&(ctx->MBEDTLS_PRIVATE(N)));
|
||||
}
|
||||
|
||||
if(!ret && ddata) {
|
||||
/* !checksrc! disable ASSIGNWITHINCONDITION 1 */
|
||||
if((ret = mbedtls_mpi_read_binary(&(ctx->D), ddata, dlen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->P), pdata, plen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->Q), qdata, qlen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->DP), e1data, e1len) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->DQ), e2data, e2len) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->QP), coeffdata, coefflen) )
|
||||
if((ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(D)), ddata, dlen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(P)), pdata, plen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(Q)), qdata, qlen) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(DP)), e1data, e1len) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(DQ)), e2data, e2len) ) != 0 ||
|
||||
(ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(QP)), coeffdata, coefflen) )
|
||||
!= 0) {
|
||||
ret = -1;
|
||||
}
|
||||
@@ -385,10 +393,20 @@ _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
if(*rsa == NULL)
|
||||
return -1;
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
mbedtls_rsa_init(*rsa);
|
||||
#else
|
||||
mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0);
|
||||
#endif
|
||||
mbedtls_pk_init(&pkey);
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg);
|
||||
#else
|
||||
ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase);
|
||||
#endif
|
||||
if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
|
||||
mbedtls_pk_free(&pkey);
|
||||
mbedtls_rsa_free(*rsa);
|
||||
@@ -434,9 +452,17 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
|
||||
mbedtls_pk_init(&pkey);
|
||||
|
||||
pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0;
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
|
||||
filedata_len + 1,
|
||||
passphrase, pwd_len,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg);
|
||||
#else
|
||||
ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
|
||||
filedata_len + 1,
|
||||
passphrase, pwd_len);
|
||||
#endif
|
||||
_libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len);
|
||||
|
||||
if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
|
||||
@@ -487,9 +513,15 @@ _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
|
||||
return -1; /* failure */
|
||||
}
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
ret = mbedtls_rsa_pkcs1_verify(rsactx,
|
||||
md_type, hash_len,
|
||||
hash, sig);
|
||||
#else
|
||||
ret = mbedtls_rsa_pkcs1_verify(rsactx, NULL, NULL, MBEDTLS_RSA_PUBLIC,
|
||||
md_type, hash_len,
|
||||
hash, sig);
|
||||
#endif
|
||||
free(hash);
|
||||
|
||||
return (ret == 1) ? 0 : -1;
|
||||
@@ -519,11 +551,12 @@ _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session,
|
||||
int md_type;
|
||||
(void)hash_len;
|
||||
|
||||
sig_len = rsa->len;
|
||||
sig_len = mbedtls_rsa_get_len(rsa);
|
||||
sig = LIBSSH2_ALLOC(session, sig_len);
|
||||
if(!sig) {
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
if(hash_len == SHA_DIGEST_LENGTH) {
|
||||
md_type = MBEDTLS_MD_SHA1;
|
||||
}
|
||||
@@ -538,9 +571,19 @@ _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session,
|
||||
"Unsupported hash digest length");
|
||||
ret = -1;
|
||||
}
|
||||
ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
|
||||
md_type, hash_len,
|
||||
hash, sig);
|
||||
if(ret == 0) {
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
ret = mbedtls_rsa_pkcs1_sign(rsa,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg,
|
||||
md_type, hash_len,
|
||||
hash, sig);
|
||||
#else
|
||||
ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
|
||||
md_type, hash_len,
|
||||
hash, sig);
|
||||
#endif
|
||||
}
|
||||
if(ret) {
|
||||
LIBSSH2_FREE(session, sig);
|
||||
return -1;
|
||||
@@ -580,8 +623,8 @@ gen_publickey_from_rsa(LIBSSH2_SESSION *session,
|
||||
unsigned char *key;
|
||||
unsigned char *p;
|
||||
|
||||
e_bytes = mbedtls_mpi_size(&rsa->E);
|
||||
n_bytes = mbedtls_mpi_size(&rsa->N);
|
||||
e_bytes = mbedtls_mpi_size(&rsa->MBEDTLS_PRIVATE(E));
|
||||
n_bytes = mbedtls_mpi_size(&rsa->MBEDTLS_PRIVATE(N));
|
||||
|
||||
/* Key form is "ssh-rsa" + e + n. */
|
||||
len = 4 + 7 + 4 + e_bytes + 4 + n_bytes;
|
||||
@@ -601,11 +644,11 @@ gen_publickey_from_rsa(LIBSSH2_SESSION *session,
|
||||
|
||||
_libssh2_htonu32(p, e_bytes);
|
||||
p += 4;
|
||||
mbedtls_mpi_write_binary(&rsa->E, p, e_bytes);
|
||||
mbedtls_mpi_write_binary(&rsa->MBEDTLS_PRIVATE(E), p, e_bytes);
|
||||
|
||||
_libssh2_htonu32(p, n_bytes);
|
||||
p += 4;
|
||||
mbedtls_mpi_write_binary(&rsa->N, p, n_bytes);
|
||||
mbedtls_mpi_write_binary(&rsa->MBEDTLS_PRIVATE(N), p, n_bytes);
|
||||
|
||||
*keylen = (size_t)(p - key);
|
||||
return key;
|
||||
@@ -677,7 +720,13 @@ _libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
int ret;
|
||||
|
||||
mbedtls_pk_init(&pkey);
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg);
|
||||
#else
|
||||
ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase);
|
||||
#endif
|
||||
if(ret != 0) {
|
||||
mbedtls_strerror(ret, (char *)buf, sizeof(buf));
|
||||
mbedtls_pk_free(&pkey);
|
||||
@@ -721,10 +770,19 @@ _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
mbedtls_pk_init(&pkey);
|
||||
|
||||
pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0;
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
ret = mbedtls_pk_parse_key(&pkey,
|
||||
(unsigned char *)privatekeydata_nullterm,
|
||||
privatekeydata_len + 1,
|
||||
(const unsigned char *)passphrase, pwd_len,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg);
|
||||
#else
|
||||
ret = mbedtls_pk_parse_key(&pkey,
|
||||
(unsigned char *)privatekeydata_nullterm,
|
||||
privatekeydata_len + 1,
|
||||
(const unsigned char *)passphrase, pwd_len);
|
||||
#endif
|
||||
_libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len);
|
||||
|
||||
if(ret != 0) {
|
||||
@@ -840,13 +898,13 @@ _libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0)
|
||||
goto failed;
|
||||
|
||||
plen = 2 * mbedtls_mpi_size(&(*privkey)->grp.P) + 1;
|
||||
plen = 2 * mbedtls_mpi_size(&(*privkey)->MBEDTLS_PRIVATE(grp).P) + 1;
|
||||
*pubkey_oct = LIBSSH2_ALLOC(session, plen);
|
||||
|
||||
if(*pubkey_oct == NULL)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_point_write_binary(&(*privkey)->grp, &(*privkey)->Q,
|
||||
if(mbedtls_ecp_point_write_binary(&(*privkey)->MBEDTLS_PRIVATE(grp), &(*privkey)->MBEDTLS_PRIVATE(Q),
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
pubkey_oct_len, *pubkey_oct, plen) == 0)
|
||||
return 0;
|
||||
@@ -879,13 +937,13 @@ _libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx,
|
||||
|
||||
mbedtls_ecdsa_init(*ctx);
|
||||
|
||||
if(mbedtls_ecp_group_load(&(*ctx)->grp, (mbedtls_ecp_group_id)curve) != 0)
|
||||
if(mbedtls_ecp_group_load(&(*ctx)->MBEDTLS_PRIVATE(grp), (mbedtls_ecp_group_id)curve) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_point_read_binary(&(*ctx)->grp, &(*ctx)->Q, k, k_len) != 0)
|
||||
if(mbedtls_ecp_point_read_binary(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(Q), k, k_len) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_check_pubkey(&(*ctx)->grp, &(*ctx)->Q) == 0)
|
||||
if(mbedtls_ecp_check_pubkey(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(Q)) == 0)
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
@@ -916,21 +974,21 @@ _libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k,
|
||||
|
||||
mbedtls_ecp_point_init(&pubkey);
|
||||
|
||||
if(mbedtls_ecp_point_read_binary(&privkey->grp, &pubkey,
|
||||
if(mbedtls_ecp_point_read_binary(&privkey->MBEDTLS_PRIVATE(grp), &pubkey,
|
||||
server_pubkey, server_pubkey_len) != 0) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(mbedtls_ecdh_compute_shared(&privkey->grp, *k,
|
||||
&pubkey, &privkey->d,
|
||||
if(mbedtls_ecdh_compute_shared(&privkey->MBEDTLS_PRIVATE(grp), *k,
|
||||
&pubkey, &privkey->MBEDTLS_PRIVATE(d),
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(mbedtls_ecp_check_privkey(&privkey->grp, *k) != 0)
|
||||
if(mbedtls_ecp_check_privkey(&privkey->MBEDTLS_PRIVATE(grp), *k) != 0)
|
||||
rc = -1;
|
||||
|
||||
cleanup:
|
||||
@@ -940,16 +998,16 @@ cleanup:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type) \
|
||||
{ \
|
||||
unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH]; \
|
||||
\
|
||||
if(libssh2_sha##digest_type(m, m_len, hsh) == 0) { \
|
||||
rc = mbedtls_ecdsa_verify(&ctx->grp, hsh, \
|
||||
SHA##digest_type##_DIGEST_LENGTH, \
|
||||
&ctx->Q, &pr, &ps); \
|
||||
} \
|
||||
\
|
||||
#define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type) \
|
||||
{ \
|
||||
unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH]; \
|
||||
\
|
||||
if(libssh2_sha##digest_type(m, m_len, hsh) == 0) { \
|
||||
rc = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hsh, \
|
||||
SHA##digest_type##_DIGEST_LENGTH, \
|
||||
&ctx->MBEDTLS_PRIVATE(Q), &pr, &ps); \
|
||||
} \
|
||||
\
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_sign
|
||||
@@ -1010,8 +1068,16 @@ _libssh2_mbedtls_parse_eckey(libssh2_ecdsa_ctx **ctx,
|
||||
|
||||
pwd_len = pwd ? strlen((const char *) pwd) : 0;
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0)
|
||||
|
||||
goto failed;
|
||||
#else
|
||||
if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len) != 0)
|
||||
goto failed;
|
||||
#endif
|
||||
|
||||
if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_ECKEY)
|
||||
goto failed;
|
||||
@@ -1075,19 +1141,19 @@ _libssh2_mbedtls_parse_openssh_key(libssh2_ecdsa_ctx **ctx,
|
||||
|
||||
mbedtls_ecdsa_init(*ctx);
|
||||
|
||||
if(mbedtls_ecp_group_load(&(*ctx)->grp, (mbedtls_ecp_group_id)type) != 0)
|
||||
if(mbedtls_ecp_group_load(&(*ctx)->MBEDTLS_PRIVATE(grp), (mbedtls_ecp_group_id)type) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_mpi_read_binary(&(*ctx)->d, exponent, exponentlen) != 0)
|
||||
if(mbedtls_mpi_read_binary(&(*ctx)->MBEDTLS_PRIVATE(d), exponent, exponentlen) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_mul(&(*ctx)->grp, &(*ctx)->Q,
|
||||
&(*ctx)->d, &(*ctx)->grp.G,
|
||||
if(mbedtls_ecp_mul(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(Q),
|
||||
&(*ctx)->MBEDTLS_PRIVATE(d), &(*ctx)->MBEDTLS_PRIVATE(grp).G,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_check_privkey(&(*ctx)->grp, &(*ctx)->d) == 0)
|
||||
if(mbedtls_ecp_check_privkey(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(d)) == 0)
|
||||
goto cleanup;
|
||||
|
||||
failed:
|
||||
@@ -1231,7 +1297,7 @@ _libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session,
|
||||
mbedtls_mpi_init(&pr);
|
||||
mbedtls_mpi_init(&ps);
|
||||
|
||||
if(mbedtls_ecdsa_sign(&ctx->grp, &pr, &ps, &ctx->d,
|
||||
if(mbedtls_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &pr, &ps, &ctx->MBEDTLS_PRIVATE(d),
|
||||
hash, hash_len,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0)
|
||||
@@ -1278,7 +1344,7 @@ cleanup:
|
||||
libssh2_curve_type
|
||||
_libssh2_mbedtls_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ctx)
|
||||
{
|
||||
return (libssh2_curve_type) ctx->grp.id;
|
||||
return (libssh2_curve_type) ctx->MBEDTLS_PRIVATE(grp).id;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_curve_type_from_name
|
||||
|
||||
Reference in New Issue
Block a user