summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ssh-sk.c96
1 files changed, 59 insertions, 37 deletions
diff --git a/ssh-sk.c b/ssh-sk.c
index 122a1e2b7..c0f6c1cc1 100644
--- a/ssh-sk.c
+++ b/ssh-sk.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-sk.c,v 1.1 2019/10/31 21:16:20 djm Exp $ */ 1/* $OpenBSD: ssh-sk.c,v 1.2 2019/11/12 19:29:54 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2019 Google LLC 3 * Copyright (c) 2019 Google LLC
4 * 4 *
@@ -143,6 +143,61 @@ sshsk_free_sign_response(struct sk_sign_response *r)
143 freezero(r, sizeof(*r)); 143 freezero(r, sizeof(*r));
144}; 144};
145 145
146/* Assemble key from response */
147static int
148sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
149{
150 struct sshkey *key = NULL;
151 struct sshbuf *b = NULL;
152 EC_POINT *q = NULL;
153 int r;
154
155 *keyp = NULL;
156 if ((key = sshkey_new(KEY_ECDSA_SK)) == NULL) {
157 error("%s: sshkey_new failed", __func__);
158 r = SSH_ERR_ALLOC_FAIL;
159 goto out;
160 }
161 key->ecdsa_nid = NID_X9_62_prime256v1;
162 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL ||
163 (q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL ||
164 (b = sshbuf_new()) == NULL) {
165 error("%s: allocation failed", __func__);
166 r = SSH_ERR_ALLOC_FAIL;
167 goto out;
168 }
169 if ((r = sshbuf_put_string(b,
170 resp->public_key, resp->public_key_len)) != 0) {
171 error("%s: buffer error: %s", __func__, ssh_err(r));
172 goto out;
173 }
174 if ((r = sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa))) != 0) {
175 error("%s: parse key: %s", __func__, ssh_err(r));
176 r = SSH_ERR_INVALID_FORMAT;
177 goto out;
178 }
179 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) {
180 error("Security key returned invalid ECDSA key");
181 r = SSH_ERR_KEY_INVALID_EC_VALUE;
182 goto out;
183 }
184 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
185 /* XXX assume it is a allocation error */
186 error("%s: allocation failed", __func__);
187 r = SSH_ERR_ALLOC_FAIL;
188 goto out;
189 }
190 /* success */
191 *keyp = key;
192 key = NULL; /* transferred */
193 r = 0;
194 out:
195 EC_POINT_free(q);
196 sshkey_free(key);
197 sshbuf_free(b);
198 return r;
199}
200
146int 201int
147sshsk_enroll(const char *provider_path, const char *application, 202sshsk_enroll(const char *provider_path, const char *application,
148 uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp, 203 uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp,
@@ -155,8 +210,6 @@ sshsk_enroll(const char *provider_path, const char *application,
155 size_t challenge_len; 210 size_t challenge_len;
156 struct sk_enroll_response *resp = NULL; 211 struct sk_enroll_response *resp = NULL;
157 int r = SSH_ERR_INTERNAL_ERROR; 212 int r = SSH_ERR_INTERNAL_ERROR;
158 struct sshbuf *b = NULL;
159 EC_POINT *q = NULL;
160 213
161 *keyp = NULL; 214 *keyp = NULL;
162 if (attest) 215 if (attest)
@@ -206,49 +259,20 @@ sshsk_enroll(const char *provider_path, const char *application,
206 r = SSH_ERR_INVALID_FORMAT; 259 r = SSH_ERR_INVALID_FORMAT;
207 goto out; 260 goto out;
208 } 261 }
209 /* Assemble key from response */ 262 if ((r = sshsk_ecdsa_assemble(resp, &key)) != 0)
210 if ((key = sshkey_new(KEY_ECDSA_SK)) == NULL) {
211 error("%s: sshkey_new failed", __func__);
212 r = SSH_ERR_ALLOC_FAIL;
213 goto out; 263 goto out;
214 }
215 key->ecdsa_nid = NID_X9_62_prime256v1;
216 key->sk_flags = flags; 264 key->sk_flags = flags;
217 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || 265 if ((key->sk_key_handle = sshbuf_new()) == NULL ||
218 (q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL || 266 (key->sk_reserved = sshbuf_new()) == NULL) {
219 (key->sk_key_handle = sshbuf_new()) == NULL ||
220 (key->sk_reserved = sshbuf_new()) == NULL ||
221 (b = sshbuf_new()) == NULL) {
222 error("%s: allocation failed", __func__); 267 error("%s: allocation failed", __func__);
223 r = SSH_ERR_ALLOC_FAIL; 268 r = SSH_ERR_ALLOC_FAIL;
224 goto out; 269 goto out;
225 } 270 }
226 if ((r = sshbuf_put_string(b,
227 resp->public_key, resp->public_key_len)) != 0) {
228 error("%s: buffer error: %s", __func__, ssh_err(r));
229 goto out;
230 }
231 if ((key->sk_application = strdup(application)) == NULL) { 271 if ((key->sk_application = strdup(application)) == NULL) {
232 error("%s: strdup application failed", __func__); 272 error("%s: strdup application failed", __func__);
233 r = SSH_ERR_ALLOC_FAIL; 273 r = SSH_ERR_ALLOC_FAIL;
234 goto out; 274 goto out;
235 } 275 }
236 if ((r = sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa))) != 0) {
237 error("%s: parse key: %s", __func__, ssh_err(r));
238 r = SSH_ERR_INVALID_FORMAT;
239 goto out;
240 }
241 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) {
242 error("Security key returned invalid ECDSA key");
243 r = SSH_ERR_KEY_INVALID_EC_VALUE;
244 goto out;
245 }
246 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
247 /* XXX assume it is a allocation error */
248 error("%s: allocation failed", __func__);
249 r = SSH_ERR_ALLOC_FAIL;
250 goto out;
251 }
252 if ((r = sshbuf_put(key->sk_key_handle, resp->key_handle, 276 if ((r = sshbuf_put(key->sk_key_handle, resp->key_handle,
253 resp->key_handle_len)) != 0) { 277 resp->key_handle_len)) != 0) {
254 error("%s: buffer error: %s", __func__, ssh_err(r)); 278 error("%s: buffer error: %s", __func__, ssh_err(r));
@@ -273,9 +297,7 @@ sshsk_enroll(const char *provider_path, const char *application,
273 key = NULL; /* transferred */ 297 key = NULL; /* transferred */
274 r = 0; 298 r = 0;
275 out: 299 out:
276 EC_POINT_free(q);
277 sshsk_free(skp); 300 sshsk_free(skp);
278 sshbuf_free(b);
279 sshkey_free(key); 301 sshkey_free(key);
280 sshsk_free_enroll_response(resp); 302 sshsk_free_enroll_response(resp);
281 explicit_bzero(randchall, sizeof(randchall)); 303 explicit_bzero(randchall, sizeof(randchall));