mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-12-15 18:32:26 +03:00
Fix mbedTLS issues caused by v3 API changes
Signed-off-by: Juraj Vijtiuk <vijtiuk.juraj@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Jakub Jelen
parent
9caedca2c6
commit
0c08159f53
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include <mbedtls/ecdh.h>
|
#include <mbedtls/ecdh.h>
|
||||||
#include <mbedtls/ecp.h>
|
#include <mbedtls/ecp.h>
|
||||||
|
#include "mbedcrypto-compat.h"
|
||||||
|
|
||||||
#ifdef HAVE_ECDH
|
#ifdef HAVE_ECDH
|
||||||
|
|
||||||
@@ -54,6 +55,10 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
mbedtls_ecp_group grp;
|
mbedtls_ecp_group grp;
|
||||||
int rc;
|
int rc;
|
||||||
mbedtls_ecp_group_id curve;
|
mbedtls_ecp_group_id curve;
|
||||||
|
mbedtls_ctr_drbg_context *ctr_drbg = NULL;
|
||||||
|
mbedtls_ecp_keypair *ecdh_privkey = NULL;
|
||||||
|
|
||||||
|
ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
||||||
|
|
||||||
curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
||||||
if (curve == MBEDTLS_ECP_DP_NONE) {
|
if (curve == MBEDTLS_ECP_DP_NONE) {
|
||||||
@@ -70,7 +75,9 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_ecp_keypair_init(session->next_crypto->ecdh_privkey);
|
ecdh_privkey = session->next_crypto->ecdh_privkey;
|
||||||
|
|
||||||
|
mbedtls_ecp_keypair_init(ecdh_privkey);
|
||||||
mbedtls_ecp_group_init(&grp);
|
mbedtls_ecp_group_init(&grp);
|
||||||
|
|
||||||
rc = mbedtls_ecp_group_load(&grp, curve);
|
rc = mbedtls_ecp_group_load(&grp, curve);
|
||||||
@@ -80,10 +87,10 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecp_gen_keypair(&grp,
|
rc = mbedtls_ecp_gen_keypair(&grp,
|
||||||
&session->next_crypto->ecdh_privkey->d,
|
&ecdh_privkey->MBEDTLS_PRIVATE(d),
|
||||||
&session->next_crypto->ecdh_privkey->Q,
|
&ecdh_privkey->MBEDTLS_PRIVATE(Q),
|
||||||
mbedtls_ctr_drbg_random,
|
mbedtls_ctr_drbg_random,
|
||||||
ssh_get_mbedtls_ctr_drbg_context());
|
ctr_drbg);
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
rc = SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
@@ -91,7 +98,7 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
client_pubkey = make_ecpoint_string(&grp,
|
client_pubkey = make_ecpoint_string(&grp,
|
||||||
&session->next_crypto->ecdh_privkey->Q);
|
&ecdh_privkey->MBEDTLS_PRIVATE(Q));
|
||||||
if (client_pubkey == NULL) {
|
if (client_pubkey == NULL) {
|
||||||
rc = SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -124,6 +131,10 @@ int ecdh_build_k(ssh_session session)
|
|||||||
mbedtls_ecp_point pubkey;
|
mbedtls_ecp_point pubkey;
|
||||||
int rc;
|
int rc;
|
||||||
mbedtls_ecp_group_id curve;
|
mbedtls_ecp_group_id curve;
|
||||||
|
mbedtls_ctr_drbg_context *ctr_drbg = NULL;
|
||||||
|
mbedtls_ecp_keypair *ecdh_privkey = NULL;
|
||||||
|
|
||||||
|
ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
||||||
|
|
||||||
curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
||||||
if (curve == MBEDTLS_ECP_DP_NONE) {
|
if (curve == MBEDTLS_ECP_DP_NONE) {
|
||||||
@@ -162,19 +173,20 @@ int ecdh_build_k(ssh_session session)
|
|||||||
|
|
||||||
mbedtls_mpi_init(session->next_crypto->shared_secret);
|
mbedtls_mpi_init(session->next_crypto->shared_secret);
|
||||||
|
|
||||||
|
ecdh_privkey = session->next_crypto->ecdh_privkey;
|
||||||
rc = mbedtls_ecdh_compute_shared(&grp,
|
rc = mbedtls_ecdh_compute_shared(&grp,
|
||||||
session->next_crypto->shared_secret,
|
session->next_crypto->shared_secret,
|
||||||
&pubkey,
|
&pubkey,
|
||||||
&session->next_crypto->ecdh_privkey->d,
|
&ecdh_privkey->MBEDTLS_PRIVATE(d),
|
||||||
mbedtls_ctr_drbg_random,
|
mbedtls_ctr_drbg_random,
|
||||||
ssh_get_mbedtls_ctr_drbg_context());
|
ctr_drbg);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
rc = SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mbedtls_ecp_keypair_free(session->next_crypto->ecdh_privkey);
|
mbedtls_ecp_keypair_free(ecdh_privkey);
|
||||||
SAFE_FREE(session->next_crypto->ecdh_privkey);
|
SAFE_FREE(session->next_crypto->ecdh_privkey);
|
||||||
mbedtls_ecp_group_free(&grp);
|
mbedtls_ecp_group_free(&grp);
|
||||||
mbedtls_ecp_point_free(&pubkey);
|
mbedtls_ecp_point_free(&pubkey);
|
||||||
@@ -187,6 +199,8 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
|||||||
ssh_string q_c_string = NULL;
|
ssh_string q_c_string = NULL;
|
||||||
ssh_string q_s_string = NULL;
|
ssh_string q_s_string = NULL;
|
||||||
mbedtls_ecp_group grp;
|
mbedtls_ecp_group grp;
|
||||||
|
mbedtls_ctr_drbg_context *ctr_drbg = NULL;
|
||||||
|
mbedtls_ecp_keypair *ecdh_privkey = NULL;
|
||||||
ssh_key privkey = NULL;
|
ssh_key privkey = NULL;
|
||||||
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||||
ssh_string sig_blob = NULL;
|
ssh_string sig_blob = NULL;
|
||||||
@@ -214,10 +228,14 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecdh_privkey = session->next_crypto->ecdh_privkey;
|
||||||
|
|
||||||
session->next_crypto->ecdh_client_pubkey = q_c_string;
|
session->next_crypto->ecdh_client_pubkey = q_c_string;
|
||||||
|
|
||||||
|
ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
||||||
|
|
||||||
mbedtls_ecp_group_init(&grp);
|
mbedtls_ecp_group_init(&grp);
|
||||||
mbedtls_ecp_keypair_init(session->next_crypto->ecdh_privkey);
|
mbedtls_ecp_keypair_init(ecdh_privkey);
|
||||||
|
|
||||||
rc = mbedtls_ecp_group_load(&grp, curve);
|
rc = mbedtls_ecp_group_load(&grp, curve);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
@@ -226,16 +244,16 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecp_gen_keypair(&grp,
|
rc = mbedtls_ecp_gen_keypair(&grp,
|
||||||
&session->next_crypto->ecdh_privkey->d,
|
&ecdh_privkey->MBEDTLS_PRIVATE(d),
|
||||||
&session->next_crypto->ecdh_privkey->Q,
|
&ecdh_privkey->MBEDTLS_PRIVATE(Q),
|
||||||
mbedtls_ctr_drbg_random,
|
mbedtls_ctr_drbg_random,
|
||||||
ssh_get_mbedtls_ctr_drbg_context());
|
ctr_drbg);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
rc = SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
q_s_string = make_ecpoint_string(&grp, &session->next_crypto->ecdh_privkey->Q);
|
q_s_string = make_ecpoint_string(&grp, &ecdh_privkey->MBEDTLS_PRIVATE(Q));
|
||||||
if (q_s_string == NULL) {
|
if (q_s_string == NULL) {
|
||||||
rc = SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/misc.h"
|
#include "libssh/misc.h"
|
||||||
|
#include "mbedcrypto-compat.h"
|
||||||
#if defined(MBEDTLS_CHACHA20_C) && defined(MBEDTLS_POLY1305_C)
|
#if defined(MBEDTLS_CHACHA20_C) && defined(MBEDTLS_POLY1305_C)
|
||||||
#include "libssh/bytearray.h"
|
#include "libssh/bytearray.h"
|
||||||
#include "libssh/chacha20-poly1305-common.h"
|
#include "libssh/chacha20-poly1305-common.h"
|
||||||
@@ -177,7 +178,7 @@ void evp_update(EVPCTX ctx, const void *data, size_t len)
|
|||||||
|
|
||||||
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
||||||
{
|
{
|
||||||
*mdlen = mbedtls_md_get_size(ctx->md_info);
|
*mdlen = mbedtls_md_get_size(ctx->MBEDTLS_PRIVATE(md_info));
|
||||||
mbedtls_md_finish(ctx, md);
|
mbedtls_md_finish(ctx, md);
|
||||||
mbedtls_md_free(ctx);
|
mbedtls_md_free(ctx);
|
||||||
SAFE_FREE(ctx);
|
SAFE_FREE(ctx);
|
||||||
@@ -453,7 +454,7 @@ void hmac_update(HMACCTX c, const void *data, size_t len)
|
|||||||
|
|
||||||
void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len)
|
void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len)
|
||||||
{
|
{
|
||||||
*len = mbedtls_md_get_size(c->md_info);
|
*len = mbedtls_md_get_size(c->MBEDTLS_PRIVATE(md_info));
|
||||||
mbedtls_md_hmac_finish(c, hashmacbuf);
|
mbedtls_md_hmac_finish(c, hashmacbuf);
|
||||||
mbedtls_md_free(c);
|
mbedtls_md_free(c);
|
||||||
SAFE_FREE(c);
|
SAFE_FREE(c);
|
||||||
@@ -467,6 +468,8 @@ cipher_init(struct ssh_cipher_struct *cipher,
|
|||||||
{
|
{
|
||||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||||
mbedtls_cipher_context_t *ctx;
|
mbedtls_cipher_context_t *ctx;
|
||||||
|
size_t key_bitlen = 0;
|
||||||
|
size_t iv_size = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (operation == MBEDTLS_ENCRYPT) {
|
if (operation == MBEDTLS_ENCRYPT) {
|
||||||
@@ -487,15 +490,15 @@ cipher_init(struct ssh_cipher_struct *cipher,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_cipher_setkey(ctx, key,
|
key_bitlen = mbedtls_cipher_info_get_key_bitlen(cipher_info);
|
||||||
cipher_info->key_bitlen,
|
rc = mbedtls_cipher_setkey(ctx, key, key_bitlen, operation);
|
||||||
operation);
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_cipher_set_iv(ctx, IV, cipher_info->iv_size);
|
iv_size = mbedtls_cipher_info_get_iv_size(cipher_info);
|
||||||
|
rc = mbedtls_cipher_set_iv(ctx, IV, iv_size);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -573,15 +576,16 @@ cipher_set_key_gcm(struct ssh_cipher_struct *cipher,
|
|||||||
void *IV)
|
void *IV)
|
||||||
{
|
{
|
||||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||||
|
size_t key_bitlen = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
mbedtls_gcm_init(&cipher->gcm_ctx);
|
mbedtls_gcm_init(&cipher->gcm_ctx);
|
||||||
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
||||||
|
|
||||||
rc = mbedtls_gcm_setkey(&cipher->gcm_ctx,
|
key_bitlen = mbedtls_cipher_info_get_key_bitlen(cipher_info);
|
||||||
MBEDTLS_CIPHER_ID_AES,
|
rc = mbedtls_gcm_setkey(&cipher->gcm_ctx, MBEDTLS_CIPHER_ID_AES,
|
||||||
key,
|
key, key_bitlen);
|
||||||
cipher_info->key_bitlen);
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_setkey failed");
|
SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_setkey failed");
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
39
src/mbedcrypto-compat.h
Normal file
39
src/mbedcrypto-compat.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef MBEDCRYPTO_COMPAT_H
|
||||||
|
#define MBEDCRYPTO_COMPAT_H
|
||||||
|
|
||||||
|
/* mbedtls/version.h should be available for both v2 and v3
|
||||||
|
* v3 defines the version inside build_info.h so if it isn't defined
|
||||||
|
* in version.h we should have v3
|
||||||
|
*/
|
||||||
|
#include <mbedtls/version.h>
|
||||||
|
#include <mbedtls/cipher.h>
|
||||||
|
#ifdef MBEDTLS_VERSION_MAJOR
|
||||||
|
#if MBEDTLS_VERSION_MAJOR < 3
|
||||||
|
|
||||||
|
static inline size_t mbedtls_cipher_info_get_key_bitlen(
|
||||||
|
const mbedtls_cipher_info_t *info)
|
||||||
|
{
|
||||||
|
if (info == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return info->key_bitlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t mbedtls_cipher_info_get_iv_size(
|
||||||
|
const mbedtls_cipher_info_t *info)
|
||||||
|
{
|
||||||
|
if (info == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (size_t)info->iv_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MBEDTLS_PRIVATE(X) X
|
||||||
|
#endif /* MBEDTLS_VERSION_MAJOR < 3 */
|
||||||
|
#else /* MBEDTLS_VERSION_MAJOR */
|
||||||
|
#include <mbedtls/build_info.h>
|
||||||
|
#if MBEDTLS_VERSION_MAJOR < 3
|
||||||
|
#define MBEDTLS_PRIVATE(X) X
|
||||||
|
#endif /* MBEDTLS_VERSION_MAJOR < 3 */
|
||||||
|
#endif /* MBEDTLS_VERSION_MAJOR */
|
||||||
|
#endif /* MBEDCRYPTO_COMPAT_H */
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
#ifdef HAVE_LIBMBEDCRYPTO
|
#ifdef HAVE_LIBMBEDCRYPTO
|
||||||
#include <mbedtls/pk.h>
|
#include <mbedtls/pk.h>
|
||||||
#include <mbedtls/error.h>
|
#include <mbedtls/error.h>
|
||||||
|
#include "mbedcrypto-compat.h"
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/pki.h"
|
#include "libssh/pki.h"
|
||||||
@@ -50,7 +51,7 @@ static int pki_key_ecdsa_to_nid(mbedtls_ecdsa_context *ecdsa)
|
|||||||
{
|
{
|
||||||
mbedtls_ecp_group_id id;
|
mbedtls_ecp_group_id id;
|
||||||
|
|
||||||
id = ecdsa->grp.id;
|
id = ecdsa->MBEDTLS_PRIVATE(grp.id);
|
||||||
if (id == MBEDTLS_ECP_DP_SECP256R1) {
|
if (id == MBEDTLS_ECP_DP_SECP256R1) {
|
||||||
return NID_mbedtls_nistp256;
|
return NID_mbedtls_nistp256;
|
||||||
} else if (id == MBEDTLS_ECP_DP_SECP384R1) {
|
} else if (id == MBEDTLS_ECP_DP_SECP384R1) {
|
||||||
@@ -92,6 +93,9 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
|||||||
/* mbedtls pk_parse_key expects strlen to count the 0 byte */
|
/* mbedtls pk_parse_key expects strlen to count the 0 byte */
|
||||||
size_t b64len = strlen(b64_key) + 1;
|
size_t b64len = strlen(b64_key) + 1;
|
||||||
unsigned char tmp[MAX_PASSPHRASE_SIZE] = {0};
|
unsigned char tmp[MAX_PASSPHRASE_SIZE] = {0};
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_ctr_drbg_context *ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
||||||
|
#endif
|
||||||
|
|
||||||
type = pki_privatekey_type_from_string(b64_key);
|
type = pki_privatekey_type_from_string(b64_key);
|
||||||
if (type == SSH_KEYTYPE_UNKNOWN) {
|
if (type == SSH_KEYTYPE_UNKNOWN) {
|
||||||
@@ -116,21 +120,44 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
/* TODO fix signedness and strlen */
|
/* TODO fix signedness and strlen */
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
valid = mbedtls_pk_parse_key(rsa,
|
||||||
|
(const unsigned char *) b64_key,
|
||||||
|
b64len, tmp,
|
||||||
|
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE),
|
||||||
|
mbedtls_ctr_drbg_random, ctr_drbg);
|
||||||
|
#else
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
valid = mbedtls_pk_parse_key(rsa,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *) b64_key,
|
||||||
b64len, tmp,
|
b64len, tmp,
|
||||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
|
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
valid = mbedtls_pk_parse_key(rsa,
|
||||||
|
(const unsigned char *) b64_key,
|
||||||
|
b64len, NULL,
|
||||||
|
0, mbedtls_ctr_drbg_random, ctr_drbg);
|
||||||
|
#else
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
valid = mbedtls_pk_parse_key(rsa,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *) b64_key,
|
||||||
b64len, NULL,
|
b64len, NULL,
|
||||||
0);
|
0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
valid = mbedtls_pk_parse_key(rsa,
|
||||||
|
(const unsigned char *) b64_key, b64len,
|
||||||
|
(const unsigned char *) passphrase,
|
||||||
|
strnlen(passphrase, MAX_PASSPHRASE_SIZE),
|
||||||
|
mbedtls_ctr_drbg_random, ctr_drbg);
|
||||||
|
#else
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
valid = mbedtls_pk_parse_key(rsa,
|
||||||
(const unsigned char *) b64_key, b64len,
|
(const unsigned char *) b64_key, b64len,
|
||||||
(const unsigned char *) passphrase,
|
(const unsigned char *) passphrase,
|
||||||
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid != 0) {
|
if (valid != 0) {
|
||||||
@@ -143,7 +170,11 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
|||||||
case SSH_KEYTYPE_ECDSA_P256:
|
case SSH_KEYTYPE_ECDSA_P256:
|
||||||
case SSH_KEYTYPE_ECDSA_P384:
|
case SSH_KEYTYPE_ECDSA_P384:
|
||||||
case SSH_KEYTYPE_ECDSA_P521:
|
case SSH_KEYTYPE_ECDSA_P521:
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
ecdsa = malloc(sizeof(mbedtls_ecdsa_context));
|
||||||
|
#else
|
||||||
ecdsa = malloc(sizeof(mbedtls_pk_context));
|
ecdsa = malloc(sizeof(mbedtls_pk_context));
|
||||||
|
#endif
|
||||||
if (ecdsa == NULL) {
|
if (ecdsa == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -157,21 +188,44 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
|||||||
if (valid < 0) {
|
if (valid < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
valid = mbedtls_pk_parse_key(ecdsa,
|
||||||
|
(const unsigned char *) b64_key,
|
||||||
|
b64len, tmp,
|
||||||
|
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE),
|
||||||
|
mbedtls_ctr_drbg_random, ctr_drbg);
|
||||||
|
#else
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
valid = mbedtls_pk_parse_key(ecdsa,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *) b64_key,
|
||||||
b64len, tmp,
|
b64len, tmp,
|
||||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
|
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
valid = mbedtls_pk_parse_key(ecdsa,
|
||||||
|
(const unsigned char *) b64_key,
|
||||||
|
b64len, NULL,
|
||||||
|
0, mbedtls_ctr_drbg_random, ctr_drbg);
|
||||||
|
#else
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
valid = mbedtls_pk_parse_key(ecdsa,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *) b64_key,
|
||||||
b64len, NULL,
|
b64len, NULL,
|
||||||
0);
|
0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
valid = mbedtls_pk_parse_key(ecdsa,
|
||||||
|
(const unsigned char *) b64_key, b64len,
|
||||||
|
(const unsigned char *) passphrase,
|
||||||
|
strnlen(passphrase, MAX_PASSPHRASE_SIZE),
|
||||||
|
mbedtls_ctr_drbg_random, ctr_drbg);
|
||||||
|
#else
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
valid = mbedtls_pk_parse_key(ecdsa,
|
||||||
(const unsigned char *) b64_key, b64len,
|
(const unsigned char *) b64_key, b64len,
|
||||||
(const unsigned char *) passphrase,
|
(const unsigned char *) passphrase,
|
||||||
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid != 0) {
|
if (valid != 0) {
|
||||||
@@ -304,6 +358,10 @@ int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n)
|
|||||||
{
|
{
|
||||||
mbedtls_rsa_context *rsa = NULL;
|
mbedtls_rsa_context *rsa = NULL;
|
||||||
const mbedtls_pk_info_t *pk_info = NULL;
|
const mbedtls_pk_info_t *pk_info = NULL;
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi N;
|
||||||
|
mbedtls_mpi E;
|
||||||
|
#endif
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
key->rsa = malloc(sizeof(mbedtls_pk_context));
|
key->rsa = malloc(sizeof(mbedtls_pk_context));
|
||||||
@@ -320,26 +378,59 @@ int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_init(&N);
|
||||||
|
mbedtls_mpi_init(&E);
|
||||||
|
#endif
|
||||||
|
|
||||||
rsa = mbedtls_pk_rsa(*key->rsa);
|
rsa = mbedtls_pk_rsa(*key->rsa);
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_read_binary(&N, ssh_string_data(n),
|
||||||
|
ssh_string_len(n));
|
||||||
|
#else
|
||||||
rc = mbedtls_mpi_read_binary(&rsa->N, ssh_string_data(n),
|
rc = mbedtls_mpi_read_binary(&rsa->N, ssh_string_data(n),
|
||||||
ssh_string_len(n));
|
ssh_string_len(n));
|
||||||
|
#endif
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_read_binary(&E, ssh_string_data(e),
|
||||||
|
ssh_string_len(e));
|
||||||
|
#else
|
||||||
rc = mbedtls_mpi_read_binary(&rsa->E, ssh_string_data(e),
|
rc = mbedtls_mpi_read_binary(&rsa->E, ssh_string_data(e),
|
||||||
ssh_string_len(e));
|
ssh_string_len(e));
|
||||||
|
#endif
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_rsa_import(rsa, &N, NULL, NULL, NULL, &E);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_rsa_complete(rsa);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
rsa->len = (mbedtls_mpi_bitlen(&rsa->N) + 7) >> 3;
|
rsa->len = (mbedtls_mpi_bitlen(&rsa->N) + 7) >> 3;
|
||||||
|
#endif
|
||||||
return SSH_OK;
|
rc = SSH_OK;
|
||||||
|
goto exit;
|
||||||
fail:
|
fail:
|
||||||
|
rc = SSH_ERROR;
|
||||||
mbedtls_pk_free(key->rsa);
|
mbedtls_pk_free(key->rsa);
|
||||||
SAFE_FREE(key->rsa);
|
SAFE_FREE(key->rsa);
|
||||||
return SSH_ERROR;
|
exit:
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_free(&N);
|
||||||
|
mbedtls_mpi_free(&E);
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_key pki_key_dup(const ssh_key key, int demote)
|
ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||||
@@ -347,7 +438,13 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
ssh_key new = NULL;
|
ssh_key new = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
const mbedtls_pk_info_t *pk_info = NULL;
|
const mbedtls_pk_info_t *pk_info = NULL;
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi N;
|
||||||
|
mbedtls_mpi E;
|
||||||
|
mbedtls_mpi D;
|
||||||
|
mbedtls_mpi P;
|
||||||
|
mbedtls_mpi Q;
|
||||||
|
#endif
|
||||||
|
|
||||||
new = ssh_key_new();
|
new = ssh_key_new();
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@@ -362,6 +459,13 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
new->flags = key->flags;
|
new->flags = key->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_init(&N);
|
||||||
|
mbedtls_mpi_init(&E);
|
||||||
|
mbedtls_mpi_init(&D);
|
||||||
|
mbedtls_mpi_init(&P);
|
||||||
|
mbedtls_mpi_init(&Q);
|
||||||
|
#endif
|
||||||
|
|
||||||
switch(key->type) {
|
switch(key->type) {
|
||||||
case SSH_KEYTYPE_RSA: {
|
case SSH_KEYTYPE_RSA: {
|
||||||
@@ -376,11 +480,26 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
|
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
|
||||||
mbedtls_pk_setup(new->rsa, pk_info);
|
mbedtls_pk_setup(new->rsa, pk_info);
|
||||||
|
|
||||||
if (mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA) &&
|
if (!mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA) ||
|
||||||
mbedtls_pk_can_do(new->rsa, MBEDTLS_PK_RSA)) {
|
!mbedtls_pk_can_do(new->rsa, MBEDTLS_PK_RSA))
|
||||||
rsa = mbedtls_pk_rsa(*key->rsa);
|
{
|
||||||
new_rsa = mbedtls_pk_rsa(*new->rsa);
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsa = mbedtls_pk_rsa(*key->rsa);
|
||||||
|
new_rsa = mbedtls_pk_rsa(*new->rsa);
|
||||||
|
|
||||||
|
if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_rsa_export(rsa, &N, &P, &Q, &D, &E);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
rc = mbedtls_rsa_import(new_rsa, &N, &P, &Q, &D, &E);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#else
|
||||||
rc = mbedtls_mpi_copy(&new_rsa->N, &rsa->N);
|
rc = mbedtls_mpi_copy(&new_rsa->N, &rsa->N);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -390,42 +509,70 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_rsa->len = (mbedtls_mpi_bitlen(&new_rsa->N) + 7) >> 3;
|
new_rsa->len = (mbedtls_mpi_bitlen(&new_rsa->N) + 7) >> 3;
|
||||||
|
|
||||||
if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
|
rc = mbedtls_mpi_copy(&new_rsa->D, &rsa->D);
|
||||||
rc = mbedtls_mpi_copy(&new_rsa->D, &rsa->D);
|
if (rc != 0) {
|
||||||
if (rc != 0) {
|
goto fail;
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_mpi_copy(&new_rsa->P, &rsa->P);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_mpi_copy(&new_rsa->Q, &rsa->Q);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_mpi_copy(&new_rsa->DP, &rsa->DP);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_mpi_copy(&new_rsa->DQ, &rsa->DQ);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_mpi_copy(&new_rsa->QP, &rsa->QP);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_mpi_copy(&new_rsa->P, &rsa->P);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_mpi_copy(&new_rsa->Q, &rsa->Q);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_mpi_copy(&new_rsa->DP, &rsa->DP);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_mpi_copy(&new_rsa->DQ, &rsa->DQ);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_mpi_copy(&new_rsa->QP, &rsa->QP);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_rsa_export(rsa, &N, NULL, NULL, NULL, &E);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
rc = mbedtls_rsa_import(new_rsa, &N, NULL, NULL, NULL, &E);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rc = mbedtls_mpi_copy(&new_rsa->N, &rsa->N);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_mpi_copy(&new_rsa->E, &rsa->E);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_rsa->len = (mbedtls_mpi_bitlen(&new_rsa->N) + 7) >> 3;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_rsa_complete(new_rsa);
|
||||||
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -443,12 +590,14 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
mbedtls_ecdsa_init(new->ecdsa);
|
mbedtls_ecdsa_init(new->ecdsa);
|
||||||
|
|
||||||
if (demote && ssh_key_is_private(key)) {
|
if (demote && ssh_key_is_private(key)) {
|
||||||
rc = mbedtls_ecp_copy(&new->ecdsa->Q, &key->ecdsa->Q);
|
rc = mbedtls_ecp_copy(&new->ecdsa->MBEDTLS_PRIVATE(Q),
|
||||||
|
&key->ecdsa->MBEDTLS_PRIVATE(Q));
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecp_group_copy(&new->ecdsa->grp, &key->ecdsa->grp);
|
rc = mbedtls_ecp_group_copy(&new->ecdsa->MBEDTLS_PRIVATE(grp),
|
||||||
|
&key->ecdsa->MBEDTLS_PRIVATE(grp));
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -467,10 +616,19 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new;
|
goto cleanup;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
ssh_key_free(new);
|
SSH_KEY_FREE(new);
|
||||||
return NULL;
|
cleanup:
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_free(&N);
|
||||||
|
mbedtls_mpi_free(&E);
|
||||||
|
mbedtls_mpi_free(&D);
|
||||||
|
mbedtls_mpi_free(&P);
|
||||||
|
mbedtls_mpi_free(&Q);
|
||||||
|
#endif
|
||||||
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pki_key_generate_rsa(ssh_key key, int parameter)
|
int pki_key_generate_rsa(ssh_key key, int parameter)
|
||||||
@@ -508,36 +666,140 @@ int pki_key_generate_rsa(ssh_key key, int parameter)
|
|||||||
|
|
||||||
int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)
|
int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi N1;
|
||||||
|
mbedtls_mpi N2;
|
||||||
|
mbedtls_mpi P1;
|
||||||
|
mbedtls_mpi P2;
|
||||||
|
mbedtls_mpi Q1;
|
||||||
|
mbedtls_mpi Q2;
|
||||||
|
mbedtls_mpi E1;
|
||||||
|
mbedtls_mpi E2;
|
||||||
|
|
||||||
|
mbedtls_mpi_init(&N1);
|
||||||
|
mbedtls_mpi_init(&N2);
|
||||||
|
mbedtls_mpi_init(&P1);
|
||||||
|
mbedtls_mpi_init(&P2);
|
||||||
|
mbedtls_mpi_init(&Q1);
|
||||||
|
mbedtls_mpi_init(&Q2);
|
||||||
|
mbedtls_mpi_init(&E1);
|
||||||
|
mbedtls_mpi_init(&E2);
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (k1->type) {
|
switch (k1->type) {
|
||||||
case SSH_KEYTYPE_RSA: {
|
case SSH_KEYTYPE_RSA: {
|
||||||
mbedtls_rsa_context *rsa1, *rsa2;
|
mbedtls_rsa_context *rsa1, *rsa2;
|
||||||
if (mbedtls_pk_can_do(k1->rsa, MBEDTLS_PK_RSA) &&
|
if (!mbedtls_pk_can_do(k1->rsa, MBEDTLS_PK_RSA) ||
|
||||||
mbedtls_pk_can_do(k2->rsa, MBEDTLS_PK_RSA)) {
|
!mbedtls_pk_can_do(k2->rsa, MBEDTLS_PK_RSA))
|
||||||
if (mbedtls_pk_get_type(k1->rsa) != mbedtls_pk_get_type(k2->rsa) ||
|
{
|
||||||
mbedtls_pk_get_bitlen(k1->rsa) !=
|
break;
|
||||||
mbedtls_pk_get_bitlen(k2->rsa)) {
|
}
|
||||||
return 1;
|
|
||||||
|
if (mbedtls_pk_get_type(k1->rsa) != mbedtls_pk_get_type(k2->rsa) ||
|
||||||
|
mbedtls_pk_get_bitlen(k1->rsa) !=
|
||||||
|
mbedtls_pk_get_bitlen(k2->rsa))
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (what == SSH_KEY_CMP_PUBLIC) {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rsa1 = mbedtls_pk_rsa(*k1->rsa);
|
||||||
|
rc = mbedtls_rsa_export(rsa1, &N1, NULL, NULL, NULL, &E1);
|
||||||
|
if (rc != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rsa2 = mbedtls_pk_rsa(*k2->rsa);
|
||||||
|
rc = mbedtls_rsa_export(rsa2, &N2, NULL, NULL, NULL, &E2);
|
||||||
|
if (rc != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&N1, &N2) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&E1, &E2) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
#else
|
||||||
rsa1 = mbedtls_pk_rsa(*k1->rsa);
|
rsa1 = mbedtls_pk_rsa(*k1->rsa);
|
||||||
rsa2 = mbedtls_pk_rsa(*k2->rsa);
|
rsa2 = mbedtls_pk_rsa(*k2->rsa);
|
||||||
if (mbedtls_mpi_cmp_mpi(&rsa1->N, &rsa2->N) != 0) {
|
if (mbedtls_mpi_cmp_mpi(&rsa1->N, &rsa2->N) != 0) {
|
||||||
return 1;
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mbedtls_mpi_cmp_mpi(&rsa1->E, &rsa2->E) != 0) {
|
if (mbedtls_mpi_cmp_mpi(&rsa1->E, &rsa2->E) != 0) {
|
||||||
return 1;
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (what == SSH_KEY_CMP_PRIVATE) {
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rsa1 = mbedtls_pk_rsa(*k1->rsa);
|
||||||
|
rc = mbedtls_rsa_export(rsa1, &N1, &P1, &Q1, NULL, &E1);
|
||||||
|
if (rc != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (what == SSH_KEY_CMP_PRIVATE) {
|
rsa2 = mbedtls_pk_rsa(*k2->rsa);
|
||||||
if (mbedtls_mpi_cmp_mpi(&rsa1->P, &rsa2->P) != 0) {
|
rc = mbedtls_rsa_export(rsa2, &N2, &P2, &Q2, NULL, &E2);
|
||||||
return 1;
|
if (rc != 0) {
|
||||||
}
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
if (mbedtls_mpi_cmp_mpi(&rsa1->Q, &rsa2->Q) != 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&N1, &N2) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&E1, &E2) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&P1, &P2) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&Q1, &Q2) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rsa1 = mbedtls_pk_rsa(*k1->rsa);
|
||||||
|
rsa2 = mbedtls_pk_rsa(*k2->rsa);
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&rsa1->N, &rsa2->N) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&rsa1->E, &rsa2->E) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&rsa1->P, &rsa2->P) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_mpi_cmp_mpi(&rsa1->Q, &rsa2->Q) != 0) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -548,25 +810,39 @@ int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)
|
|||||||
mbedtls_ecp_keypair *ecdsa1 = k1->ecdsa;
|
mbedtls_ecp_keypair *ecdsa1 = k1->ecdsa;
|
||||||
mbedtls_ecp_keypair *ecdsa2 = k2->ecdsa;
|
mbedtls_ecp_keypair *ecdsa2 = k2->ecdsa;
|
||||||
|
|
||||||
if (ecdsa1->grp.id != ecdsa2->grp.id) {
|
if (ecdsa1->MBEDTLS_PRIVATE(grp).id !=
|
||||||
return 1;
|
ecdsa2->MBEDTLS_PRIVATE(grp).id) {
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mbedtls_mpi_cmp_mpi(&ecdsa1->Q.X, &ecdsa2->Q.X)) {
|
if (mbedtls_mpi_cmp_mpi(&ecdsa1->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X),
|
||||||
return 1;
|
&ecdsa2->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)))
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mbedtls_mpi_cmp_mpi(&ecdsa1->Q.Y, &ecdsa2->Q.Y)) {
|
if (mbedtls_mpi_cmp_mpi(&ecdsa1->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y),
|
||||||
return 1;
|
&ecdsa2->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)))
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mbedtls_mpi_cmp_mpi(&ecdsa1->Q.Z, &ecdsa2->Q.Z)) {
|
if (mbedtls_mpi_cmp_mpi(&ecdsa1->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z),
|
||||||
return 1;
|
&ecdsa2->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z)))
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (what == SSH_KEY_CMP_PRIVATE) {
|
if (what == SSH_KEY_CMP_PRIVATE) {
|
||||||
if (mbedtls_mpi_cmp_mpi(&ecdsa1->d, &ecdsa2->d)) {
|
if (mbedtls_mpi_cmp_mpi(&ecdsa1->MBEDTLS_PRIVATE(d),
|
||||||
return 1;
|
&ecdsa2->MBEDTLS_PRIVATE(d)))
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,12 +851,25 @@ int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)
|
|||||||
case SSH_KEYTYPE_ED25519:
|
case SSH_KEYTYPE_ED25519:
|
||||||
case SSH_KEYTYPE_SK_ED25519:
|
case SSH_KEYTYPE_SK_ED25519:
|
||||||
/* ed25519 keys handled globally */
|
/* ed25519 keys handled globally */
|
||||||
return 0;
|
rc = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return 1;
|
rc = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
cleanup:
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_free(&N1);
|
||||||
|
mbedtls_mpi_free(&N2);
|
||||||
|
mbedtls_mpi_free(&P1);
|
||||||
|
mbedtls_mpi_free(&P2);
|
||||||
|
mbedtls_mpi_free(&Q1);
|
||||||
|
mbedtls_mpi_free(&Q2);
|
||||||
|
mbedtls_mpi_free(&E1);
|
||||||
|
mbedtls_mpi_free(&E2);
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
|
ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
|
||||||
@@ -645,8 +934,17 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
|||||||
ssh_string e = NULL;
|
ssh_string e = NULL;
|
||||||
ssh_string n = NULL;
|
ssh_string n = NULL;
|
||||||
ssh_string str = NULL;
|
ssh_string str = NULL;
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi E;
|
||||||
|
mbedtls_mpi N;
|
||||||
|
#endif
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_init(&E);
|
||||||
|
mbedtls_mpi_init(&N);
|
||||||
|
#endif
|
||||||
|
|
||||||
buffer = ssh_buffer_new();
|
buffer = ssh_buffer_new();
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -685,6 +983,22 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
|||||||
|
|
||||||
rsa = mbedtls_pk_rsa(*key->rsa);
|
rsa = mbedtls_pk_rsa(*key->rsa);
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_rsa_export(rsa, &N, NULL, NULL, NULL, &E);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = ssh_make_bignum_string(&E);
|
||||||
|
if (e == NULL) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = ssh_make_bignum_string(&N);
|
||||||
|
if (n == NULL) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#else
|
||||||
e = ssh_make_bignum_string(&rsa->E);
|
e = ssh_make_bignum_string(&rsa->E);
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -694,6 +1008,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
|||||||
if (n == NULL) {
|
if (n == NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ssh_buffer_add_ssh_string(buffer, e) < 0) {
|
if (ssh_buffer_add_ssh_string(buffer, e) < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -730,7 +1045,8 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = make_ecpoint_string(&key->ecdsa->grp, &key->ecdsa->Q);
|
e = make_ecpoint_string(&key->ecdsa->MBEDTLS_PRIVATE(grp),
|
||||||
|
&key->ecdsa->MBEDTLS_PRIVATE(Q));
|
||||||
|
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
SSH_BUFFER_FREE(buffer);
|
SSH_BUFFER_FREE(buffer);
|
||||||
@@ -779,6 +1095,10 @@ makestring:
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSH_BUFFER_FREE(buffer);
|
SSH_BUFFER_FREE(buffer);
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_free(&N);
|
||||||
|
mbedtls_mpi_free(&E);
|
||||||
|
#endif
|
||||||
return str;
|
return str;
|
||||||
fail:
|
fail:
|
||||||
SSH_BUFFER_FREE(buffer);
|
SSH_BUFFER_FREE(buffer);
|
||||||
@@ -788,6 +1108,10 @@ fail:
|
|||||||
SSH_STRING_FREE(e);
|
SSH_STRING_FREE(e);
|
||||||
ssh_string_burn(n);
|
ssh_string_burn(n);
|
||||||
SSH_STRING_FREE(n);
|
SSH_STRING_FREE(n);
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
mbedtls_mpi_free(&N);
|
||||||
|
mbedtls_mpi_free(&E);
|
||||||
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1051,6 +1375,7 @@ static ssh_string rsa_do_sign_hash(const unsigned char *digest,
|
|||||||
mbedtls_md_type_t md = 0;
|
mbedtls_md_type_t md = 0;
|
||||||
unsigned char *sig = NULL;
|
unsigned char *sig = NULL;
|
||||||
size_t slen;
|
size_t slen;
|
||||||
|
size_t sig_size;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
switch (hash_type) {
|
switch (hash_type) {
|
||||||
@@ -1069,7 +1394,8 @@ static ssh_string rsa_do_sign_hash(const unsigned char *digest,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sig = malloc(mbedtls_pk_get_bitlen(privkey) / 8);
|
sig_size = mbedtls_pk_get_bitlen(privkey) / 8;
|
||||||
|
sig = malloc(sig_size);
|
||||||
if (sig == NULL) {
|
if (sig == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1079,6 +1405,9 @@ static ssh_string rsa_do_sign_hash(const unsigned char *digest,
|
|||||||
digest,
|
digest,
|
||||||
dlen,
|
dlen,
|
||||||
sig,
|
sig,
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
sig_size,
|
||||||
|
#endif
|
||||||
&slen,
|
&slen,
|
||||||
mbedtls_ctr_drbg_random,
|
mbedtls_ctr_drbg_random,
|
||||||
ssh_get_mbedtls_ctr_drbg_context());
|
ssh_get_mbedtls_ctr_drbg_context());
|
||||||
@@ -1145,10 +1474,10 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecdsa_sign(&privkey->ecdsa->grp,
|
rc = mbedtls_ecdsa_sign(&privkey->ecdsa->MBEDTLS_PRIVATE(grp),
|
||||||
sig->ecdsa_sig.r,
|
sig->ecdsa_sig.r,
|
||||||
sig->ecdsa_sig.s,
|
sig->ecdsa_sig.s,
|
||||||
&privkey->ecdsa->d,
|
&privkey->ecdsa->MBEDTLS_PRIVATE(d),
|
||||||
hash,
|
hash,
|
||||||
hlen,
|
hlen,
|
||||||
mbedtls_ctr_drbg_random,
|
mbedtls_ctr_drbg_random,
|
||||||
@@ -1351,8 +1680,9 @@ int pki_verify_data_signature(ssh_signature signature,
|
|||||||
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
||||||
case SSH_KEYTYPE_SK_ECDSA:
|
case SSH_KEYTYPE_SK_ECDSA:
|
||||||
case SSH_KEYTYPE_SK_ECDSA_CERT01:
|
case SSH_KEYTYPE_SK_ECDSA_CERT01:
|
||||||
rc = mbedtls_ecdsa_verify(&pubkey->ecdsa->grp, hash, hlen,
|
rc = mbedtls_ecdsa_verify(&pubkey->ecdsa->MBEDTLS_PRIVATE(grp), hash,
|
||||||
&pubkey->ecdsa->Q, signature->ecdsa_sig.r,
|
hlen, &pubkey->ecdsa->MBEDTLS_PRIVATE(Q),
|
||||||
|
signature->ecdsa_sig.r,
|
||||||
signature->ecdsa_sig.s);
|
signature->ecdsa_sig.s);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
char error_buf[100];
|
char error_buf[100];
|
||||||
@@ -1455,18 +1785,19 @@ int pki_privkey_build_ecdsa(ssh_key key, int nid, ssh_string e, ssh_string exp)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecp_copy(&keypair.Q, &Q);
|
rc = mbedtls_ecp_copy(&keypair.MBEDTLS_PRIVATE(Q), &Q);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecp_group_copy(&keypair.grp, &group);
|
rc = mbedtls_ecp_group_copy(&keypair.MBEDTLS_PRIVATE(grp), &group);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_mpi_read_binary(&keypair.d, ssh_string_data(exp),
|
rc = mbedtls_mpi_read_binary(&keypair.MBEDTLS_PRIVATE(d),
|
||||||
ssh_string_len(exp));
|
ssh_string_data(exp),
|
||||||
|
ssh_string_len(exp));
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -1522,17 +1853,17 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecp_copy(&keypair.Q, &Q);
|
rc = mbedtls_ecp_copy(&keypair.MBEDTLS_PRIVATE(Q), &Q);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mbedtls_ecp_group_copy(&keypair.grp, &group);
|
rc = mbedtls_ecp_group_copy(&keypair.MBEDTLS_PRIVATE(grp), &group);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_mpi_init(&keypair.d);
|
mbedtls_mpi_init(&keypair.MBEDTLS_PRIVATE(d));
|
||||||
|
|
||||||
rc = mbedtls_ecdsa_from_keypair(key->ecdsa, &keypair);
|
rc = mbedtls_ecdsa_from_keypair(key->ecdsa, &keypair);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user