mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-07 02:39:48 +09:00
Allow limiting RSA key size used for authentication
Thanks to Harry Sintonen from WithSecure for pointing this out. Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
25
src/auth.c
25
src/auth.c
@@ -492,6 +492,7 @@ int ssh_userauth_try_publickey(ssh_session session,
|
||||
{
|
||||
ssh_string pubkey_s = NULL;
|
||||
const char *sig_type_c = NULL;
|
||||
bool allowed;
|
||||
int rc;
|
||||
|
||||
if (session == NULL) {
|
||||
@@ -531,6 +532,13 @@ int ssh_userauth_try_publickey(ssh_session session,
|
||||
sig_type_c);
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
allowed = ssh_key_size_allowed(session, pubkey);
|
||||
if (!allowed) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"The '%s' key type of size %d is not allowed by "
|
||||
"RSA_MIN_SIZE", sig_type_c, ssh_key_size(pubkey));
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
rc = ssh_userauth_request_service(session);
|
||||
if (rc == SSH_AGAIN) {
|
||||
@@ -612,6 +620,7 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
const ssh_key privkey)
|
||||
{
|
||||
ssh_string str = NULL;
|
||||
bool allowed;
|
||||
int rc;
|
||||
const char *sig_type_c = NULL;
|
||||
enum ssh_keytypes_e key_type;
|
||||
@@ -656,6 +665,13 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
sig_type_c);
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
allowed = ssh_key_size_allowed(session, privkey);
|
||||
if (!allowed) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"The '%s' key type of size %d is not allowed by "
|
||||
"RSA_MIN_SIZE", sig_type_c, ssh_key_size(privkey));
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
rc = ssh_userauth_request_service(session);
|
||||
if (rc == SSH_AGAIN) {
|
||||
@@ -732,6 +748,7 @@ static int ssh_userauth_agent_publickey(ssh_session session,
|
||||
ssh_string pubkey_s = NULL;
|
||||
ssh_string sig_blob = NULL;
|
||||
const char *sig_type_c = NULL;
|
||||
bool allowed;
|
||||
int rc;
|
||||
|
||||
switch(session->pending_call_state) {
|
||||
@@ -776,6 +793,14 @@ static int ssh_userauth_agent_publickey(ssh_session session,
|
||||
SSH_STRING_FREE(pubkey_s);
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
allowed = ssh_key_size_allowed(session, pubkey);
|
||||
if (!allowed) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"The '%s' key type of size %d is not allowed by "
|
||||
"RSA_MIN_SIZE", sig_type_c, ssh_key_size(pubkey));
|
||||
SSH_STRING_FREE(pubkey_s);
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
/* request */
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
|
||||
|
||||
@@ -465,6 +465,15 @@ int ssh_options_set_algo(ssh_session session,
|
||||
* in seconds. RFC 4253 Section 9 recommends one hour.
|
||||
* (uint32_t, 0=off)
|
||||
*
|
||||
* - SSH_OPTIONS_RSA_MIN_SIZE
|
||||
* Set the minimum RSA key size in bits to be accepted by the
|
||||
* client for both authentication and hostkey verification.
|
||||
* The values under 768 bits are not accepted even with this
|
||||
* configuration option as they are considered completely broken.
|
||||
* Setting 0 will revert the value to defaults.
|
||||
* Default is 1024 bits or 2048 bits in FIPS mode.
|
||||
* (unsigned int *)
|
||||
*
|
||||
* @param value The value to set. This is a generic pointer and the
|
||||
* datatype which is used should be set according to the
|
||||
* type set.
|
||||
@@ -1028,6 +1037,21 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
session->opts.rekey_time = (*x) * 1000;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_RSA_MIN_SIZE:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
unsigned int *x = (unsigned int *)value;
|
||||
if (*x > 0 && *x < 768) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"The provided value (%u) for minimal RSA key "
|
||||
"size is too small. Use at least 768 bits.", *x);
|
||||
return -1;
|
||||
}
|
||||
session->opts.rsa_min_size = *x;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||
return -1;
|
||||
|
||||
33
src/pki.c
33
src/pki.c
@@ -404,6 +404,39 @@ int ssh_key_algorithm_allowed(ssh_session session, const char *type)
|
||||
return ssh_match_group(allowed_list, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check the given key is acceptable in regards to the key size policy
|
||||
* specified by the configuration
|
||||
*
|
||||
* @param[in] session The SSH session
|
||||
* @param[in] key The SSH key
|
||||
* @returns true if the key is allowed, false otherwise
|
||||
*/
|
||||
bool ssh_key_size_allowed(ssh_session session, ssh_key key)
|
||||
{
|
||||
int key_size = ssh_key_size(key);
|
||||
int min_size = 0;
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
min_size = session->opts.rsa_min_size;
|
||||
if (min_size < 768) {
|
||||
if (ssh_fips_mode()) {
|
||||
min_size = 2048;
|
||||
} else {
|
||||
min_size = 1024;
|
||||
}
|
||||
}
|
||||
if (key_size < min_size) {
|
||||
return false;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a key type to a hash type. This is usually unambiguous
|
||||
* for all the key types, unless the SHA2 extension (RFC 8332) is
|
||||
|
||||
Reference in New Issue
Block a user