diff options
author | djm@openbsd.org <djm@openbsd.org> | 2020-06-22 05:56:23 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2020-06-22 16:11:14 +1000 |
commit | 64bc121097f377142f1387ffb2df7592c49935af (patch) | |
tree | db3bc091dda590eba65eb57ebead71224a0d2401 /ssh-ecdsa-sk.c | |
parent | 12848191f8fe725af4485d3600e0842d92f8637f (diff) |
upstream: refactor ECDSA-SK verification a little ahead of adding
support for FIDO webauthn signature verification support; ok markus@
OpenBSD-Commit-ID: c9f478fd8e0c1bd17e511ce8694f010d8e32043e
Diffstat (limited to 'ssh-ecdsa-sk.c')
-rw-r--r-- | ssh-ecdsa-sk.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c index 981d60d74..dcf605ba1 100644 --- a/ssh-ecdsa-sk.c +++ b/ssh-ecdsa-sk.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-ecdsa-sk.c,v 1.5 2019/11/26 03:04:27 djm Exp $ */ | 1 | /* $OpenBSD: ssh-ecdsa-sk.c,v 1.6 2020/06/22 05:56:23 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -83,15 +83,22 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, | |||
83 | /* fetch signature */ | 83 | /* fetch signature */ |
84 | if ((b = sshbuf_from(signature, signaturelen)) == NULL) | 84 | if ((b = sshbuf_from(signature, signaturelen)) == NULL) |
85 | return SSH_ERR_ALLOC_FAIL; | 85 | return SSH_ERR_ALLOC_FAIL; |
86 | if (sshbuf_get_cstring(b, &ktype, NULL) != 0 || | 86 | if ((details = calloc(1, sizeof(*details))) == NULL) { |
87 | sshbuf_froms(b, &sigbuf) != 0 || | 87 | ret = SSH_ERR_ALLOC_FAIL; |
88 | sshbuf_get_u8(b, &sig_flags) != 0 || | 88 | goto out; |
89 | sshbuf_get_u32(b, &sig_counter) != 0) { | 89 | } |
90 | if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { | ||
91 | ret = SSH_ERR_INVALID_FORMAT; | ||
92 | goto out; | ||
93 | } | ||
94 | if (strcmp(ktype, "sk-ecdsa-sha2-nistp256@openssh.com") != 0) { | ||
90 | ret = SSH_ERR_INVALID_FORMAT; | 95 | ret = SSH_ERR_INVALID_FORMAT; |
91 | goto out; | 96 | goto out; |
92 | } | 97 | } |
93 | if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) { | 98 | if (sshbuf_froms(b, &sigbuf) != 0 || |
94 | ret = SSH_ERR_KEY_TYPE_MISMATCH; | 99 | sshbuf_get_u8(b, &sig_flags) != 0 || |
100 | sshbuf_get_u32(b, &sig_counter) != 0) { | ||
101 | ret = SSH_ERR_INVALID_FORMAT; | ||
95 | goto out; | 102 | goto out; |
96 | } | 103 | } |
97 | if (sshbuf_len(b) != 0) { | 104 | if (sshbuf_len(b) != 0) { |
@@ -105,12 +112,8 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, | |||
105 | ret = SSH_ERR_INVALID_FORMAT; | 112 | ret = SSH_ERR_INVALID_FORMAT; |
106 | goto out; | 113 | goto out; |
107 | } | 114 | } |
108 | if ((sig = ECDSA_SIG_new()) == NULL) { | 115 | if (sshbuf_len(sigbuf) != 0) { |
109 | ret = SSH_ERR_ALLOC_FAIL; | 116 | ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; |
110 | goto out; | ||
111 | } | ||
112 | if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) { | ||
113 | ret = SSH_ERR_LIBCRYPTO_ERROR; | ||
114 | goto out; | 117 | goto out; |
115 | } | 118 | } |
116 | #ifdef DEBUG_SK | 119 | #ifdef DEBUG_SK |
@@ -123,12 +126,15 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, | |||
123 | fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n", | 126 | fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n", |
124 | __func__, sig_flags, sig_counter); | 127 | __func__, sig_flags, sig_counter); |
125 | #endif | 128 | #endif |
126 | sig_r = sig_s = NULL; /* transferred */ | 129 | if ((sig = ECDSA_SIG_new()) == NULL) { |
127 | 130 | ret = SSH_ERR_ALLOC_FAIL; | |
128 | if (sshbuf_len(sigbuf) != 0) { | ||
129 | ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; | ||
130 | goto out; | 131 | goto out; |
131 | } | 132 | } |
133 | if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) { | ||
134 | ret = SSH_ERR_LIBCRYPTO_ERROR; | ||
135 | goto out; | ||
136 | } | ||
137 | sig_r = sig_s = NULL; /* transferred */ | ||
132 | 138 | ||
133 | /* Reconstruct data that was supposedly signed */ | 139 | /* Reconstruct data that was supposedly signed */ |
134 | if ((original_signed = sshbuf_new()) == NULL) { | 140 | if ((original_signed = sshbuf_new()) == NULL) { |
@@ -158,10 +164,6 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, | |||
158 | if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed, | 164 | if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed, |
159 | sighash, sizeof(sighash))) != 0) | 165 | sighash, sizeof(sighash))) != 0) |
160 | goto out; | 166 | goto out; |
161 | if ((details = calloc(1, sizeof(*details))) == NULL) { | ||
162 | ret = SSH_ERR_ALLOC_FAIL; | ||
163 | goto out; | ||
164 | } | ||
165 | details->sk_counter = sig_counter; | 167 | details->sk_counter = sig_counter; |
166 | details->sk_flags = sig_flags; | 168 | details->sk_flags = sig_flags; |
167 | #ifdef DEBUG_SK | 169 | #ifdef DEBUG_SK |