mirror of git://anongit.mindrot.org/openssh.git
upstream: when signing a challenge using a FIDO toke, perform the
hashing in the middleware layer rather than in ssh code. This allows middlewares that call APIs that perform the hashing implicitly (including Microsoft's AFAIK). ok markus@ OpenBSD-Commit-ID: c9fc8630aba26c75d5016884932f08a5a237f37d
This commit is contained in:
parent
c9d10dbc0c
commit
59d2de956e
|
@ -236,7 +236,7 @@ support for the common case of USB HID security keys internally.
|
|||
|
||||
The middleware library need only expose a handful of functions:
|
||||
|
||||
#define SSH_SK_VERSION_MAJOR 0x00040000 /* API version */
|
||||
#define SSH_SK_VERSION_MAJOR 0x00050000 /* API version */
|
||||
#define SSH_SK_VERSION_MAJOR_MASK 0xffff0000
|
||||
|
||||
/* Flags */
|
||||
|
|
4
sk-api.h
4
sk-api.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sk-api.h,v 1.8 2020/01/25 23:13:09 djm Exp $ */
|
||||
/* $OpenBSD: sk-api.h,v 1.9 2020/04/28 04:02:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Google LLC
|
||||
*
|
||||
|
@ -71,7 +71,7 @@ struct sk_option {
|
|||
uint8_t required;
|
||||
};
|
||||
|
||||
#define SSH_SK_VERSION_MAJOR 0x00040000 /* current API version */
|
||||
#define SSH_SK_VERSION_MAJOR 0x00050000 /* current API version */
|
||||
#define SSH_SK_VERSION_MAJOR_MASK 0xffff0000
|
||||
|
||||
/* Return the version of the middleware API */
|
||||
|
|
35
sk-usbhid.c
35
sk-usbhid.c
|
@ -24,6 +24,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <sha2.h>
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/opensslv.h>
|
||||
|
@ -31,6 +32,7 @@
|
|||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
||||
#include <fido.h>
|
||||
|
@ -710,8 +712,28 @@ check_sign_load_resident_options(struct sk_option **options, char **devicep)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate SHA256(m) */
|
||||
static int
|
||||
sha256_mem(const void *m, size_t mlen, u_char *d, size_t dlen)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
u_int mdlen;
|
||||
#endif
|
||||
|
||||
if (dlen != 32)
|
||||
return -1;
|
||||
#ifdef WITH_OPENSSL
|
||||
mdlen = dlen;
|
||||
if (!EVP_Digest(m, mlen, d, &mdlen, EVP_sha256(), NULL))
|
||||
return -1;
|
||||
#else
|
||||
SHA256Data(m, mlen, d);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
|
||||
sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
|
||||
const char *application,
|
||||
const uint8_t *key_handle, size_t key_handle_len,
|
||||
uint8_t flags, const char *pin, struct sk_option **options,
|
||||
|
@ -721,6 +743,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
|
|||
char *device = NULL;
|
||||
fido_dev_t *dev = NULL;
|
||||
struct sk_sign_response *response = NULL;
|
||||
uint8_t message[32];
|
||||
int ret = SSH_SK_ERR_GENERAL;
|
||||
int r;
|
||||
|
||||
|
@ -735,7 +758,12 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
|
|||
*sign_response = NULL;
|
||||
if (check_sign_load_resident_options(options, &device) != 0)
|
||||
goto out; /* error already logged */
|
||||
if ((dev = find_device(device, message, message_len,
|
||||
/* hash data to be signed before it goes to the security key */
|
||||
if ((r = sha256_mem(data, datalen, message, sizeof(message))) != 0) {
|
||||
skdebug(__func__, "hash message failed");
|
||||
goto out;
|
||||
}
|
||||
if ((dev = find_device(device, message, sizeof(message),
|
||||
application, key_handle, key_handle_len)) == NULL) {
|
||||
skdebug(__func__, "couldn't find device for key handle");
|
||||
goto out;
|
||||
|
@ -745,7 +773,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
|
|||
goto out;
|
||||
}
|
||||
if ((r = fido_assert_set_clientdata_hash(assert, message,
|
||||
message_len)) != FIDO_OK) {
|
||||
sizeof(message))) != FIDO_OK) {
|
||||
skdebug(__func__, "fido_assert_set_clientdata_hash: %s",
|
||||
fido_strerr(r));
|
||||
goto out;
|
||||
|
@ -783,6 +811,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
|
|||
response = NULL;
|
||||
ret = 0;
|
||||
out:
|
||||
explicit_bzero(message, sizeof(message));
|
||||
free(device);
|
||||
if (response != NULL) {
|
||||
free(response->sig_r);
|
||||
|
|
14
ssh-sk.c
14
ssh-sk.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-sk.c,v 1.29 2020/03/06 18:25:48 markus Exp $ */
|
||||
/* $OpenBSD: ssh-sk.c,v 1.30 2020/04/28 04:02:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Google LLC
|
||||
*
|
||||
|
@ -615,7 +615,6 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
|
|||
int type, alg;
|
||||
struct sk_sign_response *resp = NULL;
|
||||
struct sshbuf *inner_sig = NULL, *sig = NULL;
|
||||
uint8_t message[32];
|
||||
struct sk_option **opts = NULL;
|
||||
|
||||
debug("%s: provider \"%s\", key %s, flags 0x%02x%s", __func__,
|
||||
|
@ -650,15 +649,7 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* hash data to be signed before it goes to the security key */
|
||||
if ((r = ssh_digest_memory(SSH_DIGEST_SHA256, data, datalen,
|
||||
message, sizeof(message))) != 0) {
|
||||
error("%s: hash application failed: %s", __func__, ssh_err(r));
|
||||
r = SSH_ERR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
if ((r = skp->sk_sign(alg, message, sizeof(message),
|
||||
key->sk_application,
|
||||
if ((r = skp->sk_sign(alg, data, datalen, key->sk_application,
|
||||
sshbuf_ptr(key->sk_key_handle), sshbuf_len(key->sk_key_handle),
|
||||
key->sk_flags, pin, opts, &resp)) != 0) {
|
||||
debug("%s: sk_sign failed with code %d", __func__, r);
|
||||
|
@ -707,7 +698,6 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
|
|||
r = 0;
|
||||
out:
|
||||
sshsk_free_options(opts);
|
||||
explicit_bzero(message, sizeof(message));
|
||||
sshsk_free(skp);
|
||||
sshsk_free_sign_response(resp);
|
||||
sshbuf_free(sig);
|
||||
|
|
Loading…
Reference in New Issue