mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
Fix handling of RSA + SHA-2 certified host keys.
Initial live testing pointed out that the ssh_keyalg corresponding to the certified version of rsa-sha2-512 was expecting to see the SSH id string "rsa-sha2-512-cert-v01@openssh.com" at the start of the public key blob, whereas in fact, the _key_ type identifier is still "ssh-rsa-...", just as the key type for base rsa-sha2-512 is base ssh-rsa. Fixed inside openssh-certs.c, by adding a couple more strings to the 'extra' structure.
This commit is contained in:
parent
3bb7e6ba9e
commit
de5f295b99
@ -66,6 +66,22 @@ typedef struct opensshcert_extra {
|
|||||||
* string itself.
|
* string itself.
|
||||||
*/
|
*/
|
||||||
blob_fmt pub_fmt, base_ossh_fmt, cert_ossh_fmt;
|
blob_fmt pub_fmt, base_ossh_fmt, cert_ossh_fmt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The RSA-SHA2 algorithm names have their SSH id set to names
|
||||||
|
* like "rsa-sha2-512-cert-...", which is what will be received in
|
||||||
|
* the KEXINIT algorithm list if a host key in one of those
|
||||||
|
* algorithms is presented. But the _key_ type id that will appear
|
||||||
|
* in the public key blob is "ssh-rsa-cert-...". So we need a
|
||||||
|
* separate field to indicate the key type id we expect to see in
|
||||||
|
* certified public keys, and also the one we want to put back
|
||||||
|
* into the artificial public blob we make to pass to the
|
||||||
|
* constructor for the underlying key.
|
||||||
|
*
|
||||||
|
* (In rsa.c this is managed much more simply, because everything
|
||||||
|
* sharing the same vtable wants the same key type id.)
|
||||||
|
*/
|
||||||
|
const char *cert_key_ssh_id, *base_key_ssh_id;
|
||||||
} opensshcert_extra;
|
} opensshcert_extra;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -206,18 +222,18 @@ static const ssh_keyalg *opensshcert_related_alg(const ssh_keyalg *self,
|
|||||||
* macro so I can also make an array of them all.
|
* macro so I can also make an array of them all.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define KEYALG_LIST(X) \
|
#define KEYALG_LIST(X) \
|
||||||
X(ssh_dsa, "ssh-dss", dsa) \
|
X(ssh_dsa, "ssh-dss", "ssh-dss", dsa) \
|
||||||
X(ssh_rsa, "ssh-rsa", rsa) \
|
X(ssh_rsa, "ssh-rsa", "ssh-rsa", rsa) \
|
||||||
X(ssh_rsa_sha256, "rsa-sha2-256", rsa) \
|
X(ssh_rsa_sha256, "rsa-sha2-256", "ssh-rsa", rsa) \
|
||||||
X(ssh_rsa_sha512, "rsa-sha2-512", rsa) \
|
X(ssh_rsa_sha512, "rsa-sha2-512", "ssh-rsa", rsa) \
|
||||||
X(ssh_ecdsa_ed25519, "ssh-ed25519", eddsa) \
|
X(ssh_ecdsa_ed25519, "ssh-ed25519", "ssh-ed25519", eddsa) \
|
||||||
X(ssh_ecdsa_nistp256, "ecdsa-sha2-nistp256", ecdsa) \
|
X(ssh_ecdsa_nistp256, "ecdsa-sha2-nistp256","ecdsa-sha2-nistp256", ecdsa) \
|
||||||
X(ssh_ecdsa_nistp384, "ecdsa-sha2-nistp384", ecdsa) \
|
X(ssh_ecdsa_nistp384, "ecdsa-sha2-nistp384","ecdsa-sha2-nistp384", ecdsa) \
|
||||||
X(ssh_ecdsa_nistp521, "ecdsa-sha2-nistp521", ecdsa) \
|
X(ssh_ecdsa_nistp521, "ecdsa-sha2-nistp521","ecdsa-sha2-nistp521", ecdsa) \
|
||||||
/* end of list */
|
/* end of list */
|
||||||
|
|
||||||
#define KEYALG_DEF(name, ssh_id_prefix, fmt_prefix) \
|
#define KEYALG_DEF(name, ssh_alg_id_prefix, ssh_key_id_prefix, fmt_prefix) \
|
||||||
const struct opensshcert_extra opensshcert_##name##_extra = { \
|
const struct opensshcert_extra opensshcert_##name##_extra = { \
|
||||||
.pub_fmt = { .fmt = fmt_prefix ## _pub_fmt, \
|
.pub_fmt = { .fmt = fmt_prefix ## _pub_fmt, \
|
||||||
.len = lenof(fmt_prefix ## _pub_fmt) }, \
|
.len = lenof(fmt_prefix ## _pub_fmt) }, \
|
||||||
@ -225,6 +241,8 @@ static const ssh_keyalg *opensshcert_related_alg(const ssh_keyalg *self,
|
|||||||
.len = lenof(fmt_prefix ## _base_ossh_fmt) }, \
|
.len = lenof(fmt_prefix ## _base_ossh_fmt) }, \
|
||||||
.cert_ossh_fmt = { .fmt = fmt_prefix ## _cert_ossh_fmt, \
|
.cert_ossh_fmt = { .fmt = fmt_prefix ## _cert_ossh_fmt, \
|
||||||
.len = lenof(fmt_prefix ## _cert_ossh_fmt) }, \
|
.len = lenof(fmt_prefix ## _cert_ossh_fmt) }, \
|
||||||
|
.cert_key_ssh_id = ssh_key_id_prefix "-cert-v01@openssh.com", \
|
||||||
|
.base_key_ssh_id = ssh_key_id_prefix, \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
const ssh_keyalg opensshcert_##name = { \
|
const ssh_keyalg opensshcert_##name = { \
|
||||||
@ -249,7 +267,7 @@ static const ssh_keyalg *opensshcert_related_alg(const ssh_keyalg *self,
|
|||||||
.supported_flags = opensshcert_supported_flags, \
|
.supported_flags = opensshcert_supported_flags, \
|
||||||
.alternate_ssh_id = opensshcert_alternate_ssh_id, \
|
.alternate_ssh_id = opensshcert_alternate_ssh_id, \
|
||||||
.related_alg = opensshcert_related_alg, \
|
.related_alg = opensshcert_related_alg, \
|
||||||
.ssh_id = ssh_id_prefix "-cert-v01@openssh.com", \
|
.ssh_id = ssh_alg_id_prefix "-cert-v01@openssh.com", \
|
||||||
.cache_id = NULL, \
|
.cache_id = NULL, \
|
||||||
.extra = &opensshcert_##name##_extra, \
|
.extra = &opensshcert_##name##_extra, \
|
||||||
.is_certificate = true, \
|
.is_certificate = true, \
|
||||||
@ -258,7 +276,7 @@ static const ssh_keyalg *opensshcert_related_alg(const ssh_keyalg *self,
|
|||||||
KEYALG_LIST(KEYALG_DEF)
|
KEYALG_LIST(KEYALG_DEF)
|
||||||
#undef KEYALG_DEF
|
#undef KEYALG_DEF
|
||||||
|
|
||||||
#define KEYALG_LIST_ENTRY(name, ssh_id_prefix, fmt_prefix) &opensshcert_##name,
|
#define KEYALG_LIST_ENTRY(name, algid, keyid, fmt) &opensshcert_##name,
|
||||||
static const ssh_keyalg *const opensshcert_all_keyalgs[] = {
|
static const ssh_keyalg *const opensshcert_all_keyalgs[] = {
|
||||||
KEYALG_LIST(KEYALG_LIST_ENTRY)
|
KEYALG_LIST(KEYALG_LIST_ENTRY)
|
||||||
};
|
};
|
||||||
@ -273,7 +291,7 @@ static opensshcert_key *opensshcert_new_shared(
|
|||||||
BinarySource_BARE_INIT_PL(src, blob);
|
BinarySource_BARE_INIT_PL(src, blob);
|
||||||
|
|
||||||
/* Check the initial key-type string */
|
/* Check the initial key-type string */
|
||||||
if (!ptrlen_eq_string(get_string(src), self->ssh_id))
|
if (!ptrlen_eq_string(get_string(src), extra->cert_key_ssh_id))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
opensshcert_key *ck = snew(opensshcert_key);
|
opensshcert_key *ck = snew(opensshcert_key);
|
||||||
@ -283,7 +301,7 @@ static opensshcert_key *opensshcert_new_shared(
|
|||||||
ck->nonce = strbuf_dup(get_string(src));
|
ck->nonce = strbuf_dup(get_string(src));
|
||||||
strbuf *basepub = strbuf_new();
|
strbuf *basepub = strbuf_new();
|
||||||
{
|
{
|
||||||
put_stringz(basepub, self->base_alg->ssh_id);
|
put_stringz(basepub, extra->base_key_ssh_id);
|
||||||
|
|
||||||
/* Make the base public key blob out of the public key
|
/* Make the base public key blob out of the public key
|
||||||
* material in the certificate. This invocation of the
|
* material in the certificate. This invocation of the
|
||||||
@ -461,7 +479,8 @@ static ssh_key *opensshcert_ca_pub_key(
|
|||||||
|
|
||||||
static void opensshcert_signature_preimage(opensshcert_key *ck, BinarySink *bs)
|
static void opensshcert_signature_preimage(opensshcert_key *ck, BinarySink *bs)
|
||||||
{
|
{
|
||||||
put_stringz(bs, ck->sshk.vt->ssh_id);
|
const opensshcert_extra *extra = ck->sshk.vt->extra;
|
||||||
|
put_stringz(bs, extra->cert_key_ssh_id);
|
||||||
put_stringpl(bs, ptrlen_from_strbuf(ck->nonce));
|
put_stringpl(bs, ptrlen_from_strbuf(ck->nonce));
|
||||||
|
|
||||||
strbuf *basepub = strbuf_new();
|
strbuf *basepub = strbuf_new();
|
||||||
|
Loading…
Reference in New Issue
Block a user