version 1.66, 2018/02/14 16:27:24 |
version 1.67, 2018/07/03 11:39:54 |
|
|
return NULL; |
return NULL; |
} |
} |
|
|
|
/* |
|
* Returns the hash algorithm ID for a given algorithm identifier as used |
|
* inside the signature blob, |
|
*/ |
static int |
static int |
rsa_hash_alg_from_ident(const char *ident) |
rsa_hash_id_from_ident(const char *ident) |
{ |
{ |
if (strcmp(ident, "ssh-rsa") == 0 || |
if (strcmp(ident, "ssh-rsa") == 0) |
strcmp(ident, "ssh-rsa-cert-v01@openssh.com") == 0) |
|
return SSH_DIGEST_SHA1; |
return SSH_DIGEST_SHA1; |
if (strcmp(ident, "rsa-sha2-256") == 0) |
if (strcmp(ident, "rsa-sha2-256") == 0) |
return SSH_DIGEST_SHA256; |
return SSH_DIGEST_SHA256; |
|
|
return -1; |
return -1; |
} |
} |
|
|
|
/* |
|
* Return the hash algorithm ID for the specified key name. This includes |
|
* all the cases of rsa_hash_id_from_ident() but also the certificate key |
|
* types. |
|
*/ |
static int |
static int |
|
rsa_hash_id_from_keyname(const char *alg) |
|
{ |
|
int r; |
|
|
|
if ((r = rsa_hash_id_from_ident(alg)) != -1) |
|
return r; |
|
if (strcmp(alg, "ssh-rsa-cert-v01@openssh.com") == 0) |
|
return SSH_DIGEST_SHA1; |
|
if (strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0) |
|
return SSH_DIGEST_SHA256; |
|
if (strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0) |
|
return SSH_DIGEST_SHA512; |
|
return -1; |
|
} |
|
|
|
static int |
rsa_hash_alg_nid(int type) |
rsa_hash_alg_nid(int type) |
{ |
{ |
switch (type) { |
switch (type) { |
|
|
if (alg_ident == NULL || strlen(alg_ident) == 0) |
if (alg_ident == NULL || strlen(alg_ident) == 0) |
hash_alg = SSH_DIGEST_SHA1; |
hash_alg = SSH_DIGEST_SHA1; |
else |
else |
hash_alg = rsa_hash_alg_from_ident(alg_ident); |
hash_alg = rsa_hash_id_from_keyname(alg_ident); |
if (key == NULL || key->rsa == NULL || hash_alg == -1 || |
if (key == NULL || key->rsa == NULL || hash_alg == -1 || |
sshkey_type_plain(key->type) != KEY_RSA) |
sshkey_type_plain(key->type) != KEY_RSA) |
return SSH_ERR_INVALID_ARGUMENT; |
return SSH_ERR_INVALID_ARGUMENT; |
|
|
const char *alg) |
const char *alg) |
{ |
{ |
char *sigtype = NULL; |
char *sigtype = NULL; |
int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; |
int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; |
size_t len = 0, diff, modlen, dlen; |
size_t len = 0, diff, modlen, dlen; |
struct sshbuf *b = NULL; |
struct sshbuf *b = NULL; |
u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; |
u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; |
|
|
ret = SSH_ERR_INVALID_FORMAT; |
ret = SSH_ERR_INVALID_FORMAT; |
goto out; |
goto out; |
} |
} |
/* XXX djm: need cert types that reliably yield SHA-2 signatures */ |
if ((hash_alg = rsa_hash_id_from_ident(sigtype)) == -1) { |
if (alg != NULL && strcmp(alg, sigtype) != 0 && |
|
strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) { |
|
error("%s: RSA signature type mismatch: " |
|
"expected %s received %s", __func__, alg, sigtype); |
|
ret = SSH_ERR_SIGNATURE_INVALID; |
|
goto out; |
|
} |
|
if ((hash_alg = rsa_hash_alg_from_ident(sigtype)) == -1) { |
|
ret = SSH_ERR_KEY_TYPE_MISMATCH; |
ret = SSH_ERR_KEY_TYPE_MISMATCH; |
goto out; |
goto out; |
|
} |
|
/* |
|
* Allow ssh-rsa-cert-v01 certs to generate SHA2 signatures for |
|
* legacy reasons, but otherwise the signature type should match. |
|
*/ |
|
if (alg != NULL && strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) { |
|
if ((want_alg = rsa_hash_id_from_keyname(alg)) == -1) { |
|
ret = SSH_ERR_INVALID_ARGUMENT; |
|
goto out; |
|
} |
|
if (hash_alg != want_alg) { |
|
ret = SSH_ERR_SIGNATURE_INVALID; |
|
goto out; |
|
} |
} |
} |
if (sshbuf_get_string(b, &sigblob, &len) != 0) { |
if (sshbuf_get_string(b, &sigblob, &len) != 0) { |
ret = SSH_ERR_INVALID_FORMAT; |
ret = SSH_ERR_INVALID_FORMAT; |