mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-27 13:21:11 +03:00
pki: allow certificates to be used in signature verification
A number of places checked that the signature type matched the key type. We losen these checks to, for example, allow an RSA signature with an RSA-cert key. Signed-off-by: Ben Toews <mastahyeti@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
committed by
Andreas Schneider
parent
7c0719e53d
commit
2f26b5d63c
@@ -100,6 +100,7 @@ const char *
|
|||||||
ssh_key_get_signature_algorithm(ssh_session session,
|
ssh_key_get_signature_algorithm(ssh_session session,
|
||||||
enum ssh_keytypes_e type);
|
enum ssh_keytypes_e type);
|
||||||
enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
|
enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
|
||||||
|
enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type);
|
||||||
|
|
||||||
#define is_ecdsa_key_type(t) \
|
#define is_ecdsa_key_type(t) \
|
||||||
((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521)
|
((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521)
|
||||||
|
|||||||
35
src/pki.c
35
src/pki.c
@@ -443,6 +443,32 @@ enum ssh_keytypes_e ssh_key_type_from_name(const char *name) {
|
|||||||
return SSH_KEYTYPE_UNKNOWN;
|
return SSH_KEYTYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the pubic key type corresponding to a certificate type.
|
||||||
|
*
|
||||||
|
* @param[in] type The certificate or public key type.
|
||||||
|
*
|
||||||
|
* @return The matching public key type.
|
||||||
|
*/
|
||||||
|
enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type) {
|
||||||
|
switch (type) {
|
||||||
|
case SSH_KEYTYPE_DSS_CERT01:
|
||||||
|
return SSH_KEYTYPE_DSS;
|
||||||
|
case SSH_KEYTYPE_RSA_CERT01:
|
||||||
|
return SSH_KEYTYPE_RSA;
|
||||||
|
case SSH_KEYTYPE_ECDSA_P256_CERT01:
|
||||||
|
return SSH_KEYTYPE_ECDSA_P256;
|
||||||
|
case SSH_KEYTYPE_ECDSA_P384_CERT01:
|
||||||
|
return SSH_KEYTYPE_ECDSA_P384;
|
||||||
|
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
||||||
|
return SSH_KEYTYPE_ECDSA_P521;
|
||||||
|
case SSH_KEYTYPE_ED25519_CERT01:
|
||||||
|
return SSH_KEYTYPE_ED25519;
|
||||||
|
default:
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if the key has/is a public key.
|
* @brief Check if the key has/is a public key.
|
||||||
*
|
*
|
||||||
@@ -2025,19 +2051,20 @@ int ssh_pki_signature_verify(ssh_session session,
|
|||||||
size_t dlen)
|
size_t dlen)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
enum ssh_keytypes_e key_type = ssh_key_type_plain(key->type);
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_FUNCTIONS,
|
SSH_LOG(SSH_LOG_FUNCTIONS,
|
||||||
"Going to verify a %s type signature",
|
"Going to verify a %s type signature",
|
||||||
sig->type_c);
|
sig->type_c);
|
||||||
|
|
||||||
if (key->type != sig->type) {
|
if (key_type != sig->type) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
"Can not verify %s signature with %s key",
|
"Can not verify %s signature with %s key",
|
||||||
sig->type_c, key->type_c);
|
sig->type_c, key->type_c);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_ecdsa_key_type(key->type)) {
|
if (is_ecdsa_key_type(key_type)) {
|
||||||
#if HAVE_ECC
|
#if HAVE_ECC
|
||||||
unsigned char ehash[EVP_DIGEST_LEN] = {0};
|
unsigned char ehash[EVP_DIGEST_LEN] = {0};
|
||||||
uint32_t elen;
|
uint32_t elen;
|
||||||
@@ -2055,7 +2082,7 @@ int ssh_pki_signature_verify(ssh_session session,
|
|||||||
ehash,
|
ehash,
|
||||||
elen);
|
elen);
|
||||||
#endif
|
#endif
|
||||||
} else if (key->type == SSH_KEYTYPE_ED25519) {
|
} else if (key_type == SSH_KEYTYPE_ED25519) {
|
||||||
rc = pki_signature_verify(session, sig, key, digest, dlen);
|
rc = pki_signature_verify(session, sig, key, digest, dlen);
|
||||||
} else {
|
} else {
|
||||||
unsigned char hash[SHA512_DIGEST_LEN] = {0};
|
unsigned char hash[SHA512_DIGEST_LEN] = {0};
|
||||||
@@ -2085,7 +2112,7 @@ int ssh_pki_signature_verify(ssh_session session,
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_print_hexa(key->type == SSH_KEYTYPE_DSS
|
ssh_print_hexa(key_type == SSH_KEYTYPE_DSS
|
||||||
? "Hash to be verified with DSA"
|
? "Hash to be verified with DSA"
|
||||||
: "Hash to be verified with RSA",
|
: "Hash to be verified with RSA",
|
||||||
hash,
|
hash,
|
||||||
|
|||||||
@@ -1625,7 +1625,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
|||||||
int rc;
|
int rc;
|
||||||
BIGNUM *pr = NULL, *ps = NULL;
|
BIGNUM *pr = NULL, *ps = NULL;
|
||||||
|
|
||||||
if (type != pubkey->type) {
|
if (ssh_key_type_plain(pubkey->type) != type) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
"Incompatible public key provided (%d) expecting (%d)",
|
"Incompatible public key provided (%d) expecting (%d)",
|
||||||
type,
|
type,
|
||||||
@@ -1833,7 +1833,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
int rc;
|
int rc;
|
||||||
int nid;
|
int nid;
|
||||||
|
|
||||||
if (key->type != sig->type) {
|
if (ssh_key_type_plain(key->type) != sig->type) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
"Can not verify %s signature with %s key",
|
"Can not verify %s signature with %s key",
|
||||||
sig->type_c,
|
sig->type_c,
|
||||||
@@ -1843,6 +1843,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
|
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
|
case SSH_KEYTYPE_DSS_CERT01:
|
||||||
rc = DSA_do_verify(hash,
|
rc = DSA_do_verify(hash,
|
||||||
hlen,
|
hlen,
|
||||||
sig->dsa_sig,
|
sig->dsa_sig,
|
||||||
@@ -1857,6 +1858,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_RSA:
|
case SSH_KEYTYPE_RSA:
|
||||||
case SSH_KEYTYPE_RSA1:
|
case SSH_KEYTYPE_RSA1:
|
||||||
|
case SSH_KEYTYPE_RSA_CERT01:
|
||||||
switch (sig->hash_type) {
|
switch (sig->hash_type) {
|
||||||
case SSH_DIGEST_AUTO:
|
case SSH_DIGEST_AUTO:
|
||||||
case SSH_DIGEST_SHA1:
|
case SSH_DIGEST_SHA1:
|
||||||
@@ -1892,6 +1894,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_ED25519:
|
case SSH_KEYTYPE_ED25519:
|
||||||
|
case SSH_KEYTYPE_ED25519_CERT01:
|
||||||
rc = pki_ed25519_verify(key, sig, hash, hlen);
|
rc = pki_ed25519_verify(key, sig, hash, hlen);
|
||||||
if (rc != SSH_OK){
|
if (rc != SSH_OK){
|
||||||
ssh_set_error(session,
|
ssh_set_error(session,
|
||||||
@@ -1903,6 +1906,9 @@ int pki_signature_verify(ssh_session session,
|
|||||||
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:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P256_CERT01:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P384_CERT01:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
||||||
#ifdef HAVE_OPENSSL_ECC
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
rc = ECDSA_do_verify(hash,
|
rc = ECDSA_do_verify(hash,
|
||||||
hlen,
|
hlen,
|
||||||
|
|||||||
@@ -1909,7 +1909,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
|||||||
size_t rsalen;
|
size_t rsalen;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (type != pubkey->type) {
|
if (ssh_key_type_plain(pubkey->type) != type) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
"Incompatible public key provided (%d) expecting (%d)",
|
"Incompatible public key provided (%d) expecting (%d)",
|
||||||
type,
|
type,
|
||||||
@@ -2096,7 +2096,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
gcry_sexp_t sexp;
|
gcry_sexp_t sexp;
|
||||||
gcry_error_t err;
|
gcry_error_t err;
|
||||||
|
|
||||||
if (key->type != sig->type) {
|
if (ssh_key_type_plain(key->type) != sig->type) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
"Can not verify %s signature with %s key",
|
"Can not verify %s signature with %s key",
|
||||||
sig->type_c,
|
sig->type_c,
|
||||||
@@ -2106,6 +2106,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
|
|
||||||
switch(key->type) {
|
switch(key->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
|
case SSH_KEYTYPE_DSS_CERT01:
|
||||||
/* That is to mark the number as positive */
|
/* That is to mark the number as positive */
|
||||||
if(hash[0] >= 0x80) {
|
if(hash[0] >= 0x80) {
|
||||||
memcpy(ghash + 1, hash, hlen);
|
memcpy(ghash + 1, hash, hlen);
|
||||||
@@ -2135,6 +2136,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_RSA:
|
case SSH_KEYTYPE_RSA:
|
||||||
|
case SSH_KEYTYPE_RSA_CERT01:
|
||||||
switch (sig->hash_type) {
|
switch (sig->hash_type) {
|
||||||
case SSH_DIGEST_SHA256:
|
case SSH_DIGEST_SHA256:
|
||||||
hash_type = "sha256";
|
hash_type = "sha256";
|
||||||
@@ -2179,6 +2181,7 @@ int pki_signature_verify(ssh_session session,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_ED25519:
|
case SSH_KEYTYPE_ED25519:
|
||||||
|
case SSH_KEYTYPE_ED25519_CERT01:
|
||||||
err = pki_ed25519_verify(key, sig, hash, hlen);
|
err = pki_ed25519_verify(key, sig, hash, hlen);
|
||||||
if (err != SSH_OK){
|
if (err != SSH_OK){
|
||||||
ssh_set_error(session, SSH_FATAL, "ed25519 signature verification error");
|
ssh_set_error(session, SSH_FATAL, "ed25519 signature verification error");
|
||||||
@@ -2188,6 +2191,9 @@ int pki_signature_verify(ssh_session session,
|
|||||||
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:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P256_CERT01:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P384_CERT01:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
||||||
#ifdef HAVE_GCRYPT_ECC
|
#ifdef HAVE_GCRYPT_ECC
|
||||||
err = gcry_sexp_build(&sexp,
|
err = gcry_sexp_build(&sexp,
|
||||||
NULL,
|
NULL,
|
||||||
|
|||||||
@@ -912,7 +912,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
|||||||
ssh_signature sig = NULL;
|
ssh_signature sig = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (type != pubkey->type) {
|
if (ssh_key_type_plain(pubkey->type) != type) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
"Incompatible public key provided (%d) expecting (%d)",
|
"Incompatible public key provided (%d) expecting (%d)",
|
||||||
type,
|
type,
|
||||||
@@ -1027,7 +1027,7 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const
|
|||||||
int rc;
|
int rc;
|
||||||
mbedtls_md_type_t md = 0;
|
mbedtls_md_type_t md = 0;
|
||||||
|
|
||||||
if (key->type != sig->type) {
|
if (ssh_key_type_plain(key->type) != sig->type) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
"Can not verify %s signature with %s key",
|
"Can not verify %s signature with %s key",
|
||||||
sig->type_c,
|
sig->type_c,
|
||||||
@@ -1037,6 +1037,7 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const
|
|||||||
|
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case SSH_KEYTYPE_RSA:
|
case SSH_KEYTYPE_RSA:
|
||||||
|
case SSH_KEYTYPE_RSA_CERT01:
|
||||||
switch (sig->hash_type) {
|
switch (sig->hash_type) {
|
||||||
case SSH_DIGEST_SHA1:
|
case SSH_DIGEST_SHA1:
|
||||||
case SSH_DIGEST_AUTO:
|
case SSH_DIGEST_AUTO:
|
||||||
@@ -1069,6 +1070,9 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const
|
|||||||
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:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P256_CERT01:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P384_CERT01:
|
||||||
|
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
||||||
rc = mbedtls_ecdsa_verify(&key->ecdsa->grp, hash, hlen,
|
rc = mbedtls_ecdsa_verify(&key->ecdsa->grp, hash, hlen,
|
||||||
&key->ecdsa->Q, sig->ecdsa_sig.r, sig->ecdsa_sig.s);
|
&key->ecdsa->Q, sig->ecdsa_sig.r, sig->ecdsa_sig.s);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
@@ -1080,6 +1084,7 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_ED25519:
|
case SSH_KEYTYPE_ED25519:
|
||||||
|
case SSH_KEYTYPE_ED25519_CERT01:
|
||||||
rc = pki_ed25519_verify(key, sig, hash, hlen);
|
rc = pki_ed25519_verify(key, sig, hash, hlen);
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
|||||||
Reference in New Issue
Block a user