diff options
-rw-r--r-- | auth2-hostbased.c | 4 | ||||
-rw-r--r-- | auth2-pubkey.c | 11 | ||||
-rw-r--r-- | clientloop.c | 5 | ||||
-rw-r--r-- | kexgen.c | 4 | ||||
-rw-r--r-- | kexgexc.c | 4 | ||||
-rw-r--r-- | krl.c | 4 | ||||
-rw-r--r-- | monitor.c | 14 | ||||
-rw-r--r-- | monitor_wrap.c | 23 | ||||
-rw-r--r-- | monitor_wrap.h | 5 | ||||
-rw-r--r-- | ssh-add.c | 4 | ||||
-rw-r--r-- | ssh-ecdsa-sk.c | 21 | ||||
-rw-r--r-- | ssh-ed25519-sk.c | 20 | ||||
-rw-r--r-- | ssh-keygen.c | 13 | ||||
-rw-r--r-- | sshkey.c | 19 | ||||
-rw-r--r-- | sshkey.h | 18 | ||||
-rw-r--r-- | sshsig.c | 22 | ||||
-rw-r--r-- | sshsig.h | 6 |
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; @@ -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) @@ -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) @@ -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++) { @@ -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); @@ -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; } @@ -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 @@ -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, @@ -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; @@ -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 */ |