upstream: begin big refactor of sshkey
Move keytype data and some of the type-specific code (allocation, cleanup, etc) out into each key type's implementation. Subsequent commits will move more, with the goal of having each key-*.c file owning as much of its keytype's implementation as possible. lots of feedback + ok markus@ OpenBSD-Commit-ID: 0f2b4334f73914344e9e5b3d33522d41762a57ec
This commit is contained in:
parent
445363433b
commit
25de1c01a8
58
ssh-dss.c
58
ssh-dss.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-dss.c,v 1.39 2020/02/26 13:40:09 jsg Exp $ */
|
||||
/* $OpenBSD: ssh-dss.c,v 1.40 2022/10/28 00:35:40 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -48,6 +48,32 @@
|
|||
#define INTBLOB_LEN 20
|
||||
#define SIGBLOB_LEN (2*INTBLOB_LEN)
|
||||
|
||||
static u_int
|
||||
ssh_dss_size(const struct sshkey *key)
|
||||
{
|
||||
const BIGNUM *dsa_p;
|
||||
|
||||
if (key->dsa == NULL)
|
||||
return 0;
|
||||
DSA_get0_pqg(key->dsa, &dsa_p, NULL, NULL);
|
||||
return BN_num_bits(dsa_p);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_dss_alloc(struct sshkey *k)
|
||||
{
|
||||
if ((k->dsa = DSA_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_dss_cleanup(struct sshkey *k)
|
||||
{
|
||||
DSA_free(k->dsa);
|
||||
k->dsa = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
|
@ -204,4 +230,34 @@ ssh_dss_verify(const struct sshkey *key,
|
|||
freezero(sigblob, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl_funcs sshkey_dss_funcs = {
|
||||
/* .size = */ ssh_dss_size,
|
||||
/* .alloc = */ ssh_dss_alloc,
|
||||
/* .cleanup = */ ssh_dss_cleanup,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_dss_impl = {
|
||||
/* .name = */ "ssh-dss",
|
||||
/* .shortname = */ "DSA",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_DSA,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_dss_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_dsa_cert_impl = {
|
||||
/* .name = */ "ssh-dss-cert-v01@openssh.com",
|
||||
/* .shortname = */ "DSA-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_DSA_CERT,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_dss_funcs,
|
||||
};
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-ecdsa-sk.c,v 1.8 2020/06/22 23:44:27 djm Exp $ */
|
||||
/* $OpenBSD: ssh-ecdsa-sk.c,v 1.9 2022/10/28 00:35:40 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -61,6 +61,16 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
|
|||
}
|
||||
#else /* OPENSSL_HAS_ECC */
|
||||
|
||||
static void
|
||||
ssh_ecdsa_sk_cleanup(struct sshkey *k)
|
||||
{
|
||||
free(k->sk_application);
|
||||
sshbuf_free(k->sk_key_handle);
|
||||
sshbuf_free(k->sk_reserved);
|
||||
EC_KEY_free(k->ecdsa);
|
||||
k->ecdsa = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check FIDO/W3C webauthn signatures clientData field against the expected
|
||||
* format and prepare a hash of it for use in signature verification.
|
||||
|
@ -321,4 +331,46 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl_funcs sshkey_ecdsa_sk_funcs = {
|
||||
/* .size = */ NULL,
|
||||
/* .alloc = */ NULL,
|
||||
/* .cleanup = */ ssh_ecdsa_sk_cleanup,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_sk_impl = {
|
||||
/* .name = */ "sk-ecdsa-sha2-nistp256@openssh.com",
|
||||
/* .shortname = */ "ECDSA-SK",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA_SK,
|
||||
/* .nid = */ NID_X9_62_prime256v1,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_ecdsa_sk_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_sk_cert_impl = {
|
||||
/* .name = */ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
/* .shortname = */ "ECDSA-SK-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA_SK_CERT,
|
||||
/* .nid = */ NID_X9_62_prime256v1,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_ecdsa_sk_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl = {
|
||||
/* .name = */ "webauthn-sk-ecdsa-sha2-nistp256@openssh.com",
|
||||
/* .shortname = */ "ECDSA-SK",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA_SK,
|
||||
/* .nid = */ NID_X9_62_prime256v1,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 1,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_ecdsa_sk_funcs,
|
||||
};
|
||||
|
||||
#endif /* OPENSSL_HAS_ECC */
|
||||
|
|
106
ssh-ecdsa.c
106
ssh-ecdsa.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-ecdsa.c,v 1.16 2019/01/21 09:54:11 djm Exp $ */
|
||||
/* $OpenBSD: ssh-ecdsa.c,v 1.17 2022/10/28 00:35:40 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -45,6 +45,30 @@
|
|||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
static u_int
|
||||
ssh_ecdsa_size(const struct sshkey *key)
|
||||
{
|
||||
switch (key->ecdsa_nid) {
|
||||
case NID_X9_62_prime256v1:
|
||||
return 256;
|
||||
case NID_secp384r1:
|
||||
return 384;
|
||||
#ifdef OPENSSL_HAS_NISTP521
|
||||
case NID_secp521r1:
|
||||
return 521;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_ecdsa_cleanup(struct sshkey *k)
|
||||
{
|
||||
EC_KEY_free(k->ecdsa);
|
||||
k->ecdsa = NULL;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
|
@ -197,4 +221,84 @@ ssh_ecdsa_verify(const struct sshkey *key,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl_funcs sshkey_ecdsa_funcs = {
|
||||
/* .size = */ ssh_ecdsa_size,
|
||||
/* .alloc = */ NULL,
|
||||
/* .cleanup = */ ssh_ecdsa_cleanup,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_nistp256_impl = {
|
||||
/* .name = */ "ecdsa-sha2-nistp256",
|
||||
/* .shortname = */ "ECDSA",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA,
|
||||
/* .nid = */ NID_X9_62_prime256v1,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_ecdsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl = {
|
||||
/* .name = */ "ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
/* .shortname = */ "ECDSA-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA_CERT,
|
||||
/* .nid = */ NID_X9_62_prime256v1,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_ecdsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_nistp384_impl = {
|
||||
/* .name = */ "ecdsa-sha2-nistp384",
|
||||
/* .shortname = */ "ECDSA",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA,
|
||||
/* .nid = */ NID_secp384r1,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_ecdsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_nistp384_cert_impl = {
|
||||
/* .name = */ "ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
||||
/* .shortname = */ "ECDSA-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA_CERT,
|
||||
/* .nid = */ NID_secp384r1,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_ecdsa_funcs,
|
||||
};
|
||||
|
||||
#ifdef OPENSSL_HAS_NISTP521
|
||||
const struct sshkey_impl sshkey_ecdsa_nistp521_impl = {
|
||||
/* .name = */ "ecdsa-sha2-nistp521",
|
||||
/* .shortname = */ "ECDSA",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA,
|
||||
/* .nid = */ NID_secp521r1,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_ecdsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ecdsa_nistp521_cert_impl = {
|
||||
/* .name = */ "ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
||||
/* .shortname = */ "ECDSA-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ECDSA_CERT,
|
||||
/* .nid = */ NID_secp521r1,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_ecdsa_funcs,
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-ed25519-sk.c,v 1.6 2020/10/18 11:32:02 djm Exp $ */
|
||||
/* $OpenBSD: ssh-ed25519-sk.c,v 1.7 2022/10/28 00:35:40 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -35,6 +35,18 @@
|
|||
#include "ssh.h"
|
||||
#include "digest.h"
|
||||
|
||||
static void
|
||||
ssh_ed25519_sk_cleanup(struct sshkey *k)
|
||||
{
|
||||
free(k->sk_application);
|
||||
sshbuf_free(k->sk_key_handle);
|
||||
sshbuf_free(k->sk_reserved);
|
||||
freezero(k->ed25519_pk, ED25519_PK_SZ);
|
||||
freezero(k->ed25519_sk, ED25519_SK_SZ);
|
||||
k->ed25519_pk = NULL;
|
||||
k->ed25519_sk = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_ed25519_sk_verify(const struct sshkey *key,
|
||||
const u_char *signature, size_t signaturelen,
|
||||
|
@ -161,3 +173,33 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
|
|||
free(ktype);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl_funcs sshkey_ed25519_sk_funcs = {
|
||||
/* .size = */ NULL,
|
||||
/* .alloc = */ NULL,
|
||||
/* .cleanup = */ ssh_ed25519_sk_cleanup,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ed25519_sk_impl = {
|
||||
/* .name = */ "sk-ssh-ed25519@openssh.com",
|
||||
/* .shortname = */ "ED25519-SK",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ED25519_SK,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_ed25519_sk_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ed25519_sk_cert_impl = {
|
||||
/* .name = */ "sk-ssh-ed25519-cert-v01@openssh.com",
|
||||
/* .shortname = */ "ED25519-SK-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ED25519_SK_CERT,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_ed25519_sk_funcs,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-ed25519.c,v 1.10 2022/08/26 08:12:56 djm Exp $ */
|
||||
/* $OpenBSD: ssh-ed25519.c,v 1.11 2022/10/28 00:35:40 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
|
@ -32,6 +32,15 @@
|
|||
#include "ssherr.h"
|
||||
#include "ssh.h"
|
||||
|
||||
static void
|
||||
ssh_ed25519_cleanup(struct sshkey *k)
|
||||
{
|
||||
freezero(k->ed25519_pk, ED25519_PK_SZ);
|
||||
freezero(k->ed25519_sk, ED25519_SK_SZ);
|
||||
k->ed25519_pk = NULL;
|
||||
k->ed25519_sk = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
|
@ -158,3 +167,33 @@ ssh_ed25519_verify(const struct sshkey *key,
|
|||
free(ktype);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl_funcs sshkey_ed25519_funcs = {
|
||||
/* .size = */ NULL,
|
||||
/* .alloc = */ NULL,
|
||||
/* .cleanup = */ ssh_ed25519_cleanup,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ed25519_impl = {
|
||||
/* .name = */ "ssh-ed25519",
|
||||
/* .shortname = */ "ED25519",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ED25519,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_ed25519_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_ed25519_cert_impl = {
|
||||
/* .name = */ "ssh-ed25519-cert-v01@openssh.com",
|
||||
/* .shortname = */ "ED25519-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_ED25519_CERT,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_ed25519_funcs,
|
||||
};
|
||||
|
|
108
ssh-rsa.c
108
ssh-rsa.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-rsa.c,v 1.67 2018/07/03 11:39:54 djm Exp $ */
|
||||
/* $OpenBSD: ssh-rsa.c,v 1.69 2022/10/28 00:35:40 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
|
@ -39,6 +39,32 @@
|
|||
|
||||
static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
|
||||
|
||||
static u_int
|
||||
ssh_rsa_size(const struct sshkey *key)
|
||||
{
|
||||
const BIGNUM *rsa_n;
|
||||
|
||||
if (key->rsa == NULL)
|
||||
return 0;
|
||||
RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
|
||||
return BN_num_bits(rsa_n);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_rsa_alloc(struct sshkey *k)
|
||||
{
|
||||
if ((k->rsa = RSA_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_rsa_cleanup(struct sshkey *k)
|
||||
{
|
||||
RSA_free(k->rsa);
|
||||
k->rsa = NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
rsa_hash_alg_ident(int hash_alg)
|
||||
{
|
||||
|
@ -446,4 +472,84 @@ done:
|
|||
freezero(decrypted, rsasize);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
|
||||
/* .size = */ ssh_rsa_size,
|
||||
/* .alloc = */ ssh_rsa_alloc,
|
||||
/* .cleanup = */ ssh_rsa_cleanup,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_rsa_impl = {
|
||||
/* .name = */ "ssh-rsa",
|
||||
/* .shortname = */ "RSA",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_RSA,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_rsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_rsa_cert_impl = {
|
||||
/* .name = */ "ssh-rsa-cert-v01@openssh.com",
|
||||
/* .shortname = */ "RSA-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_RSA_CERT,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_rsa_funcs,
|
||||
};
|
||||
|
||||
/* SHA2 signature algorithms */
|
||||
|
||||
const struct sshkey_impl sshkey_rsa_sha256_impl = {
|
||||
/* .name = */ "rsa-sha2-256",
|
||||
/* .shortname = */ "RSA",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_RSA,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 1,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_rsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_rsa_sha512_impl = {
|
||||
/* .name = */ "rsa-sha2-512",
|
||||
/* .shortname = */ "RSA",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_RSA,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 1,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_rsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_rsa_sha256_cert_impl = {
|
||||
/* .name = */ "rsa-sha2-256-cert-v01@openssh.com",
|
||||
/* .shortname = */ "RSA-CERT",
|
||||
/* .sigalg = */ "rsa-sha2-256",
|
||||
/* .type = */ KEY_RSA_CERT,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 1,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_rsa_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_rsa_sha512_cert_impl = {
|
||||
/* .name = */ "rsa-sha2-512-cert-v01@openssh.com",
|
||||
/* .shortname = */ "RSA-CERT",
|
||||
/* .sigalg = */ "rsa-sha2-512",
|
||||
/* .type = */ KEY_RSA_CERT,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 1,
|
||||
/* .keybits = */ 0,
|
||||
/* .funcs = */ &sshkey_rsa_funcs,
|
||||
};
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
|
46
ssh-xmss.c
46
ssh-xmss.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-xmss.c,v 1.5 2022/04/20 15:59:18 millert Exp $*/
|
||||
/* $OpenBSD: ssh-xmss.c,v 1.6 2022/10/28 00:35:40 djm Exp $*/
|
||||
/*
|
||||
* Copyright (c) 2017 Stefan-Lukas Gazdag.
|
||||
* Copyright (c) 2017 Markus Friedl.
|
||||
|
@ -37,6 +37,20 @@
|
|||
|
||||
#include "xmss_fast.h"
|
||||
|
||||
static void
|
||||
ssh_xmss_cleanup(struct sshkey *k)
|
||||
{
|
||||
freezero(k->xmss_pk, sshkey_xmss_pklen(k));
|
||||
freezero(k->xmss_sk, sshkey_xmss_sklen(k));
|
||||
sshkey_xmss_free_state(k);
|
||||
free(k->xmss_name);
|
||||
free(k->xmss_filename);
|
||||
k->xmss_pk = NULL;
|
||||
k->xmss_sk = NULL;
|
||||
k->xmss_name = NULL;
|
||||
k->xmss_filename = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
|
@ -184,4 +198,34 @@ ssh_xmss_verify(const struct sshkey *key,
|
|||
free(ktype);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl_funcs sshkey_xmss_funcs = {
|
||||
/* .size = */ NULL,
|
||||
/* .alloc = */ NULL,
|
||||
/* .cleanup = */ ssh_xmss_cleanup,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_xmss_impl = {
|
||||
/* .name = */ "ssh-xmss@openssh.com",
|
||||
/* .shortname = */ "XMSS",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_XMSS,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 0,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_xmss_funcs,
|
||||
};
|
||||
|
||||
const struct sshkey_impl sshkey_xmss_cert_impl = {
|
||||
/* .name = */ "ssh-xmss-cert-v01@openssh.com",
|
||||
/* .shortname = */ "XMSS-CERT",
|
||||
/* .sigalg = */ NULL,
|
||||
/* .type = */ KEY_XMSS_CERT,
|
||||
/* .nid = */ 0,
|
||||
/* .cert = */ 1,
|
||||
/* .sigonly = */ 0,
|
||||
/* .keybits = */ 256,
|
||||
/* .funcs = */ &sshkey_xmss_funcs,
|
||||
};
|
||||
#endif /* WITH_XMSS */
|
||||
|
|
443
sshkey.c
443
sshkey.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshkey.c,v 1.122 2022/09/17 10:30:45 djm Exp $ */
|
||||
/* $OpenBSD: sshkey.c,v 1.123 2022/10/28 00:35:40 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
||||
|
@ -94,111 +94,132 @@ static int sshkey_from_blob_internal(struct sshbuf *buf,
|
|||
struct sshkey **keyp, int allow_cert);
|
||||
|
||||
/* Supported key types */
|
||||
struct keytype {
|
||||
const char *name;
|
||||
const char *shortname;
|
||||
const char *sigalg;
|
||||
int type;
|
||||
int nid;
|
||||
int cert;
|
||||
int sigonly;
|
||||
};
|
||||
static const struct keytype keytypes[] = {
|
||||
{ "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },
|
||||
{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,
|
||||
KEY_ED25519_CERT, 0, 1, 0 },
|
||||
#ifdef ENABLE_SK
|
||||
{ "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL,
|
||||
KEY_ED25519_SK, 0, 0, 0 },
|
||||
{ "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL,
|
||||
KEY_ED25519_SK_CERT, 0, 1, 0 },
|
||||
#endif
|
||||
#ifdef WITH_XMSS
|
||||
{ "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },
|
||||
{ "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,
|
||||
KEY_XMSS_CERT, 0, 1, 0 },
|
||||
#endif /* WITH_XMSS */
|
||||
extern const struct sshkey_impl sshkey_ed25519_impl;
|
||||
extern const struct sshkey_impl sshkey_ed25519_cert_impl;
|
||||
extern const struct sshkey_impl sshkey_ed25519_sk_impl;
|
||||
extern const struct sshkey_impl sshkey_ed25519_sk_cert_impl;
|
||||
#ifdef WITH_OPENSSL
|
||||
{ "ssh-rsa", "RSA", NULL, KEY_RSA, 0, 0, 0 },
|
||||
{ "rsa-sha2-256", "RSA", NULL, KEY_RSA, 0, 0, 1 },
|
||||
{ "rsa-sha2-512", "RSA", NULL, KEY_RSA, 0, 0, 1 },
|
||||
{ "ssh-dss", "DSA", NULL, KEY_DSA, 0, 0, 0 },
|
||||
# ifdef OPENSSL_HAS_ECC
|
||||
{ "ecdsa-sha2-nistp256", "ECDSA", NULL,
|
||||
KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
|
||||
{ "ecdsa-sha2-nistp384", "ECDSA", NULL,
|
||||
KEY_ECDSA, NID_secp384r1, 0, 0 },
|
||||
# ifdef OPENSSL_HAS_NISTP521
|
||||
{ "ecdsa-sha2-nistp521", "ECDSA", NULL,
|
||||
KEY_ECDSA, NID_secp521r1, 0, 0 },
|
||||
# endif /* OPENSSL_HAS_NISTP521 */
|
||||
# ifdef ENABLE_SK
|
||||
{ "sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,
|
||||
KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 0 },
|
||||
{ "webauthn-sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,
|
||||
KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 1 },
|
||||
extern const struct sshkey_impl sshkey_ecdsa_sk_impl;
|
||||
extern const struct sshkey_impl sshkey_ecdsa_sk_cert_impl;
|
||||
extern const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl;
|
||||
# endif /* ENABLE_SK */
|
||||
# endif /* OPENSSL_HAS_ECC */
|
||||
{ "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
|
||||
KEY_RSA_CERT, 0, 1, 0 },
|
||||
{ "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",
|
||||
"rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },
|
||||
{ "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",
|
||||
"rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },
|
||||
{ "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,
|
||||
KEY_DSA_CERT, 0, 1, 0 },
|
||||
# ifdef OPENSSL_HAS_ECC
|
||||
{ "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", NULL,
|
||||
KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
|
||||
{ "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", NULL,
|
||||
KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
|
||||
extern const struct sshkey_impl sshkey_ecdsa_nistp256_impl;
|
||||
extern const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl;
|
||||
extern const struct sshkey_impl sshkey_ecdsa_nistp384_impl;
|
||||
extern const struct sshkey_impl sshkey_ecdsa_nistp384_cert_impl;
|
||||
# ifdef OPENSSL_HAS_NISTP521
|
||||
{ "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL,
|
||||
KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
|
||||
extern const struct sshkey_impl sshkey_ecdsa_nistp521_impl;
|
||||
extern const struct sshkey_impl sshkey_ecdsa_nistp521_cert_impl;
|
||||
# endif /* OPENSSL_HAS_NISTP521 */
|
||||
# ifdef ENABLE_SK
|
||||
{ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-SK-CERT", NULL,
|
||||
KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 },
|
||||
# endif /* ENABLE_SK */
|
||||
# endif /* OPENSSL_HAS_ECC */
|
||||
extern const struct sshkey_impl sshkey_rsa_impl;
|
||||
extern const struct sshkey_impl sshkey_rsa_cert_impl;
|
||||
extern const struct sshkey_impl sshkey_rsa_sha256_impl;
|
||||
extern const struct sshkey_impl sshkey_rsa_sha256_cert_impl;
|
||||
extern const struct sshkey_impl sshkey_rsa_sha512_impl;
|
||||
extern const struct sshkey_impl sshkey_rsa_sha512_cert_impl;
|
||||
extern const struct sshkey_impl sshkey_dss_impl;
|
||||
extern const struct sshkey_impl sshkey_dsa_cert_impl;
|
||||
#endif /* WITH_OPENSSL */
|
||||
{ NULL, NULL, NULL, -1, -1, 0, 0 }
|
||||
#ifdef WITH_XMSS
|
||||
extern const struct sshkey_impl sshkey_xmss_impl;
|
||||
extern const struct sshkey_impl sshkey_xmss_cert_impl;
|
||||
#endif
|
||||
|
||||
const struct sshkey_impl * const keyimpls[] = {
|
||||
&sshkey_ed25519_impl,
|
||||
&sshkey_ed25519_cert_impl,
|
||||
#ifdef ENABLE_SK
|
||||
&sshkey_ed25519_sk_impl,
|
||||
&sshkey_ed25519_sk_cert_impl,
|
||||
#endif
|
||||
#ifdef WITH_OPENSSL
|
||||
# ifdef OPENSSL_HAS_ECC
|
||||
&sshkey_ecdsa_nistp256_impl,
|
||||
&sshkey_ecdsa_nistp256_cert_impl,
|
||||
&sshkey_ecdsa_nistp384_impl,
|
||||
&sshkey_ecdsa_nistp384_cert_impl,
|
||||
# ifdef OPENSSL_HAS_NISTP521
|
||||
&sshkey_ecdsa_nistp521_impl,
|
||||
&sshkey_ecdsa_nistp521_cert_impl,
|
||||
# endif /* OPENSSL_HAS_NISTP521 */
|
||||
# ifdef ENABLE_SK
|
||||
&sshkey_ecdsa_sk_impl,
|
||||
&sshkey_ecdsa_sk_cert_impl,
|
||||
&sshkey_ecdsa_sk_webauthn_impl,
|
||||
# endif /* ENABLE_SK */
|
||||
# endif /* OPENSSL_HAS_ECC */
|
||||
&sshkey_dss_impl,
|
||||
&sshkey_dsa_cert_impl,
|
||||
&sshkey_rsa_impl,
|
||||
&sshkey_rsa_cert_impl,
|
||||
&sshkey_rsa_sha256_impl,
|
||||
&sshkey_rsa_sha256_cert_impl,
|
||||
&sshkey_rsa_sha512_impl,
|
||||
&sshkey_rsa_sha512_cert_impl,
|
||||
#endif /* WITH_OPENSSL */
|
||||
#ifdef WITH_XMSS
|
||||
&sshkey_xmss_impl,
|
||||
&sshkey_xmss_cert_impl,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct sshkey_impl *
|
||||
sshkey_impl_from_type(int type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
if (keyimpls[i]->type == type)
|
||||
return keyimpls[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct sshkey_impl *
|
||||
sshkey_impl_from_type_nid(int type, int nid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
if (keyimpls[i]->type == type &&
|
||||
(keyimpls[i]->nid == 0 || keyimpls[i]->nid == nid))
|
||||
return keyimpls[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
sshkey_type(const struct sshkey *k)
|
||||
{
|
||||
const struct keytype *kt;
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (kt->type == k->type)
|
||||
return kt->shortname;
|
||||
}
|
||||
return "unknown";
|
||||
if ((impl = sshkey_impl_from_type(k->type)) == NULL)
|
||||
return "unknown";
|
||||
return impl->shortname;
|
||||
}
|
||||
|
||||
static const char *
|
||||
sshkey_ssh_name_from_type_nid(int type, int nid)
|
||||
{
|
||||
const struct keytype *kt;
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
|
||||
return kt->name;
|
||||
}
|
||||
return "ssh-unknown";
|
||||
if ((impl = sshkey_impl_from_type_nid(type, nid)) == NULL)
|
||||
return "ssh-unknown";
|
||||
return impl->name;
|
||||
}
|
||||
|
||||
int
|
||||
sshkey_type_is_cert(int type)
|
||||
{
|
||||
const struct keytype *kt;
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (kt->type == type)
|
||||
return kt->cert;
|
||||
}
|
||||
return 0;
|
||||
if ((impl = sshkey_impl_from_type(type)) == NULL)
|
||||
return 0;
|
||||
return impl->cert;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -217,13 +238,15 @@ sshkey_ssh_name_plain(const struct sshkey *k)
|
|||
int
|
||||
sshkey_type_from_name(const char *name)
|
||||
{
|
||||
const struct keytype *kt;
|
||||
int i;
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
impl = keyimpls[i];
|
||||
/* Only allow shortname matches for plain key types */
|
||||
if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
|
||||
(!kt->cert && strcasecmp(kt->shortname, name) == 0))
|
||||
return kt->type;
|
||||
if ((impl->name != NULL && strcmp(name, impl->name) == 0) ||
|
||||
(!impl->cert && strcasecmp(impl->shortname, name) == 0))
|
||||
return impl->type;
|
||||
}
|
||||
return KEY_UNSPEC;
|
||||
}
|
||||
|
@ -244,13 +267,14 @@ key_type_is_ecdsa_variant(int type)
|
|||
int
|
||||
sshkey_ecdsa_nid_from_name(const char *name)
|
||||
{
|
||||
const struct keytype *kt;
|
||||
int i;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (!key_type_is_ecdsa_variant(kt->type))
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
if (!key_type_is_ecdsa_variant(keyimpls[i]->type))
|
||||
continue;
|
||||
if (kt->name != NULL && strcmp(name, kt->name) == 0)
|
||||
return kt->nid;
|
||||
if (keyimpls[i]->name != NULL &&
|
||||
strcmp(name, keyimpls[i]->name) == 0)
|
||||
return keyimpls[i]->nid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -282,25 +306,26 @@ char *
|
|||
sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
|
||||
{
|
||||
char *tmp, *ret = NULL;
|
||||
size_t nlen, rlen = 0;
|
||||
const struct keytype *kt;
|
||||
size_t i, nlen, rlen = 0;
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (kt->name == NULL)
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
impl = keyimpls[i];
|
||||
if (impl->name == NULL)
|
||||
continue;
|
||||
if (!include_sigonly && kt->sigonly)
|
||||
if (!include_sigonly && impl->sigonly)
|
||||
continue;
|
||||
if ((certs_only && !kt->cert) || (plain_only && kt->cert))
|
||||
if ((certs_only && !impl->cert) || (plain_only && impl->cert))
|
||||
continue;
|
||||
if (ret != NULL)
|
||||
ret[rlen++] = sep;
|
||||
nlen = strlen(kt->name);
|
||||
nlen = strlen(impl->name);
|
||||
if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ret = tmp;
|
||||
memcpy(ret + rlen, kt->name, nlen + 1);
|
||||
memcpy(ret + rlen, impl->name, nlen + 1);
|
||||
rlen += nlen;
|
||||
}
|
||||
return ret;
|
||||
|
@ -310,8 +335,8 @@ int
|
|||
sshkey_names_valid2(const char *names, int allow_wildcard)
|
||||
{
|
||||
char *s, *cp, *p;
|
||||
const struct keytype *kt;
|
||||
int type;
|
||||
const struct sshkey_impl *impl;
|
||||
int i, type;
|
||||
|
||||
if (names == NULL || strcmp(names, "") == 0)
|
||||
return 0;
|
||||
|
@ -327,12 +352,15 @@ sshkey_names_valid2(const char *names, int allow_wildcard)
|
|||
* If any has a positive or negative match then
|
||||
* the component is accepted.
|
||||
*/
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (match_pattern_list(kt->name,
|
||||
p, 0) != 0)
|
||||
impl = NULL;
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
if (match_pattern_list(
|
||||
keyimpls[i]->name, p, 0) != 0) {
|
||||
impl = keyimpls[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (kt->type != -1)
|
||||
if (impl != NULL)
|
||||
continue;
|
||||
}
|
||||
free(s);
|
||||
|
@ -346,56 +374,24 @@ sshkey_names_valid2(const char *names, int allow_wildcard)
|
|||
u_int
|
||||
sshkey_size(const struct sshkey *k)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
const BIGNUM *rsa_n, *dsa_p;
|
||||
#endif /* WITH_OPENSSL */
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
switch (k->type) {
|
||||
#ifdef WITH_OPENSSL
|
||||
case KEY_RSA:
|
||||
case KEY_RSA_CERT:
|
||||
if (k->rsa == NULL)
|
||||
return 0;
|
||||
RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
|
||||
return BN_num_bits(rsa_n);
|
||||
case KEY_DSA:
|
||||
case KEY_DSA_CERT:
|
||||
if (k->dsa == NULL)
|
||||
return 0;
|
||||
DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL);
|
||||
return BN_num_bits(dsa_p);
|
||||
case KEY_ECDSA:
|
||||
case KEY_ECDSA_CERT:
|
||||
case KEY_ECDSA_SK:
|
||||
case KEY_ECDSA_SK_CERT:
|
||||
return sshkey_curve_nid_to_bits(k->ecdsa_nid);
|
||||
#endif /* WITH_OPENSSL */
|
||||
case KEY_ED25519:
|
||||
case KEY_ED25519_CERT:
|
||||
case KEY_ED25519_SK:
|
||||
case KEY_ED25519_SK_CERT:
|
||||
case KEY_XMSS:
|
||||
case KEY_XMSS_CERT:
|
||||
return 256; /* XXX */
|
||||
}
|
||||
return 0;
|
||||
if ((impl = sshkey_impl_from_type_nid(k->type, k->ecdsa_nid)) == NULL)
|
||||
return 0;
|
||||
if (impl->funcs->size != NULL)
|
||||
return impl->funcs->size(k);
|
||||
return impl->keybits;
|
||||
}
|
||||
|
||||
static int
|
||||
sshkey_type_is_valid_ca(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
case KEY_ECDSA_SK:
|
||||
case KEY_ED25519:
|
||||
case KEY_ED25519_SK:
|
||||
case KEY_XMSS:
|
||||
return 1;
|
||||
default:
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
if ((impl = sshkey_impl_from_type(type)) == NULL)
|
||||
return 0;
|
||||
}
|
||||
/* All non-certificate types may act as CAs */
|
||||
return !impl->cert;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -573,63 +569,23 @@ struct sshkey *
|
|||
sshkey_new(int type)
|
||||
{
|
||||
struct sshkey *k;
|
||||
#ifdef WITH_OPENSSL
|
||||
RSA *rsa;
|
||||
DSA *dsa;
|
||||
#endif /* WITH_OPENSSL */
|
||||
const struct sshkey_impl *impl = NULL;
|
||||
|
||||
if (type != KEY_UNSPEC &&
|
||||
(impl = sshkey_impl_from_type(type)) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* All non-certificate types may act as CAs */
|
||||
if ((k = calloc(1, sizeof(*k))) == NULL)
|
||||
return NULL;
|
||||
k->type = type;
|
||||
k->ecdsa = NULL;
|
||||
k->ecdsa_nid = -1;
|
||||
k->dsa = NULL;
|
||||
k->rsa = NULL;
|
||||
k->cert = NULL;
|
||||
k->ed25519_sk = NULL;
|
||||
k->ed25519_pk = NULL;
|
||||
k->xmss_sk = NULL;
|
||||
k->xmss_pk = NULL;
|
||||
switch (k->type) {
|
||||
#ifdef WITH_OPENSSL
|
||||
case KEY_RSA:
|
||||
case KEY_RSA_CERT:
|
||||
if ((rsa = RSA_new()) == NULL) {
|
||||
if (impl != NULL && impl->funcs->alloc != NULL) {
|
||||
if (impl->funcs->alloc(k) != 0) {
|
||||
free(k);
|
||||
return NULL;
|
||||
}
|
||||
k->rsa = rsa;
|
||||
break;
|
||||
case KEY_DSA:
|
||||
case KEY_DSA_CERT:
|
||||
if ((dsa = DSA_new()) == NULL) {
|
||||
free(k);
|
||||
return NULL;
|
||||
}
|
||||
k->dsa = dsa;
|
||||
break;
|
||||
case KEY_ECDSA:
|
||||
case KEY_ECDSA_CERT:
|
||||
case KEY_ECDSA_SK:
|
||||
case KEY_ECDSA_SK_CERT:
|
||||
/* Cannot do anything until we know the group */
|
||||
break;
|
||||
#endif /* WITH_OPENSSL */
|
||||
case KEY_ED25519:
|
||||
case KEY_ED25519_CERT:
|
||||
case KEY_ED25519_SK:
|
||||
case KEY_ED25519_SK_CERT:
|
||||
case KEY_XMSS:
|
||||
case KEY_XMSS_CERT:
|
||||
/* no need to prealloc */
|
||||
break;
|
||||
case KEY_UNSPEC:
|
||||
break;
|
||||
default:
|
||||
free(k);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sshkey_is_cert(k)) {
|
||||
if ((k->cert = cert_new()) == NULL) {
|
||||
sshkey_free(k);
|
||||
|
@ -643,66 +599,13 @@ sshkey_new(int type)
|
|||
void
|
||||
sshkey_free(struct sshkey *k)
|
||||
{
|
||||
const struct sshkey_impl *impl;
|
||||
|
||||
if (k == NULL)
|
||||
return;
|
||||
switch (k->type) {
|
||||
#ifdef WITH_OPENSSL
|
||||
case KEY_RSA:
|
||||
case KEY_RSA_CERT:
|
||||
RSA_free(k->rsa);
|
||||
k->rsa = NULL;
|
||||
break;
|
||||
case KEY_DSA:
|
||||
case KEY_DSA_CERT:
|
||||
DSA_free(k->dsa);
|
||||
k->dsa = NULL;
|
||||
break;
|
||||
# ifdef OPENSSL_HAS_ECC
|
||||
case KEY_ECDSA_SK:
|
||||
case KEY_ECDSA_SK_CERT:
|
||||
free(k->sk_application);
|
||||
sshbuf_free(k->sk_key_handle);
|
||||
sshbuf_free(k->sk_reserved);
|
||||
/* FALLTHROUGH */
|
||||
case KEY_ECDSA:
|
||||
case KEY_ECDSA_CERT:
|
||||
EC_KEY_free(k->ecdsa);
|
||||
k->ecdsa = NULL;
|
||||
break;
|
||||
# endif /* OPENSSL_HAS_ECC */
|
||||
#endif /* WITH_OPENSSL */
|
||||
case KEY_ED25519_SK:
|
||||
case KEY_ED25519_SK_CERT:
|
||||
free(k->sk_application);
|
||||
sshbuf_free(k->sk_key_handle);
|
||||
sshbuf_free(k->sk_reserved);
|
||||
/* FALLTHROUGH */
|
||||
case KEY_ED25519:
|
||||
case KEY_ED25519_CERT:
|
||||
freezero(k->ed25519_pk, ED25519_PK_SZ);
|
||||
k->ed25519_pk = NULL;
|
||||
freezero(k->ed25519_sk, ED25519_SK_SZ);
|
||||
k->ed25519_sk = NULL;
|
||||
break;
|
||||
#ifdef WITH_XMSS
|
||||
case KEY_XMSS:
|
||||
case KEY_XMSS_CERT:
|
||||
freezero(k->xmss_pk, sshkey_xmss_pklen(k));
|
||||
k->xmss_pk = NULL;
|
||||
freezero(k->xmss_sk, sshkey_xmss_sklen(k));
|
||||
k->xmss_sk = NULL;
|
||||
sshkey_xmss_free_state(k);
|
||||
free(k->xmss_name);
|
||||
k->xmss_name = NULL;
|
||||
free(k->xmss_filename);
|
||||
k->xmss_filename = NULL;
|
||||
break;
|
||||
#endif /* WITH_XMSS */
|
||||
case KEY_UNSPEC:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((impl = sshkey_impl_from_type(k->type)) != NULL &&
|
||||
impl->funcs->cleanup != NULL)
|
||||
impl->funcs->cleanup(k);
|
||||
if (sshkey_is_cert(k))
|
||||
cert_free(k->cert);
|
||||
freezero(k->shielded_private, k->shielded_len);
|
||||
|
@ -1319,16 +1222,18 @@ sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
|
|||
static int
|
||||
peek_type_nid(const char *s, size_t l, int *nid)
|
||||
{
|
||||
const struct keytype *kt;
|
||||
const struct sshkey_impl *impl;
|
||||
int i;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (kt->name == NULL || strlen(kt->name) != l)
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
impl = keyimpls[i];
|
||||
if (impl->name == NULL || strlen(impl->name) != l)
|
||||
continue;
|
||||
if (memcmp(s, kt->name, l) == 0) {
|
||||
if (memcmp(s, impl->name, l) == 0) {
|
||||
*nid = -1;
|
||||
if (key_type_is_ecdsa_variant(kt->type))
|
||||
*nid = kt->nid;
|
||||
return kt->type;
|
||||
if (key_type_is_ecdsa_variant(impl->type))
|
||||
*nid = impl->nid;
|
||||
return impl->type;
|
||||
}
|
||||
}
|
||||
return KEY_UNSPEC;
|
||||
|
@ -2737,17 +2642,19 @@ sshkey_check_cert_sigtype(const struct sshkey *key, const char *allowed)
|
|||
const char *
|
||||
sshkey_sigalg_by_name(const char *name)
|
||||
{
|
||||
const struct keytype *kt;
|
||||
const struct sshkey_impl *impl;
|
||||
int i;
|
||||
|
||||
for (kt = keytypes; kt->type != -1; kt++) {
|
||||
if (strcmp(kt->name, name) != 0)
|
||||
for (i = 0; keyimpls[i] != NULL; i++) {
|
||||
impl = keyimpls[i];
|
||||
if (strcmp(impl->name, name) != 0)
|
||||
continue;
|
||||
if (kt->sigalg != NULL)
|
||||
return kt->sigalg;
|
||||
if (!kt->cert)
|
||||
return kt->name;
|
||||
if (impl->sigalg != NULL)
|
||||
return impl->sigalg;
|
||||
if (!impl->cert)
|
||||
return impl->name;
|
||||
return sshkey_ssh_name_from_type_nid(
|
||||
sshkey_type_plain(kt->type), kt->nid);
|
||||
sshkey_type_plain(impl->type), impl->nid);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
20
sshkey.h
20
sshkey.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshkey.h,v 1.52 2022/09/17 10:30:45 djm Exp $ */
|
||||
/* $OpenBSD: sshkey.h,v 1.53 2022/10/28 00:35:40 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -164,6 +164,24 @@ struct sshkey_sig_details {
|
|||
uint8_t sk_flags; /* U2F signature flags; see ssh-sk.h */
|
||||
};
|
||||
|
||||
struct sshkey_impl_funcs {
|
||||
u_int (*size)(const struct sshkey *); /* optional */
|
||||
int (*alloc)(struct sshkey *); /* optional */
|
||||
void (*cleanup)(struct sshkey *); /* optional */
|
||||
};
|
||||
|
||||
struct sshkey_impl {
|
||||
const char *name;
|
||||
const char *shortname;
|
||||
const char *sigalg;
|
||||
int type;
|
||||
int nid;
|
||||
int cert;
|
||||
int sigonly;
|
||||
int keybits;
|
||||
const struct sshkey_impl_funcs *funcs;
|
||||
};
|
||||
|
||||
struct sshkey *sshkey_new(int);
|
||||
void sshkey_free(struct sshkey *);
|
||||
int sshkey_equal_public(const struct sshkey *,
|
||||
|
|
Loading…
Reference in New Issue