agent: Add support for RSA signatures with SHA256 and SHA512
This commit is contained in:
@@ -81,6 +81,14 @@ enum agent_msg_type_t {
|
|||||||
SSH_AGENT_SIGN_RESPONSE = 14,
|
SSH_AGENT_SIGN_RESPONSE = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags for signatures
|
||||||
|
*/
|
||||||
|
enum agent_signature_flags_t {
|
||||||
|
SSH_AGENT_FLAG_SHA2_256 = 2,
|
||||||
|
SSH_AGENT_FLAG_SHA2_512 = 4,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read a byte from a blob
|
* read a byte from a blob
|
||||||
*/
|
*/
|
||||||
@@ -217,12 +225,29 @@ static bool read_key(private_agent_private_key_t *this, public_key_t *pubkey)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool scheme_supported(private_agent_private_key_t *this,
|
static bool scheme_supported(private_agent_private_key_t *this,
|
||||||
signature_scheme_t scheme)
|
signature_scheme_t scheme, uint32_t *flags,
|
||||||
|
char **prefix)
|
||||||
{
|
{
|
||||||
switch (this->pubkey->get_type(this->pubkey))
|
switch (this->pubkey->get_type(this->pubkey))
|
||||||
{
|
{
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
return scheme == SIGN_RSA_EMSA_PKCS1_SHA1;
|
switch (scheme)
|
||||||
|
{
|
||||||
|
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||||
|
*prefix = "ssh-rsa";
|
||||||
|
return TRUE;
|
||||||
|
case SIGN_RSA_EMSA_PKCS1_SHA2_256:
|
||||||
|
*flags |= SSH_AGENT_FLAG_SHA2_256;
|
||||||
|
*prefix = "rsa-sha2-256";
|
||||||
|
return TRUE;
|
||||||
|
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
||||||
|
*flags |= SSH_AGENT_FLAG_SHA2_512;
|
||||||
|
*prefix = "rsa-sha2-512";
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
case KEY_ECDSA:
|
case KEY_ECDSA:
|
||||||
return scheme == SIGN_ECDSA_256 ||
|
return scheme == SIGN_ECDSA_256 ||
|
||||||
scheme == SIGN_ECDSA_384 ||
|
scheme == SIGN_ECDSA_384 ||
|
||||||
@@ -236,11 +261,11 @@ METHOD(private_key_t, sign, bool,
|
|||||||
private_agent_private_key_t *this, signature_scheme_t scheme, void *params,
|
private_agent_private_key_t *this, signature_scheme_t scheme, void *params,
|
||||||
chunk_t data, chunk_t *signature)
|
chunk_t data, chunk_t *signature)
|
||||||
{
|
{
|
||||||
uint32_t len, flags;
|
uint32_t len, flags = 0;
|
||||||
char buf[2048];
|
char buf[2048], *prefix = NULL;
|
||||||
chunk_t blob;
|
chunk_t blob;
|
||||||
|
|
||||||
if (!scheme_supported(this, scheme))
|
if (!scheme_supported(this, scheme, &flags, &prefix))
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "signature scheme %N not supported by ssh-agent",
|
DBG1(DBG_LIB, "signature scheme %N not supported by ssh-agent",
|
||||||
signature_scheme_names, scheme);
|
signature_scheme_names, scheme);
|
||||||
@@ -272,7 +297,7 @@ METHOD(private_key_t, sign, bool,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = htonl(0);
|
flags = htonl(flags);
|
||||||
if (write(this->socket, &flags, sizeof(flags)) != sizeof(flags))
|
if (write(this->socket, &flags, sizeof(flags)) != sizeof(flags))
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "writing to ssh-agent failed");
|
DBG1(DBG_LIB, "writing to ssh-agent failed");
|
||||||
@@ -290,9 +315,15 @@ METHOD(private_key_t, sign, bool,
|
|||||||
}
|
}
|
||||||
/* parse length */
|
/* parse length */
|
||||||
blob = read_string(&blob);
|
blob = read_string(&blob);
|
||||||
/* check sig type */
|
/* verify type */
|
||||||
if (chunk_equals(read_string(&blob), chunk_from_str("ssh-rsa")))
|
if (prefix && !chunk_equals(read_string(&blob), chunk_from_str(prefix)))
|
||||||
{ /* for RSA the signature has no special encoding */
|
{
|
||||||
|
DBG1(DBG_LIB, "ssh-agent didn't return requested %s signature", prefix);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->pubkey->get_type(this->pubkey) == KEY_RSA)
|
||||||
|
{ /* for RSA, the signature has no special encoding */
|
||||||
blob = read_string(&blob);
|
blob = read_string(&blob);
|
||||||
if (blob.len)
|
if (blob.len)
|
||||||
{
|
{
|
||||||
@@ -301,7 +332,7 @@ METHOD(private_key_t, sign, bool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* anything else is treated as ECSDA for now */
|
{ /* parse ECDSA signatures */
|
||||||
blob = read_string(&blob);
|
blob = read_string(&blob);
|
||||||
if (blob.len)
|
if (blob.len)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user