summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--auth2-hostbased.c4
-rw-r--r--auth2-pubkey.c11
-rw-r--r--clientloop.c5
-rw-r--r--kexgen.c4
-rw-r--r--kexgexc.c4
-rw-r--r--krl.c4
-rw-r--r--monitor.c14
-rw-r--r--monitor_wrap.c23
-rw-r--r--monitor_wrap.h5
-rw-r--r--ssh-add.c4
-rw-r--r--ssh-ecdsa-sk.c21
-rw-r--r--ssh-ed25519-sk.c20
-rw-r--r--ssh-keygen.c13
-rw-r--r--sshkey.c19
-rw-r--r--sshkey.h18
-rw-r--r--sshsig.c22
-rw-r--r--sshsig.h6
17 files changed, 147 insertions, 50 deletions
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index d4604708..5e9b7c65 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-hostbased.c,v 1.41 2019/09/06 04:53:27 djm Exp $ */
+/* $OpenBSD: auth2-hostbased.c,v 1.42 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -151,7 +151,7 @@ userauth_hostbased(struct ssh *ssh)
if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser,
chost, key)) &&
PRIVSEP(sshkey_verify(key, sig, slen,
- sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat)) == 0)
+ sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0)
authenticated = 1;
auth2_record_key(authctxt, authenticated, key);
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index df12c2c6..2b698670 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.94 2019/09/06 04:53:27 djm Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.95 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -98,6 +98,7 @@ userauth_pubkey(struct ssh *ssh)
int r, pktype;
int authenticated = 0;
struct sshauthopt *authopts = NULL;
+ struct sshkey_sig_details *sig_details = NULL;
if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 ||
(r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
@@ -213,9 +214,14 @@ userauth_pubkey(struct ssh *ssh)
PRIVSEP(sshkey_verify(key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b),
(ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
- ssh->compat)) == 0) {
+ ssh->compat, &sig_details)) == 0) {
authenticated = 1;
}
+ if (sig_details != NULL) {
+ debug("%s: sk_counter = %u, sk_flags = 0x%02x",
+ __func__, sig_details->sk_counter,
+ sig_details->sk_flags);
+ }
auth2_record_key(authctxt, authenticated, key);
} else {
debug("%s: test pkalg %s pkblob %s%s%s",
@@ -266,6 +272,7 @@ done:
free(key_s);
free(ca_s);
free(sig);
+ sshkey_sig_details_free(sig_details);
return authenticated;
}
diff --git a/clientloop.c b/clientloop.c
index 06850621..880abfda 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.328 2019/11/13 04:47:52 deraadt Exp $ */
+/* $OpenBSD: clientloop.c,v 1.329 2019/11/25 00:51:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2003,7 +2003,8 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
sshbuf_ptr(signdata), sshbuf_len(signdata),
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0) {
+ use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
+ NULL)) != 0) {
error("%s: server gave bad signature for %s key %zu",
__func__, sshkey_type(ctx->keys[i]), i);
goto out;
diff --git a/kexgen.c b/kexgen.c
index bb996b50..69348b96 100644
--- a/kexgen.c
+++ b/kexgen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgen.c,v 1.3 2019/09/06 05:23:55 djm Exp $ */
+/* $OpenBSD: kexgen.c,v 1.4 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
@@ -212,7 +212,7 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
goto out;
if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
- kex->hostkey_alg, ssh->compat)) != 0)
+ kex->hostkey_alg, ssh->compat, NULL)) != 0)
goto out;
if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
diff --git a/kexgexc.c b/kexgexc.c
index 1c65b8a1..323a659b 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexc.c,v 1.34 2019/01/23 00:30:41 djm Exp $ */
+/* $OpenBSD: kexgexc.c,v 1.35 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -199,7 +199,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
goto out;
if ((r = sshkey_verify(server_host_key, signature, slen, hash,
- hashlen, kex->hostkey_alg, ssh->compat)) != 0)
+ hashlen, kex->hostkey_alg, ssh->compat, NULL)) != 0)
goto out;
if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
diff --git a/krl.c b/krl.c
index 89cb433b..aa8318cf 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $OpenBSD: krl.c,v 1.45 2019/10/31 21:23:19 djm Exp $ */
+/* $OpenBSD: krl.c,v 1.46 2019/11/25 00:51:37 djm Exp $ */
#include "includes.h"
@@ -1079,7 +1079,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
}
/* Check signature over entire KRL up to this point */
if ((r = sshkey_verify(key, blob, blen,
- sshbuf_ptr(buf), sig_off, NULL, 0)) != 0)
+ sshbuf_ptr(buf), sig_off, NULL, 0, NULL)) != 0)
goto out;
/* Check if this key has already signed this KRL */
for (i = 0; i < nca_used; i++) {
diff --git a/monitor.c b/monitor.c
index 1186c1dd..40ff43ee 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.201 2019/11/19 22:21:15 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.202 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -1391,6 +1391,7 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
char *sigalg;
size_t signaturelen, datalen, bloblen;
int r, ret, valid_data = 0, encoded_ret;
+ struct sshkey_sig_details *sig_details = NULL;
if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
(r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
@@ -1430,7 +1431,7 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
fatal("%s: bad signature data blob", __func__);
ret = sshkey_verify(key, signature, signaturelen, data, datalen,
- sigalg, ssh->compat);
+ sigalg, ssh->compat, &sig_details);
debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key,
(ret == 0) ? "verified" : "unverified",
(ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : "");
@@ -1450,8 +1451,15 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
/* encode ret != 0 as positive integer, since we're sending u32 */
encoded_ret = (ret != 0);
- if ((r = sshbuf_put_u32(m, encoded_ret)) != 0)
+ if ((r = sshbuf_put_u32(m, encoded_ret)) != 0 ||
+ (r = sshbuf_put_u8(m, sig_details != NULL != 0)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if (sig_details != NULL) {
+ if ((r = sshbuf_put_u32(m, sig_details->sk_counter)) != 0 ||
+ (r = sshbuf_put_u8(m, sig_details->sk_flags)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ }
+ sshkey_sig_details_free(sig_details);
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
return ret == 0;
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 5b42c0e5..06599e3b 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.115 2019/11/18 16:10:05 naddy Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.116 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -495,15 +495,19 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
int
mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
- const u_char *data, size_t datalen, const char *sigalg, u_int compat)
+ const u_char *data, size_t datalen, const char *sigalg, u_int compat,
+ struct sshkey_sig_details **sig_detailsp)
{
struct sshbuf *m;
u_int encoded_ret = 0;
int r;
+ u_char sig_details_present, flags;
+ u_int counter;
debug3("%s entering", __func__);
-
+ if (sig_detailsp != NULL)
+ *sig_detailsp = NULL;
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if ((r = sshkey_puts(key, m)) != 0 ||
@@ -518,8 +522,19 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_KEYVERIFY, m);
- if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0)
+ if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0 ||
+ (r = sshbuf_get_u8(m, &sig_details_present)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if (sig_details_present && encoded_ret == 0) {
+ if ((r = sshbuf_get_u32(m, &counter)) != 0 ||
+ (r = sshbuf_get_u8(m, &flags)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if (sig_detailsp != NULL) {
+ *sig_detailsp = xcalloc(1, sizeof(**sig_detailsp));
+ (*sig_detailsp)->sk_counter = counter;
+ (*sig_detailsp)->sk_flags = flags;
+ }
+ }
sshbuf_free(m);
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 76330fc6..23ab096a 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.h,v 1.43 2019/10/31 21:23:19 djm Exp $ */
+/* $OpenBSD: monitor_wrap.h,v 1.44 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -38,6 +38,7 @@ struct monitor;
struct Authctxt;
struct sshkey;
struct sshauthopt;
+struct sshkey_sig_details;
void mm_log_handler(LogLevel, const char *, void *);
int mm_is_monitor(void);
@@ -57,7 +58,7 @@ int mm_user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int,
int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *,
const char *, struct sshkey *);
int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
- const u_char *, size_t, const char *, u_int);
+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
#ifdef GSSAPI
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
diff --git a/ssh-add.c b/ssh-add.c
index 6b1962bc..1d85e9d6 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.146 2019/11/18 16:10:05 naddy Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.147 2019/11/25 00:51:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -451,7 +451,7 @@ test_key(int agent_fd, const char *filename)
goto done;
}
if ((r = sshkey_verify(key, sig, slen, data, sizeof(data),
- NULL, 0)) != 0) {
+ NULL, 0, NULL)) != 0) {
error("Signature verification failed for %s: %s",
filename, ssh_err(r));
goto done;
diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c
index f33fac71..b2f31ae2 100644
--- a/ssh-ecdsa-sk.c
+++ b/ssh-ecdsa-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa-sk.c,v 1.3 2019/11/25 00:38:17 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa-sk.c,v 1.4 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -53,7 +53,8 @@
int
ssh_ecdsa_sk_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat)
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
ECDSA_SIG *sig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
@@ -63,10 +64,13 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL;
char *ktype = NULL;
+ struct sshkey_sig_details *details = NULL;
#ifdef DEBUG_SK
char *tmp = NULL;
#endif
+ if (detailsp != NULL)
+ *detailsp = NULL;
if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA_SK ||
signature == NULL || signaturelen == 0)
@@ -149,6 +153,12 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed,
sighash, sizeof(sighash))) != 0)
goto out;
+ if ((details = calloc(1, sizeof(*details))) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ details->sk_counter = sig_counter;
+ details->sk_flags = sig_flags;
#ifdef DEBUG_SK
fprintf(stderr, "%s: signed buf:\n", __func__);
sshbuf_dump(original_signed, stderr);
@@ -168,13 +178,18 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
-
+ /* success */
+ if (detailsp != NULL) {
+ *detailsp = details;
+ details = NULL;
+ }
out:
explicit_bzero(&sig_flags, sizeof(sig_flags));
explicit_bzero(&sig_counter, sizeof(sig_counter));
explicit_bzero(msghash, sizeof(msghash));
explicit_bzero(sighash, sizeof(msghash));
explicit_bzero(apphash, sizeof(apphash));
+ sshkey_sig_details_free(details);
sshbuf_free(original_signed);
sshbuf_free(sigbuf);
sshbuf_free(b);
diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c
index 622cb45c..d11fde6f 100644
--- a/ssh-ed25519-sk.c
+++ b/ssh-ed25519-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519-sk.c,v 1.2 2019/11/12 19:34:40 markus Exp $ */
+/* $OpenBSD: ssh-ed25519-sk.c,v 1.3 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
@@ -33,7 +33,8 @@
int
ssh_ed25519_sk_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat)
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
struct sshbuf *b = NULL;
struct sshbuf *encoded = NULL;
@@ -49,6 +50,10 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
unsigned long long smlen = 0, mlen = 0;
int r = SSH_ERR_INTERNAL_ERROR;
int ret;
+ struct sshkey_sig_details *details = NULL;
+
+ if (detailsp != NULL)
+ *detailsp = NULL;
if (key == NULL ||
sshkey_type_plain(key->type) != KEY_ED25519_SK ||
@@ -84,6 +89,12 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
+ if ((details = calloc(1, sizeof(*details))) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ details->sk_counter = sig_counter;
+ details->sk_flags = sig_flags;
if ((encoded = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
@@ -115,11 +126,16 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
/* XXX compare 'm' and 'sm + len' ? */
/* success */
r = 0;
+ if (detailsp != NULL) {
+ *detailsp = details;
+ details = NULL;
+ }
out:
if (m != NULL) {
explicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */
free(m);
}
+ sshkey_sig_details_free(details);
sshbuf_free(b);
sshbuf_free(encoded);
free(ktype);
diff --git a/ssh-keygen.c b/ssh-keygen.c
index e869989d..08dd7cb8 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.369 2019/11/18 23:16:49 naddy Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.370 2019/11/25 00:51:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -584,7 +584,7 @@ do_convert_private_ssh2(struct sshbuf *b)
if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
NULL, NULL, 0) != 0 ||
sshkey_verify(key, sig, slen, data, sizeof(data),
- NULL, 0) != 0) {
+ NULL, 0, NULL) != 0) {
sshkey_free(key);
free(sig);
return NULL;
@@ -2657,7 +2657,9 @@ verify(const char *signature, const char *sig_namespace, const char *principal,
struct sshbuf *sigbuf = NULL, *abuf = NULL;
struct sshkey *sign_key = NULL;
char *fp = NULL;
+ struct sshkey_sig_details *sig_details = NULL;
+ memset(&sig_details, 0, sizeof(sig_details));
if ((abuf = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new() failed", __func__);
@@ -2675,13 +2677,17 @@ verify(const char *signature, const char *sig_namespace, const char *principal,
return r;
}
if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
- &sign_key)) != 0)
+ &sign_key, &sig_details)) != 0)
goto done; /* sshsig_verify() prints error */
if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
fatal("%s: sshkey_fingerprint failed", __func__);
debug("Valid (unverified) signature from key %s", fp);
+ if (sig_details != NULL) {
+ debug2("%s: signature details: counter = %u, flags = 0x%02x",
+ __func__, sig_details->sk_counter, sig_details->sk_flags);
+ }
free(fp);
fp = NULL;
@@ -2726,6 +2732,7 @@ done:
sshbuf_free(sigbuf);
sshbuf_free(abuf);
sshkey_free(sign_key);
+ sshkey_sig_details_free(sig_details);
free(fp);
return ret;
}
diff --git a/sshkey.c b/sshkey.c
index 48dd8bea..920c0dc3 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.95 2019/11/18 06:58:00 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.96 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -2301,7 +2301,7 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
goto out;
}
if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
- sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
+ sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0)
goto out;
if ((ret = sshkey_get_sigtype(sig, slen,
&key->cert->signature_type)) != 0)
@@ -2796,8 +2796,11 @@ sshkey_sign(struct sshkey *key,
int
sshkey_verify(const struct sshkey *key,
const u_char *sig, size_t siglen,
- const u_char *data, size_t dlen, const char *alg, u_int compat)
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
+ if (detailsp != NULL)
+ *detailsp = NULL;
if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
switch (key->type) {
@@ -2813,7 +2816,7 @@ sshkey_verify(const struct sshkey *key,
case KEY_ECDSA_SK_CERT:
case KEY_ECDSA_SK:
return ssh_ecdsa_sk_verify(key, sig, siglen, data, dlen,
- compat);
+ compat, detailsp);
# endif /* ENABLE_SK */
# endif /* OPENSSL_HAS_ECC */
case KEY_RSA_CERT:
@@ -2826,7 +2829,7 @@ sshkey_verify(const struct sshkey *key,
case KEY_ED25519_SK:
case KEY_ED25519_SK_CERT:
return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen,
- compat);
+ compat, detailsp);
#ifdef WITH_XMSS
case KEY_XMSS:
case KEY_XMSS_CERT:
@@ -4661,6 +4664,12 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
passphrase, keyp, commentp);
}
+void
+sshkey_sig_details_free(struct sshkey_sig_details *details)
+{
+ freezero(details, sizeof(*details));
+}
+
#ifdef WITH_XMSS
/*
* serialize the key with the current state and forward the state
diff --git a/sshkey.h b/sshkey.h
index a34a4cb4..56c0a9cd 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.39 2019/11/13 07:53:10 markus Exp $ */
+/* $OpenBSD: sshkey.h,v 1.40 2019/11/25 00:51:37 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -156,6 +156,12 @@ struct sshkey {
#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES
#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
+/* Additional fields contained in signature */
+struct sshkey_sig_details {
+ uint32_t sk_counter; /* U2F signature counter */
+ uint8_t sk_flags; /* U2F signature flags; see ssh-sk.h */
+};
+
struct sshkey *sshkey_new(int);
void sshkey_free(struct sshkey *);
int sshkey_equal_public(const struct sshkey *,
@@ -230,7 +236,7 @@ int sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
int sshkey_sign(struct sshkey *, u_char **, size_t *,
const u_char *, size_t, const char *, const char *, u_int);
int sshkey_verify(const struct sshkey *, const u_char *, size_t,
- const u_char *, size_t, const char *, u_int);
+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
int sshkey_check_sigtype(const u_char *, size_t, const char *);
const char *sshkey_sigalg_by_name(const char *);
int sshkey_get_sigtype(const u_char *, size_t, char **);
@@ -270,6 +276,8 @@ int sshkey_forward_state(const struct sshkey *, u_int32_t, sshkey_printfn *);
int sshkey_private_serialize_maxsign(struct sshkey *key, struct sshbuf *buf,
u_int32_t maxsign, sshkey_printfn *pr);
+void sshkey_sig_details_free(struct sshkey_sig_details *);
+
#ifdef SSHKEY_INTERNAL
int ssh_rsa_sign(const struct sshkey *key,
u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
@@ -289,7 +297,8 @@ int ssh_ecdsa_verify(const struct sshkey *key,
const u_char *data, size_t datalen, u_int compat);
int ssh_ecdsa_sk_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat);
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp);
int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_ed25519_verify(const struct sshkey *key,
@@ -297,7 +306,8 @@ int ssh_ed25519_verify(const struct sshkey *key,
const u_char *data, size_t datalen, u_int compat);
int ssh_ed25519_sk_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat);
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp);
int ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_xmss_verify(const struct sshkey *key,
diff --git a/sshsig.c b/sshsig.c
index 8c7aba1b..abba3f67 100644
--- a/sshsig.c
+++ b/sshsig.c
@@ -286,7 +286,7 @@ sshsig_peek_hashalg(struct sshbuf *signature, char **hashalgp)
static int
sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
const struct sshbuf *h_message, const char *expect_namespace,
- struct sshkey **sign_keyp)
+ struct sshkey **sign_keyp, struct sshkey_sig_details **sig_details)
{
int r = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *buf = NULL, *toverify = NULL;
@@ -296,6 +296,8 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
size_t siglen;
debug("%s: verify message length %zu", __func__, sshbuf_len(h_message));
+ if (sig_details != NULL)
+ *sig_details = NULL;
if (sign_keyp != NULL)
*sign_keyp = NULL;
@@ -361,7 +363,7 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
}
}
if ((r = sshkey_verify(key, sig, siglen, sshbuf_ptr(toverify),
- sshbuf_len(toverify), NULL, 0)) != 0) {
+ sshbuf_len(toverify), NULL, 0, sig_details)) != 0) {
error("Signature verification failed: %s", ssh_err(r));
goto done;
}
@@ -453,15 +455,17 @@ sshsig_signb(struct sshkey *key, const char *hashalg, const char *sk_provider,
int
sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message,
- const char *expect_namespace, struct sshkey **sign_keyp)
+ const char *expect_namespace, struct sshkey **sign_keyp,
+ struct sshkey_sig_details **sig_details)
{
struct sshbuf *b = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
char *hashalg = NULL;
+ if (sig_details != NULL)
+ *sig_details = NULL;
if (sign_keyp != NULL)
*sign_keyp = NULL;
-
if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
return r;
debug("%s: signature made with hash \"%s\"", __func__, hashalg);
@@ -470,7 +474,7 @@ sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message,
goto out;
}
if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
- sign_keyp)) != 0)
+ sign_keyp, sig_details)) != 0)
goto out;
/* success */
r = 0;
@@ -579,15 +583,17 @@ sshsig_sign_fd(struct sshkey *key, const char *hashalg, const char *sk_provider,
int
sshsig_verify_fd(struct sshbuf *signature, int fd,
- const char *expect_namespace, struct sshkey **sign_keyp)
+ const char *expect_namespace, struct sshkey **sign_keyp,
+ struct sshkey_sig_details **sig_details)
{
struct sshbuf *b = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
char *hashalg = NULL;
+ if (sig_details != NULL)
+ *sig_details = NULL;
if (sign_keyp != NULL)
*sign_keyp = NULL;
-
if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
return r;
debug("%s: signature made with hash \"%s\"", __func__, hashalg);
@@ -596,7 +602,7 @@ sshsig_verify_fd(struct sshbuf *signature, int fd,
goto out;
}
if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
- sign_keyp)) != 0)
+ sign_keyp, sig_details)) != 0)
goto out;
/* success */
r = 0;
diff --git a/sshsig.h b/sshsig.h
index 487db116..386c8b5d 100644
--- a/sshsig.h
+++ b/sshsig.h
@@ -20,6 +20,7 @@
struct sshbuf;
struct sshkey;
struct sshsigopt;
+struct sshkey_sig_details;
typedef int sshsig_signer(struct sshkey *, u_char **, size_t *,
const u_char *, size_t, const char *, const char *, u_int, void *);
@@ -43,7 +44,7 @@ int sshsig_signb(struct sshkey *key, const char *hashalg,
*/
int sshsig_verifyb(struct sshbuf *signature,
const struct sshbuf *message, const char *sig_namespace,
- struct sshkey **sign_keyp);
+ struct sshkey **sign_keyp, struct sshkey_sig_details **sig_details);
/* File/FD-oriented API */
@@ -62,7 +63,8 @@ int sshsig_sign_fd(struct sshkey *key, const char *hashalg,
* Returns 0 on success or a negative SSH_ERR_* error code on failure.
*/
int sshsig_verify_fd(struct sshbuf *signature, int fd,
- const char *sig_namespace, struct sshkey **sign_keyp);
+ const char *sig_namespace, struct sshkey **sign_keyp,
+ struct sshkey_sig_details **sig_details);
/* Utility functions */