Page MenuHome GnuPG

agent-ssh-fix-2025-10-30.patch

Authored By
gniibe
Thu, Oct 30, 6:14 AM
Size
8 KB
Subscribers

agent-ssh-fix-2025-10-30.patch

diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 2a9de20ee..015db6b20 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -26,6 +26,7 @@
RFC-4252 - Authentication Protocol
RFC-4253 - Transport Layer Protocol
RFC-5656 - ECC support
+ RFC-8332 - Use of RSA Keys with SHA-256 and SHA-512
The protocol for the agent is defined in:
@@ -90,10 +91,11 @@
#define SSH_DSA_SIGNATURE_ELEMS 2
#define SSH_AGENT_RSA_SHA2_256 0x02
#define SSH_AGENT_RSA_SHA2_512 0x04
-#define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
-#define SPEC_FLAG_IS_ECDSA (1 << 1)
-#define SPEC_FLAG_IS_EdDSA (1 << 2) /*(lowercase 'd' on purpose.)*/
-#define SPEC_FLAG_WITH_CERT (1 << 7)
+#define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
+#define SPEC_FLAG_IS_ECDSA (1 << 1)
+#define SPEC_FLAG_IS_EdDSA (1 << 2) /*(lowercase 'd' on purpose.)*/
+#define SPEC_FLAG_WITH_CERT (1 << 7)
+#define SPEC_FLAG_WITH_FIXEDLENGTH (1 << 8)
/* The name of the control file. */
#define SSH_CONTROL_FILE_NAME "sshcontrol"
@@ -157,6 +159,7 @@ typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
algorithm; therefore algorithm specific signature encoding
functions are necessary. */
typedef gpg_error_t (*ssh_signature_encoder_t) (ssh_key_type_spec_t *spec,
+ gcry_sexp_t key,
estream_t signature_blob,
gcry_sexp_t sig);
@@ -275,15 +278,19 @@ static gpg_error_t ssh_handler_extension (ctrl_t ctrl,
static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
static gpg_error_t ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
+ gcry_sexp_t key,
estream_t signature_blob,
gcry_sexp_t signature);
static gpg_error_t ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
+ gcry_sexp_t key,
estream_t signature_blob,
gcry_sexp_t signature);
static gpg_error_t ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
+ gcry_sexp_t key,
estream_t signature_blob,
gcry_sexp_t signature);
static gpg_error_t ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
+ gcry_sexp_t key,
estream_t signature_blob,
gcry_sexp_t signature);
static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
@@ -1405,6 +1412,7 @@ ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
/* Signature encoder function for RSA. */
static gpg_error_t
ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
+ gcry_sexp_t key,
estream_t signature_blob,
gcry_sexp_t s_signature)
{
@@ -1464,7 +1472,35 @@ ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
/* RSA specific */
s = mpis[0];
- err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
+ if ((spec->flags & SPEC_FLAG_WITH_FIXEDLENGTH))
+ {
+ unsigned int n = gcry_pk_get_nbits (key);
+ size_t modulus_n;
+
+ if (!n)
+ {
+ err = gpg_error (GPG_ERR_INTERNAL);
+ goto out;
+ }
+
+ modulus_n = (n+7)/8;
+ data = gpgrt_malloc (modulus_n);
+ if (!data)
+ {
+ err = gpg_error_from_syserror ();
+ goto out;
+ }
+
+ err = gcry_mpi_print (GCRYMPI_FMT_USG, data, modulus_n, &data_n, s);
+ if (data_n < modulus_n)
+ {
+ memmove (data, data+modulus_n-data_n, data_n);
+ memset (data, 0, modulus_n-data_n);
+ data_n = modulus_n;
+ }
+ }
+ else
+ err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
if (err)
goto out;
@@ -1482,6 +1518,7 @@ ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
/* Signature encoder function for DSA. */
static gpg_error_t
ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
+ gcry_sexp_t key,
estream_t signature_blob,
gcry_sexp_t s_signature)
{
@@ -1498,6 +1535,8 @@ ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
unsigned char *data = NULL;
size_t data_n;
+ (void)key;
+
valuelist = gcry_sexp_nth (s_signature, 1);
if (!valuelist)
{
@@ -1578,7 +1617,7 @@ ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
/* Signature encoder function for ECDSA. */
static gpg_error_t
-ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
+ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec, gcry_sexp_t key,
estream_t stream, gcry_sexp_t s_signature)
{
gpg_error_t err = 0;
@@ -1594,6 +1633,8 @@ ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
size_t data_n[2];
size_t innerlen;
+ (void)key;
+
valuelist = gcry_sexp_nth (s_signature, 1);
if (!valuelist)
{
@@ -1668,7 +1709,7 @@ ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
/* Signature encoder function for EdDSA. */
static gpg_error_t
-ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
+ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec, gcry_sexp_t key,
estream_t stream, gcry_sexp_t s_signature)
{
gpg_error_t err = 0;
@@ -1682,6 +1723,8 @@ ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
size_t data_n[2];
size_t totallen = 0;
+ (void)key;
+
valuelist = gcry_sexp_nth (s_signature, 1);
if (!valuelist)
{
@@ -2870,7 +2913,7 @@ data_hash (unsigned char *data, size_t data_n,
stored in ssh format at R_SIG and it's size at R_SIGLEN; the caller
must use es_free to release this memory. */
static gpg_error_t
-data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec, gcry_sexp_t key,
const void *hash, size_t hashlen,
unsigned char **r_sig, size_t *r_siglen)
{
@@ -2896,22 +2939,22 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
/* Ask for confirmation if needed. */
if (confirm_flag_from_sshcontrol (hexgrip))
{
- gcry_sexp_t key;
+ gcry_sexp_t k;
char *fpr, *prompt;
char *comment = NULL;
- err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key, NULL);
+ err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &k, NULL);
if (err)
goto out;
- err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &fpr);
+ err = ssh_get_fingerprint_string (k, opt.ssh_fingerprint_digest, &fpr);
if (!err)
{
- gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
+ gcry_sexp_t tmpsxp = gcry_sexp_find_token (k, "comment", 0);
if (tmpsxp)
comment = gcry_sexp_nth_string (tmpsxp, 1);
gcry_sexp_release (tmpsxp);
}
- gcry_sexp_release (key);
+ gcry_sexp_release (k);
if (err)
goto out;
prompt = xtryasprintf (L_("An ssh process requested the use of key%%0A"
@@ -2950,7 +2993,7 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
if (err)
goto out;
- err = spec->signature_encoder (spec, stream, signature_sexp);
+ err = spec->signature_encoder (spec, key, stream, signature_sexp);
if (err)
goto out;
@@ -3007,7 +3050,7 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
/* Flag processing. */
{
- u32 flags;
+ u32 flags = 0;
err = stream_read_uint32 (request, &flags);
if (err)
@@ -3020,6 +3063,7 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
flags &= ~SSH_AGENT_RSA_SHA2_512;
spec.ssh_identifier = "rsa-sha2-512";
spec.hash_algo = GCRY_MD_SHA512;
+ spec.flags |= SPEC_FLAG_WITH_FIXEDLENGTH;
}
if ((flags & SSH_AGENT_RSA_SHA2_256))
{
@@ -3027,6 +3071,7 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
flags &= ~SSH_AGENT_RSA_SHA2_256;
spec.ssh_identifier = "rsa-sha2-256";
spec.hash_algo = GCRY_MD_SHA256;
+ spec.flags |= SPEC_FLAG_WITH_FIXEDLENGTH;
}
}
@@ -3080,9 +3125,9 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
/* Sign data. */
if ((spec.flags & SPEC_FLAG_IS_EdDSA))
- err = data_sign (ctrl, &spec, data, data_size, &sig, &sig_n);
+ err = data_sign (ctrl, &spec, key, data, data_size, &sig, &sig_n);
else
- err = data_sign (ctrl, &spec, NULL, 0, &sig, &sig_n);
+ err = data_sign (ctrl, &spec, key, NULL, 0, &sig, &sig_n);
out:
/* Done. */

File Metadata

Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
b6/09/af8c261ea31b98013da479049456

Event Timeline

I think at line 82 we should use xtrymalloc as always in gpg-agent. xtrymalloc expands to gcry_malloc.