blob: 236e02676e9011bef26937cb1e60913ccdd6c493 [file] [log] [blame]
Damien Millerbcd00ab2013-12-07 10:41:55 +11001/* $OpenBSD: key.c,v 1.108 2013/12/06 13:34:54 markus Exp $ */
Damien Miller450a7a12000-03-26 13:04:51 +10002/*
Damien Millere4340be2000-09-16 13:29:08 +11003 * read_bignum():
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 *
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
11 *
12 *
Ben Lindstrom44697232001-07-04 03:32:30 +000013 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
Darren Tucker0f0ef0a2008-06-13 08:58:05 +100014 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
Damien Miller450a7a12000-03-26 13:04:51 +100015 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
Damien Miller450a7a12000-03-26 13:04:51 +100024 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
Damien Millerd7834352006-08-05 12:39:39 +100036
Damien Miller450a7a12000-03-26 13:04:51 +100037#include "includes.h"
Ben Lindstrom226cfa02001-01-22 05:34:40 +000038
Darren Tucker9c16ac92008-06-13 04:40:35 +100039#include <sys/param.h>
Damien Millerd7834352006-08-05 12:39:39 +100040#include <sys/types.h>
41
Damien Miller5be9d9e2013-12-07 11:24:01 +110042#include "crypto_api.h"
43
Damien Miller450a7a12000-03-26 13:04:51 +100044#include <openssl/evp.h>
Darren Tucker3d295a62008-02-28 19:22:04 +110045#include <openbsd-compat/openssl-compat.h>
Ben Lindstrom226cfa02001-01-22 05:34:40 +000046
Damien Millerded319c2006-09-01 15:38:36 +100047#include <stdarg.h>
Damien Millera7a73ee2006-08-05 11:37:59 +100048#include <stdio.h>
Damien Millere3476ed2006-07-24 14:13:33 +100049#include <string.h>
50
Damien Miller450a7a12000-03-26 13:04:51 +100051#include "xmalloc.h"
52#include "key.h"
Damien Miller0bc1bd82000-11-13 22:57:25 +110053#include "rsa.h"
Damien Millereba71ba2000-04-29 23:57:08 +100054#include "uuencode.h"
Damien Miller0bc1bd82000-11-13 22:57:25 +110055#include "buffer.h"
Ben Lindstrom226cfa02001-01-22 05:34:40 +000056#include "log.h"
Damien Miller8a0268f2010-07-16 13:57:51 +100057#include "misc.h"
Damien Miller0a80ca12010-02-27 07:55:05 +110058#include "ssh2.h"
59
Damien Millerf3747bf2013-01-18 11:44:04 +110060static int to_blob(const Key *, u_char **, u_int *, int);
Damien Miller4a3a9d42013-10-30 22:19:47 +110061static Key *key_from_blob2(const u_char *, u_int, int);
Damien Millerf3747bf2013-01-18 11:44:04 +110062
Damien Miller0a80ca12010-02-27 07:55:05 +110063static struct KeyCert *
64cert_new(void)
65{
66 struct KeyCert *cert;
67
68 cert = xcalloc(1, sizeof(*cert));
69 buffer_init(&cert->certblob);
Damien Miller4e270b02010-04-16 15:56:21 +100070 buffer_init(&cert->critical);
71 buffer_init(&cert->extensions);
Damien Miller0a80ca12010-02-27 07:55:05 +110072 cert->key_id = NULL;
73 cert->principals = NULL;
74 cert->signature_key = NULL;
75 return cert;
76}
Damien Miller450a7a12000-03-26 13:04:51 +100077
78Key *
79key_new(int type)
80{
81 Key *k;
82 RSA *rsa;
83 DSA *dsa;
Damien Miller07d86be2006-03-26 14:19:21 +110084 k = xcalloc(1, sizeof(*k));
Damien Miller450a7a12000-03-26 13:04:51 +100085 k->type = type;
Damien Millereb8b60e2010-08-31 22:41:14 +100086 k->ecdsa = NULL;
87 k->ecdsa_nid = -1;
Damien Millereba71ba2000-04-29 23:57:08 +100088 k->dsa = NULL;
89 k->rsa = NULL;
Damien Miller0a80ca12010-02-27 07:55:05 +110090 k->cert = NULL;
Damien Miller5be9d9e2013-12-07 11:24:01 +110091 k->ed25519_sk = NULL;
92 k->ed25519_pk = NULL;
Damien Miller450a7a12000-03-26 13:04:51 +100093 switch (k->type) {
Damien Miller0bc1bd82000-11-13 22:57:25 +110094 case KEY_RSA1:
Damien Miller450a7a12000-03-26 13:04:51 +100095 case KEY_RSA:
Damien Miller4e270b02010-04-16 15:56:21 +100096 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +110097 case KEY_RSA_CERT:
Damien Millerda755162002-01-22 23:09:22 +110098 if ((rsa = RSA_new()) == NULL)
99 fatal("key_new: RSA_new failed");
100 if ((rsa->n = BN_new()) == NULL)
101 fatal("key_new: BN_new failed");
102 if ((rsa->e = BN_new()) == NULL)
103 fatal("key_new: BN_new failed");
Damien Miller450a7a12000-03-26 13:04:51 +1000104 k->rsa = rsa;
105 break;
106 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +1000107 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100108 case KEY_DSA_CERT:
Damien Millerda755162002-01-22 23:09:22 +1100109 if ((dsa = DSA_new()) == NULL)
110 fatal("key_new: DSA_new failed");
111 if ((dsa->p = BN_new()) == NULL)
112 fatal("key_new: BN_new failed");
113 if ((dsa->q = BN_new()) == NULL)
114 fatal("key_new: BN_new failed");
115 if ((dsa->g = BN_new()) == NULL)
116 fatal("key_new: BN_new failed");
117 if ((dsa->pub_key = BN_new()) == NULL)
118 fatal("key_new: BN_new failed");
Damien Miller450a7a12000-03-26 13:04:51 +1000119 k->dsa = dsa;
120 break;
Damien Miller6af914a2010-09-10 11:39:26 +1000121#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000122 case KEY_ECDSA:
123 case KEY_ECDSA_CERT:
124 /* Cannot do anything until we know the group */
125 break;
Damien Miller6af914a2010-09-10 11:39:26 +1000126#endif
Damien Miller5be9d9e2013-12-07 11:24:01 +1100127 case KEY_ED25519:
128 case KEY_ED25519_CERT:
129 /* no need to prealloc */
130 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100131 case KEY_UNSPEC:
Damien Miller450a7a12000-03-26 13:04:51 +1000132 break;
133 default:
134 fatal("key_new: bad key type %d", k->type);
135 break;
136 }
Damien Miller0a80ca12010-02-27 07:55:05 +1100137
138 if (key_is_cert(k))
139 k->cert = cert_new();
140
Damien Miller450a7a12000-03-26 13:04:51 +1000141 return k;
142}
Ben Lindstrom836f0e92002-06-23 21:21:30 +0000143
Damien Miller0a80ca12010-02-27 07:55:05 +1100144void
145key_add_private(Key *k)
Damien Miller0bc1bd82000-11-13 22:57:25 +1100146{
Damien Miller0bc1bd82000-11-13 22:57:25 +1100147 switch (k->type) {
148 case KEY_RSA1:
149 case KEY_RSA:
Damien Miller4e270b02010-04-16 15:56:21 +1000150 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100151 case KEY_RSA_CERT:
Damien Millerda755162002-01-22 23:09:22 +1100152 if ((k->rsa->d = BN_new()) == NULL)
153 fatal("key_new_private: BN_new failed");
154 if ((k->rsa->iqmp = BN_new()) == NULL)
155 fatal("key_new_private: BN_new failed");
156 if ((k->rsa->q = BN_new()) == NULL)
157 fatal("key_new_private: BN_new failed");
158 if ((k->rsa->p = BN_new()) == NULL)
159 fatal("key_new_private: BN_new failed");
160 if ((k->rsa->dmq1 = BN_new()) == NULL)
161 fatal("key_new_private: BN_new failed");
162 if ((k->rsa->dmp1 = BN_new()) == NULL)
163 fatal("key_new_private: BN_new failed");
Damien Miller0bc1bd82000-11-13 22:57:25 +1100164 break;
165 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +1000166 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100167 case KEY_DSA_CERT:
Damien Millerda755162002-01-22 23:09:22 +1100168 if ((k->dsa->priv_key = BN_new()) == NULL)
169 fatal("key_new_private: BN_new failed");
Damien Miller0bc1bd82000-11-13 22:57:25 +1100170 break;
Damien Millereb8b60e2010-08-31 22:41:14 +1000171 case KEY_ECDSA:
172 case KEY_ECDSA_CERT:
173 /* Cannot do anything until we know the group */
174 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +1100175 case KEY_ED25519:
176 case KEY_ED25519_CERT:
177 /* no need to prealloc */
178 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100179 case KEY_UNSPEC:
180 break;
181 default:
182 break;
183 }
Damien Miller0a80ca12010-02-27 07:55:05 +1100184}
185
186Key *
187key_new_private(int type)
188{
189 Key *k = key_new(type);
190
191 key_add_private(k);
Damien Miller0bc1bd82000-11-13 22:57:25 +1100192 return k;
193}
Ben Lindstrom836f0e92002-06-23 21:21:30 +0000194
Damien Miller0a80ca12010-02-27 07:55:05 +1100195static void
196cert_free(struct KeyCert *cert)
197{
198 u_int i;
199
200 buffer_free(&cert->certblob);
Damien Miller4e270b02010-04-16 15:56:21 +1000201 buffer_free(&cert->critical);
202 buffer_free(&cert->extensions);
Darren Tuckera627d422013-06-02 07:31:17 +1000203 free(cert->key_id);
Damien Miller0a80ca12010-02-27 07:55:05 +1100204 for (i = 0; i < cert->nprincipals; i++)
Darren Tuckera627d422013-06-02 07:31:17 +1000205 free(cert->principals[i]);
206 free(cert->principals);
Damien Miller0a80ca12010-02-27 07:55:05 +1100207 if (cert->signature_key != NULL)
208 key_free(cert->signature_key);
Darren Tuckera627d422013-06-02 07:31:17 +1000209 free(cert);
Damien Miller0a80ca12010-02-27 07:55:05 +1100210}
211
Damien Miller450a7a12000-03-26 13:04:51 +1000212void
213key_free(Key *k)
214{
Damien Miller429fcc22006-03-26 14:02:16 +1100215 if (k == NULL)
Damien Millerbbaad772006-03-26 14:03:03 +1100216 fatal("key_free: key is NULL");
Damien Miller450a7a12000-03-26 13:04:51 +1000217 switch (k->type) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100218 case KEY_RSA1:
Damien Miller450a7a12000-03-26 13:04:51 +1000219 case KEY_RSA:
Damien Miller4e270b02010-04-16 15:56:21 +1000220 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100221 case KEY_RSA_CERT:
Damien Miller450a7a12000-03-26 13:04:51 +1000222 if (k->rsa != NULL)
223 RSA_free(k->rsa);
224 k->rsa = NULL;
225 break;
226 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +1000227 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100228 case KEY_DSA_CERT:
Damien Miller450a7a12000-03-26 13:04:51 +1000229 if (k->dsa != NULL)
230 DSA_free(k->dsa);
231 k->dsa = NULL;
232 break;
Damien Miller6af914a2010-09-10 11:39:26 +1000233#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000234 case KEY_ECDSA:
235 case KEY_ECDSA_CERT:
236 if (k->ecdsa != NULL)
237 EC_KEY_free(k->ecdsa);
238 k->ecdsa = NULL;
239 break;
Damien Miller6af914a2010-09-10 11:39:26 +1000240#endif
Damien Miller5be9d9e2013-12-07 11:24:01 +1100241 case KEY_ED25519:
242 case KEY_ED25519_CERT:
243 if (k->ed25519_pk) {
244 memset(k->ed25519_pk, 0, ED25519_PK_SZ);
245 free(k->ed25519_pk);
246 k->ed25519_pk = NULL;
247 }
248 if (k->ed25519_sk) {
249 memset(k->ed25519_sk, 0, ED25519_SK_SZ);
250 free(k->ed25519_sk);
251 k->ed25519_sk = NULL;
252 }
253 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100254 case KEY_UNSPEC:
255 break;
Damien Miller450a7a12000-03-26 13:04:51 +1000256 default:
257 fatal("key_free: bad key type %d", k->type);
258 break;
259 }
Damien Miller0a80ca12010-02-27 07:55:05 +1100260 if (key_is_cert(k)) {
261 if (k->cert != NULL)
262 cert_free(k->cert);
263 k->cert = NULL;
264 }
265
Darren Tuckera627d422013-06-02 07:31:17 +1000266 free(k);
Damien Miller450a7a12000-03-26 13:04:51 +1000267}
Damien Millerf58b58c2003-11-17 21:18:23 +1100268
Damien Miller0a80ca12010-02-27 07:55:05 +1100269static int
270cert_compare(struct KeyCert *a, struct KeyCert *b)
Damien Miller450a7a12000-03-26 13:04:51 +1000271{
Damien Miller0a80ca12010-02-27 07:55:05 +1100272 if (a == NULL && b == NULL)
273 return 1;
274 if (a == NULL || b == NULL)
Damien Miller450a7a12000-03-26 13:04:51 +1000275 return 0;
Damien Miller0a80ca12010-02-27 07:55:05 +1100276 if (buffer_len(&a->certblob) != buffer_len(&b->certblob))
277 return 0;
Damien Millerea1651c2010-07-16 13:58:37 +1000278 if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob),
Damien Miller0a80ca12010-02-27 07:55:05 +1100279 buffer_len(&a->certblob)) != 0)
280 return 0;
281 return 1;
282}
283
284/*
285 * Compare public portions of key only, allowing comparisons between
286 * certificates and plain keys too.
287 */
288int
289key_equal_public(const Key *a, const Key *b)
290{
Darren Tucker8ccb7392010-09-10 12:28:24 +1000291#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000292 BN_CTX *bnctx;
Darren Tucker8ccb7392010-09-10 12:28:24 +1000293#endif
Damien Millereb8b60e2010-08-31 22:41:14 +1000294
Damien Miller0a80ca12010-02-27 07:55:05 +1100295 if (a == NULL || b == NULL ||
296 key_type_plain(a->type) != key_type_plain(b->type))
297 return 0;
298
Damien Miller450a7a12000-03-26 13:04:51 +1000299 switch (a->type) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100300 case KEY_RSA1:
Damien Miller4e270b02010-04-16 15:56:21 +1000301 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100302 case KEY_RSA_CERT:
Damien Miller450a7a12000-03-26 13:04:51 +1000303 case KEY_RSA:
304 return a->rsa != NULL && b->rsa != NULL &&
305 BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
306 BN_cmp(a->rsa->n, b->rsa->n) == 0;
Damien Miller4e270b02010-04-16 15:56:21 +1000307 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100308 case KEY_DSA_CERT:
Damien Miller450a7a12000-03-26 13:04:51 +1000309 case KEY_DSA:
310 return a->dsa != NULL && b->dsa != NULL &&
311 BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
312 BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
313 BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
314 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
Damien Miller6af914a2010-09-10 11:39:26 +1000315#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000316 case KEY_ECDSA_CERT:
317 case KEY_ECDSA:
318 if (a->ecdsa == NULL || b->ecdsa == NULL ||
319 EC_KEY_get0_public_key(a->ecdsa) == NULL ||
320 EC_KEY_get0_public_key(b->ecdsa) == NULL)
321 return 0;
322 if ((bnctx = BN_CTX_new()) == NULL)
323 fatal("%s: BN_CTX_new failed", __func__);
324 if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
325 EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||
326 EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
327 EC_KEY_get0_public_key(a->ecdsa),
328 EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {
329 BN_CTX_free(bnctx);
330 return 0;
331 }
332 BN_CTX_free(bnctx);
333 return 1;
Damien Miller6af914a2010-09-10 11:39:26 +1000334#endif /* OPENSSL_HAS_ECC */
Damien Miller5be9d9e2013-12-07 11:24:01 +1100335 case KEY_ED25519:
336 case KEY_ED25519_CERT:
337 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
338 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
Damien Miller450a7a12000-03-26 13:04:51 +1000339 default:
Damien Millereba71ba2000-04-29 23:57:08 +1000340 fatal("key_equal: bad key type %d", a->type);
Damien Miller450a7a12000-03-26 13:04:51 +1000341 }
Damien Miller87dd5f22008-07-11 17:35:09 +1000342 /* NOTREACHED */
Damien Miller450a7a12000-03-26 13:04:51 +1000343}
344
Damien Miller0a80ca12010-02-27 07:55:05 +1100345int
346key_equal(const Key *a, const Key *b)
347{
348 if (a == NULL || b == NULL || a->type != b->type)
349 return 0;
350 if (key_is_cert(a)) {
351 if (!cert_compare(a->cert, b->cert))
352 return 0;
353 }
354 return key_equal_public(a, b);
355}
356
Damien Miller37876e92003-05-15 10:19:46 +1000357u_char*
Damien Millerf3747bf2013-01-18 11:44:04 +1100358key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
359 u_int *dgst_raw_length)
Damien Miller450a7a12000-03-26 13:04:51 +1000360{
Ben Lindstrom80cb27d2002-03-05 01:33:36 +0000361 const EVP_MD *md = NULL;
Ben Lindstromf0b48532001-03-12 02:59:31 +0000362 EVP_MD_CTX ctx;
Ben Lindstrom46c16222000-12-22 01:43:59 +0000363 u_char *blob = NULL;
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000364 u_char *retval = NULL;
Ben Lindstrom90fd8142002-02-26 18:09:42 +0000365 u_int len = 0;
Damien Millerf3747bf2013-01-18 11:44:04 +1100366 int nlen, elen;
Damien Miller450a7a12000-03-26 13:04:51 +1000367
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000368 *dgst_raw_length = 0;
369
Ben Lindstromf0b48532001-03-12 02:59:31 +0000370 switch (dgst_type) {
371 case SSH_FP_MD5:
372 md = EVP_md5();
373 break;
374 case SSH_FP_SHA1:
375 md = EVP_sha1();
376 break;
Darren Tucker14a9d252012-06-30 20:05:02 +1000377#ifdef HAVE_EVP_SHA256
Damien Miller3bde12a2012-06-20 21:51:11 +1000378 case SSH_FP_SHA256:
379 md = EVP_sha256();
380 break;
Darren Tucker14a9d252012-06-30 20:05:02 +1000381#endif
Ben Lindstromf0b48532001-03-12 02:59:31 +0000382 default:
383 fatal("key_fingerprint_raw: bad digest type %d",
384 dgst_type);
385 }
Damien Miller450a7a12000-03-26 13:04:51 +1000386 switch (k->type) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100387 case KEY_RSA1:
Damien Miller450a7a12000-03-26 13:04:51 +1000388 nlen = BN_num_bytes(k->rsa->n);
389 elen = BN_num_bytes(k->rsa->e);
390 len = nlen + elen;
Damien Millereba71ba2000-04-29 23:57:08 +1000391 blob = xmalloc(len);
392 BN_bn2bin(k->rsa->n, blob);
393 BN_bn2bin(k->rsa->e, blob + nlen);
Damien Miller450a7a12000-03-26 13:04:51 +1000394 break;
395 case KEY_DSA:
Damien Millereb8b60e2010-08-31 22:41:14 +1000396 case KEY_ECDSA:
Damien Miller0bc1bd82000-11-13 22:57:25 +1100397 case KEY_RSA:
Damien Miller5be9d9e2013-12-07 11:24:01 +1100398 case KEY_ED25519:
Damien Miller0bc1bd82000-11-13 22:57:25 +1100399 key_to_blob(k, &blob, &len);
400 break;
Damien Miller4e270b02010-04-16 15:56:21 +1000401 case KEY_DSA_CERT_V00:
402 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100403 case KEY_DSA_CERT:
Damien Millereb8b60e2010-08-31 22:41:14 +1000404 case KEY_ECDSA_CERT:
Damien Miller0a80ca12010-02-27 07:55:05 +1100405 case KEY_RSA_CERT:
Damien Miller5be9d9e2013-12-07 11:24:01 +1100406 case KEY_ED25519_CERT:
Damien Miller0a80ca12010-02-27 07:55:05 +1100407 /* We want a fingerprint of the _key_ not of the cert */
Damien Millerf3747bf2013-01-18 11:44:04 +1100408 to_blob(k, &blob, &len, 1);
Damien Miller0a80ca12010-02-27 07:55:05 +1100409 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100410 case KEY_UNSPEC:
411 return retval;
Damien Miller450a7a12000-03-26 13:04:51 +1000412 default:
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000413 fatal("key_fingerprint_raw: bad key type %d", k->type);
Damien Miller450a7a12000-03-26 13:04:51 +1000414 break;
415 }
Damien Millereba71ba2000-04-29 23:57:08 +1000416 if (blob != NULL) {
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000417 retval = xmalloc(EVP_MAX_MD_SIZE);
Damien Miller6536c7d2000-06-22 21:32:31 +1000418 EVP_DigestInit(&ctx, md);
419 EVP_DigestUpdate(&ctx, blob, len);
Damien Miller3672e4b2002-02-05 11:54:07 +1100420 EVP_DigestFinal(&ctx, retval, dgst_raw_length);
Damien Millereba71ba2000-04-29 23:57:08 +1000421 memset(blob, 0, len);
Darren Tuckera627d422013-06-02 07:31:17 +1000422 free(blob);
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000423 } else {
424 fatal("key_fingerprint_raw: blob is null");
Damien Miller450a7a12000-03-26 13:04:51 +1000425 }
426 return retval;
427}
428
Ben Lindstroma962c2f2002-07-04 00:14:17 +0000429static char *
430key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000431{
432 char *retval;
Damien Millereccb9de2005-06-17 12:59:34 +1000433 u_int i;
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000434
Damien Miller07d86be2006-03-26 14:19:21 +1100435 retval = xcalloc(1, dgst_raw_len * 3 + 1);
Damien Miller9f0f5c62001-12-21 14:45:46 +1100436 for (i = 0; i < dgst_raw_len; i++) {
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000437 char hex[4];
438 snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
Darren Tucker29588612003-07-14 17:28:34 +1000439 strlcat(retval, hex, dgst_raw_len * 3 + 1);
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000440 }
Darren Tucker29588612003-07-14 17:28:34 +1000441
442 /* Remove the trailing ':' character */
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000443 retval[(dgst_raw_len * 3) - 1] = '\0';
444 return retval;
445}
446
Ben Lindstroma962c2f2002-07-04 00:14:17 +0000447static char *
448key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000449{
450 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
451 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
452 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000453 u_int i, j = 0, rounds, seed = 1;
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000454 char *retval;
455
456 rounds = (dgst_raw_len / 2) + 1;
Damien Miller07d86be2006-03-26 14:19:21 +1100457 retval = xcalloc((rounds * 6), sizeof(char));
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000458 retval[j++] = 'x';
459 for (i = 0; i < rounds; i++) {
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000460 u_int idx0, idx1, idx2, idx3, idx4;
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000461 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
462 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000463 seed) % 6;
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000464 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
465 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000466 (seed / 6)) % 6;
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000467 retval[j++] = vowels[idx0];
468 retval[j++] = consonants[idx1];
469 retval[j++] = vowels[idx2];
470 if ((i + 1) < rounds) {
471 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
472 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
473 retval[j++] = consonants[idx3];
474 retval[j++] = '-';
475 retval[j++] = consonants[idx4];
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000476 seed = ((seed * 5) +
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000477 ((((u_int)(dgst_raw[2 * i])) * 7) +
478 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000479 }
480 } else {
481 idx0 = seed % 6;
482 idx1 = 16;
483 idx2 = seed / 6;
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000484 retval[j++] = vowels[idx0];
485 retval[j++] = consonants[idx1];
486 retval[j++] = vowels[idx2];
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000487 }
488 }
Ben Lindstromcbe3ad22001-03-11 20:06:59 +0000489 retval[j++] = 'x';
490 retval[j++] = '\0';
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000491 return retval;
492}
493
Darren Tucker9c16ac92008-06-13 04:40:35 +1000494/*
495 * Draw an ASCII-Art representing the fingerprint so human brain can
496 * profit from its built-in pattern recognition ability.
497 * This technique is called "random art" and can be found in some
498 * scientific publications like this original paper:
499 *
500 * "Hash Visualization: a New Technique to improve Real-World Security",
501 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
502 * Techniques and E-Commerce (CrypTEC '99)
503 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
504 *
505 * The subject came up in a talk by Dan Kaminsky, too.
506 *
507 * If you see the picture is different, the key is different.
508 * If the picture looks the same, you still know nothing.
509 *
510 * The algorithm used here is a worm crawling over a discrete plane,
511 * leaving a trace (augmenting the field) everywhere it goes.
512 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
513 * makes the respective movement vector be ignored for this turn.
514 * Graphs are not unambiguous, because circles in graphs can be
515 * walked in either direction.
516 */
Darren Tucker987ac842008-06-13 04:54:40 +1000517
518/*
519 * Field sizes for the random art. Have to be odd, so the starting point
520 * can be in the exact middle of the picture, and FLDBASE should be >=8 .
521 * Else pictures would be too dense, and drawing the frame would
522 * fail, too, because the key type would not fit in anymore.
523 */
524#define FLDBASE 8
525#define FLDSIZE_Y (FLDBASE + 1)
526#define FLDSIZE_X (FLDBASE * 2 + 1)
Darren Tucker9c16ac92008-06-13 04:40:35 +1000527static char *
Darren Tucker987ac842008-06-13 04:54:40 +1000528key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
Darren Tucker9c16ac92008-06-13 04:40:35 +1000529{
530 /*
531 * Chars to be used after each other every time the worm
532 * intersects with itself. Matter of taste.
533 */
Darren Tucker4b3b9772008-06-13 04:55:10 +1000534 char *augmentation_string = " .o+=*BOX@%&#/^SE";
Darren Tucker9c16ac92008-06-13 04:40:35 +1000535 char *retval, *p;
Darren Tucker014d76f2008-06-13 04:43:51 +1000536 u_char field[FLDSIZE_X][FLDSIZE_Y];
Darren Tucker9c16ac92008-06-13 04:40:35 +1000537 u_int i, b;
538 int x, y;
Darren Tuckerd32b28a2008-06-13 04:45:50 +1000539 size_t len = strlen(augmentation_string) - 1;
Darren Tucker9c16ac92008-06-13 04:40:35 +1000540
541 retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
542
543 /* initialize field */
Darren Tucker014d76f2008-06-13 04:43:51 +1000544 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
Darren Tucker9c16ac92008-06-13 04:40:35 +1000545 x = FLDSIZE_X / 2;
546 y = FLDSIZE_Y / 2;
Darren Tucker9c16ac92008-06-13 04:40:35 +1000547
548 /* process raw key */
549 for (i = 0; i < dgst_raw_len; i++) {
550 int input;
551 /* each byte conveys four 2-bit move commands */
552 input = dgst_raw[i];
553 for (b = 0; b < 4; b++) {
554 /* evaluate 2 bit, rest is shifted later */
555 x += (input & 0x1) ? 1 : -1;
556 y += (input & 0x2) ? 1 : -1;
557
558 /* assure we are still in bounds */
559 x = MAX(x, 0);
560 y = MAX(y, 0);
561 x = MIN(x, FLDSIZE_X - 1);
562 y = MIN(y, FLDSIZE_Y - 1);
563
564 /* augment the field */
Damien Millerc6aadd92008-11-03 19:16:20 +1100565 if (field[x][y] < len - 2)
566 field[x][y]++;
Darren Tucker9c16ac92008-06-13 04:40:35 +1000567 input = input >> 2;
568 }
569 }
Darren Tucker4b3b9772008-06-13 04:55:10 +1000570
571 /* mark starting point and end point*/
572 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
573 field[x][y] = len;
Darren Tucker9c16ac92008-06-13 04:40:35 +1000574
575 /* fill in retval */
Damien Miller007132a2008-06-29 22:45:37 +1000576 snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k));
Darren Tucker987ac842008-06-13 04:54:40 +1000577 p = strchr(retval, '\0');
Darren Tucker9c16ac92008-06-13 04:40:35 +1000578
579 /* output upper border */
Damien Miller007132a2008-06-29 22:45:37 +1000580 for (i = p - retval - 1; i < FLDSIZE_X; i++)
Darren Tucker9c16ac92008-06-13 04:40:35 +1000581 *p++ = '-';
582 *p++ = '+';
583 *p++ = '\n';
584
585 /* output content */
586 for (y = 0; y < FLDSIZE_Y; y++) {
587 *p++ = '|';
588 for (x = 0; x < FLDSIZE_X; x++)
Darren Tuckerd32b28a2008-06-13 04:45:50 +1000589 *p++ = augmentation_string[MIN(field[x][y], len)];
Darren Tucker9c16ac92008-06-13 04:40:35 +1000590 *p++ = '|';
591 *p++ = '\n';
592 }
593
594 /* output lower border */
595 *p++ = '+';
596 for (i = 0; i < FLDSIZE_X; i++)
597 *p++ = '-';
598 *p++ = '+';
599
600 return retval;
601}
602
Ben Lindstroma962c2f2002-07-04 00:14:17 +0000603char *
Darren Tucker0acca372013-06-02 07:41:51 +1000604key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000605{
Ben Lindstroma3700052001-04-05 23:26:32 +0000606 char *retval = NULL;
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000607 u_char *dgst_raw;
Damien Miller3672e4b2002-02-05 11:54:07 +1100608 u_int dgst_raw_len;
Damien Miller9f0f5c62001-12-21 14:45:46 +1100609
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000610 dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
611 if (!dgst_raw)
Ben Lindstromcfccef92001-03-13 04:57:58 +0000612 fatal("key_fingerprint: null from key_fingerprint_raw()");
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +0000613 switch (dgst_rep) {
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000614 case SSH_FP_HEX:
615 retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
616 break;
617 case SSH_FP_BUBBLEBABBLE:
618 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
619 break;
Darren Tucker9c16ac92008-06-13 04:40:35 +1000620 case SSH_FP_RANDOMART:
Darren Tucker987ac842008-06-13 04:54:40 +1000621 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k);
Darren Tucker9c16ac92008-06-13 04:40:35 +1000622 break;
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000623 default:
Damien Miller2f54ada2008-11-03 19:24:16 +1100624 fatal("key_fingerprint: bad digest representation %d",
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000625 dgst_rep);
626 break;
627 }
628 memset(dgst_raw, 0, dgst_raw_len);
Darren Tuckera627d422013-06-02 07:31:17 +1000629 free(dgst_raw);
Ben Lindstrom96e8ea62001-03-11 20:03:44 +0000630 return retval;
631}
632
Damien Miller450a7a12000-03-26 13:04:51 +1000633/*
634 * Reads a multiple-precision integer in decimal from the buffer, and advances
635 * the pointer. The integer must already be initialized. This function is
636 * permitted to modify the buffer. This leaves *cpp to point just beyond the
637 * last processed (and maybe modified) character. Note that this may modify
638 * the buffer containing the number.
639 */
Ben Lindstrombba81212001-06-25 05:01:22 +0000640static int
Damien Miller450a7a12000-03-26 13:04:51 +1000641read_bignum(char **cpp, BIGNUM * value)
642{
643 char *cp = *cpp;
644 int old;
645
646 /* Skip any leading whitespace. */
647 for (; *cp == ' ' || *cp == '\t'; cp++)
648 ;
649
650 /* Check that it begins with a decimal digit. */
651 if (*cp < '0' || *cp > '9')
652 return 0;
653
654 /* Save starting position. */
655 *cpp = cp;
656
657 /* Move forward until all decimal digits skipped. */
658 for (; *cp >= '0' && *cp <= '9'; cp++)
659 ;
660
661 /* Save the old terminating character, and replace it by \0. */
662 old = *cp;
663 *cp = 0;
664
665 /* Parse the number. */
666 if (BN_dec2bn(&value, *cpp) == 0)
667 return 0;
668
669 /* Restore old terminating character. */
670 *cp = old;
671
672 /* Move beyond the number and return success. */
673 *cpp = cp;
674 return 1;
675}
Ben Lindstrom836f0e92002-06-23 21:21:30 +0000676
Ben Lindstrombba81212001-06-25 05:01:22 +0000677static int
Damien Miller450a7a12000-03-26 13:04:51 +1000678write_bignum(FILE *f, BIGNUM *num)
679{
680 char *buf = BN_bn2dec(num);
681 if (buf == NULL) {
682 error("write_bignum: BN_bn2dec() failed");
683 return 0;
684 }
685 fprintf(f, " %s", buf);
Damien Milleraf3030f2001-10-10 15:00:49 +1000686 OPENSSL_free(buf);
Damien Miller450a7a12000-03-26 13:04:51 +1000687 return 1;
688}
Damien Miller0bc1bd82000-11-13 22:57:25 +1100689
Ben Lindstrom309f3d12001-09-20 00:55:53 +0000690/* returns 1 ok, -1 error */
Damien Miller0bc1bd82000-11-13 22:57:25 +1100691int
Damien Millereba71ba2000-04-29 23:57:08 +1000692key_read(Key *ret, char **cpp)
Damien Miller450a7a12000-03-26 13:04:51 +1000693{
Damien Millereba71ba2000-04-29 23:57:08 +1000694 Key *k;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100695 int success = -1;
696 char *cp, *space;
Darren Tucker8ccb7392010-09-10 12:28:24 +1000697 int len, n, type;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100698 u_int bits;
Ben Lindstrom46c16222000-12-22 01:43:59 +0000699 u_char *blob;
Darren Tucker8ccb7392010-09-10 12:28:24 +1000700#ifdef OPENSSL_HAS_ECC
701 int curve_nid = -1;
702#endif
Damien Millereba71ba2000-04-29 23:57:08 +1000703
704 cp = *cpp;
705
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +0000706 switch (ret->type) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100707 case KEY_RSA1:
Damien Millereba71ba2000-04-29 23:57:08 +1000708 /* Get number of bits. */
709 if (*cp < '0' || *cp > '9')
Damien Miller0bc1bd82000-11-13 22:57:25 +1100710 return -1; /* Bad bit count... */
Damien Millereba71ba2000-04-29 23:57:08 +1000711 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
712 bits = 10 * bits + *cp - '0';
Damien Miller450a7a12000-03-26 13:04:51 +1000713 if (bits == 0)
Damien Miller0bc1bd82000-11-13 22:57:25 +1100714 return -1;
Damien Millereba71ba2000-04-29 23:57:08 +1000715 *cpp = cp;
Damien Miller450a7a12000-03-26 13:04:51 +1000716 /* Get public exponent, public modulus. */
717 if (!read_bignum(cpp, ret->rsa->e))
Damien Miller0bc1bd82000-11-13 22:57:25 +1100718 return -1;
Damien Miller450a7a12000-03-26 13:04:51 +1000719 if (!read_bignum(cpp, ret->rsa->n))
Damien Miller0bc1bd82000-11-13 22:57:25 +1100720 return -1;
Darren Tucker561724f2010-01-13 22:43:05 +1100721 /* validate the claimed number of bits */
722 if ((u_int)BN_num_bits(ret->rsa->n) != bits) {
723 verbose("key_read: claimed key size %d does not match "
724 "actual %d", bits, BN_num_bits(ret->rsa->n));
725 return -1;
726 }
Damien Miller0bc1bd82000-11-13 22:57:25 +1100727 success = 1;
Damien Miller450a7a12000-03-26 13:04:51 +1000728 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100729 case KEY_UNSPEC:
730 case KEY_RSA:
Damien Miller450a7a12000-03-26 13:04:51 +1000731 case KEY_DSA:
Damien Millereb8b60e2010-08-31 22:41:14 +1000732 case KEY_ECDSA:
Damien Miller5be9d9e2013-12-07 11:24:01 +1100733 case KEY_ED25519:
Damien Miller4e270b02010-04-16 15:56:21 +1000734 case KEY_DSA_CERT_V00:
735 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100736 case KEY_DSA_CERT:
Damien Millereb8b60e2010-08-31 22:41:14 +1000737 case KEY_ECDSA_CERT:
Damien Miller0a80ca12010-02-27 07:55:05 +1100738 case KEY_RSA_CERT:
Damien Miller5be9d9e2013-12-07 11:24:01 +1100739 case KEY_ED25519_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +1100740 space = strchr(cp, ' ');
741 if (space == NULL) {
Damien Miller386f1f32003-02-24 11:54:57 +1100742 debug3("key_read: missing whitespace");
Damien Miller0bc1bd82000-11-13 22:57:25 +1100743 return -1;
744 }
745 *space = '\0';
746 type = key_type_from_name(cp);
Damien Miller6af914a2010-09-10 11:39:26 +1000747#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000748 if (key_type_plain(type) == KEY_ECDSA &&
749 (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) {
750 debug("key_read: invalid curve");
751 return -1;
752 }
Damien Miller6af914a2010-09-10 11:39:26 +1000753#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +1100754 *space = ' ';
755 if (type == KEY_UNSPEC) {
Damien Miller386f1f32003-02-24 11:54:57 +1100756 debug3("key_read: missing keytype");
Damien Miller0bc1bd82000-11-13 22:57:25 +1100757 return -1;
758 }
759 cp = space+1;
760 if (*cp == '\0') {
761 debug3("key_read: short string");
762 return -1;
763 }
764 if (ret->type == KEY_UNSPEC) {
765 ret->type = type;
766 } else if (ret->type != type) {
767 /* is a key, but different type */
768 debug3("key_read: type mismatch");
Ben Lindstrom309f3d12001-09-20 00:55:53 +0000769 return -1;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100770 }
Damien Millereba71ba2000-04-29 23:57:08 +1000771 len = 2*strlen(cp);
772 blob = xmalloc(len);
773 n = uudecode(cp, blob, len);
Damien Millere247cc42000-05-07 12:03:14 +1000774 if (n < 0) {
Damien Millerb1715dc2000-05-30 13:44:51 +1000775 error("key_read: uudecode %s failed", cp);
Darren Tuckera627d422013-06-02 07:31:17 +1000776 free(blob);
Damien Miller0bc1bd82000-11-13 22:57:25 +1100777 return -1;
Damien Millere247cc42000-05-07 12:03:14 +1000778 }
Darren Tucker502d3842003-06-28 12:38:01 +1000779 k = key_from_blob(blob, (u_int)n);
Darren Tuckera627d422013-06-02 07:31:17 +1000780 free(blob);
Damien Millerb1715dc2000-05-30 13:44:51 +1000781 if (k == NULL) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100782 error("key_read: key_from_blob %s failed", cp);
783 return -1;
Damien Millerb1715dc2000-05-30 13:44:51 +1000784 }
Damien Miller0bc1bd82000-11-13 22:57:25 +1100785 if (k->type != type) {
786 error("key_read: type mismatch: encoding error");
787 key_free(k);
788 return -1;
789 }
Damien Miller6af914a2010-09-10 11:39:26 +1000790#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000791 if (key_type_plain(type) == KEY_ECDSA &&
792 curve_nid != k->ecdsa_nid) {
793 error("key_read: type mismatch: EC curve mismatch");
794 key_free(k);
795 return -1;
796 }
Damien Miller6af914a2010-09-10 11:39:26 +1000797#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +1100798/*XXXX*/
Damien Miller0a80ca12010-02-27 07:55:05 +1100799 if (key_is_cert(ret)) {
800 if (!key_is_cert(k)) {
801 error("key_read: loaded key is not a cert");
802 key_free(k);
803 return -1;
804 }
805 if (ret->cert != NULL)
806 cert_free(ret->cert);
807 ret->cert = k->cert;
808 k->cert = NULL;
809 }
810 if (key_type_plain(ret->type) == KEY_RSA) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100811 if (ret->rsa != NULL)
812 RSA_free(ret->rsa);
813 ret->rsa = k->rsa;
814 k->rsa = NULL;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100815#ifdef DEBUG_PK
816 RSA_print_fp(stderr, ret->rsa, 8);
817#endif
Damien Miller0a80ca12010-02-27 07:55:05 +1100818 }
819 if (key_type_plain(ret->type) == KEY_DSA) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100820 if (ret->dsa != NULL)
821 DSA_free(ret->dsa);
822 ret->dsa = k->dsa;
823 k->dsa = NULL;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100824#ifdef DEBUG_PK
825 DSA_print_fp(stderr, ret->dsa, 8);
826#endif
827 }
Damien Miller6af914a2010-09-10 11:39:26 +1000828#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000829 if (key_type_plain(ret->type) == KEY_ECDSA) {
830 if (ret->ecdsa != NULL)
831 EC_KEY_free(ret->ecdsa);
832 ret->ecdsa = k->ecdsa;
833 ret->ecdsa_nid = k->ecdsa_nid;
834 k->ecdsa = NULL;
835 k->ecdsa_nid = -1;
836#ifdef DEBUG_PK
837 key_dump_ec_key(ret->ecdsa);
838#endif
839 }
Damien Miller6af914a2010-09-10 11:39:26 +1000840#endif
Damien Miller5be9d9e2013-12-07 11:24:01 +1100841 if (key_type_plain(ret->type) == KEY_ED25519) {
842 free(ret->ed25519_pk);
843 ret->ed25519_pk = k->ed25519_pk;
844 k->ed25519_pk = NULL;
845#ifdef DEBUG_PK
846 /* XXX */
847#endif
848 }
Damien Miller0a80ca12010-02-27 07:55:05 +1100849 success = 1;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100850/*XXXX*/
Ben Lindstrom4cbc1812001-12-06 16:41:41 +0000851 key_free(k);
Damien Miller0bc1bd82000-11-13 22:57:25 +1100852 if (success != 1)
853 break;
Damien Millerb1715dc2000-05-30 13:44:51 +1000854 /* advance cp: skip whitespace and data */
855 while (*cp == ' ' || *cp == '\t')
856 cp++;
857 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
858 cp++;
859 *cpp = cp;
Damien Miller450a7a12000-03-26 13:04:51 +1000860 break;
861 default:
Damien Millereba71ba2000-04-29 23:57:08 +1000862 fatal("key_read: bad key type: %d", ret->type);
Damien Miller450a7a12000-03-26 13:04:51 +1000863 break;
864 }
Damien Miller0bc1bd82000-11-13 22:57:25 +1100865 return success;
Damien Miller450a7a12000-03-26 13:04:51 +1000866}
Ben Lindstrom836f0e92002-06-23 21:21:30 +0000867
Damien Miller450a7a12000-03-26 13:04:51 +1000868int
Damien Millerf58b58c2003-11-17 21:18:23 +1100869key_write(const Key *key, FILE *f)
Damien Miller450a7a12000-03-26 13:04:51 +1000870{
Ben Lindstrom90fd8142002-02-26 18:09:42 +0000871 int n, success = 0;
872 u_int len, bits = 0;
Damien Millera10f5612002-09-12 09:49:15 +1000873 u_char *blob;
874 char *uu;
Damien Miller450a7a12000-03-26 13:04:51 +1000875
Damien Miller0a80ca12010-02-27 07:55:05 +1100876 if (key_is_cert(key)) {
877 if (key->cert == NULL) {
878 error("%s: no cert data", __func__);
879 return 0;
880 }
881 if (buffer_len(&key->cert->certblob) == 0) {
882 error("%s: no signed certificate blob", __func__);
883 return 0;
884 }
885 }
886
887 switch (key->type) {
888 case KEY_RSA1:
889 if (key->rsa == NULL)
890 return 0;
Damien Miller450a7a12000-03-26 13:04:51 +1000891 /* size of modulus 'n' */
892 bits = BN_num_bits(key->rsa->n);
893 fprintf(f, "%u", bits);
894 if (write_bignum(f, key->rsa->e) &&
Damien Miller0a80ca12010-02-27 07:55:05 +1100895 write_bignum(f, key->rsa->n))
896 return 1;
897 error("key_write: failed for RSA key");
898 return 0;
899 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +1000900 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100901 case KEY_DSA_CERT:
902 if (key->dsa == NULL)
903 return 0;
904 break;
Damien Miller6af914a2010-09-10 11:39:26 +1000905#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +1000906 case KEY_ECDSA:
907 case KEY_ECDSA_CERT:
908 if (key->ecdsa == NULL)
909 return 0;
910 break;
Damien Miller6af914a2010-09-10 11:39:26 +1000911#endif
Damien Miller5be9d9e2013-12-07 11:24:01 +1100912 case KEY_ED25519:
913 case KEY_ED25519_CERT:
914 if (key->ed25519_pk == NULL)
915 return 0;
916 break;
Damien Miller0a80ca12010-02-27 07:55:05 +1100917 case KEY_RSA:
Damien Miller4e270b02010-04-16 15:56:21 +1000918 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +1100919 case KEY_RSA_CERT:
920 if (key->rsa == NULL)
921 return 0;
922 break;
923 default:
924 return 0;
Damien Miller450a7a12000-03-26 13:04:51 +1000925 }
Damien Miller0a80ca12010-02-27 07:55:05 +1100926
927 key_to_blob(key, &blob, &len);
928 uu = xmalloc(2*len);
929 n = uuencode(blob, len, uu, 2*len);
930 if (n > 0) {
931 fprintf(f, "%s %s", key_ssh_name(key), uu);
932 success = 1;
933 }
Darren Tuckera627d422013-06-02 07:31:17 +1000934 free(blob);
935 free(uu);
Damien Miller0a80ca12010-02-27 07:55:05 +1100936
Damien Miller450a7a12000-03-26 13:04:51 +1000937 return success;
938}
Ben Lindstrom836f0e92002-06-23 21:21:30 +0000939
Damien Millerf58b58c2003-11-17 21:18:23 +1100940const char *
Damien Miller1cfbfaf2010-03-22 05:58:24 +1100941key_cert_type(const Key *k)
942{
943 switch (k->cert->type) {
944 case SSH2_CERT_TYPE_USER:
945 return "user";
946 case SSH2_CERT_TYPE_HOST:
947 return "host";
948 default:
949 return "unknown";
950 }
951}
952
Damien Millerea111192013-04-23 19:24:32 +1000953struct keytype {
954 char *name;
955 char *shortname;
956 int type;
957 int nid;
958 int cert;
959};
960static const struct keytype keytypes[] = {
961 { NULL, "RSA1", KEY_RSA1, 0, 0 },
962 { "ssh-rsa", "RSA", KEY_RSA, 0, 0 },
963 { "ssh-dss", "DSA", KEY_DSA, 0, 0 },
Damien Miller5be9d9e2013-12-07 11:24:01 +1100964 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 },
Damien Millerea111192013-04-23 19:24:32 +1000965#ifdef OPENSSL_HAS_ECC
966 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 },
967 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 },
Darren Tucker37bcef52013-11-09 18:39:25 +1100968# ifdef OPENSSL_HAS_NISTP521
Damien Millerea111192013-04-23 19:24:32 +1000969 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 },
Darren Tucker37bcef52013-11-09 18:39:25 +1100970# endif
Damien Millerea111192013-04-23 19:24:32 +1000971#endif /* OPENSSL_HAS_ECC */
972 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 },
973 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 },
974#ifdef OPENSSL_HAS_ECC
975 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
976 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 },
977 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
978 KEY_ECDSA_CERT, NID_secp384r1, 1 },
Darren Tucker37bcef52013-11-09 18:39:25 +1100979# ifdef OPENSSL_HAS_NISTP521
Damien Millerea111192013-04-23 19:24:32 +1000980 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
981 KEY_ECDSA_CERT, NID_secp521r1, 1 },
Darren Tucker37bcef52013-11-09 18:39:25 +1100982# endif
Damien Millerea111192013-04-23 19:24:32 +1000983#endif /* OPENSSL_HAS_ECC */
984 { "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00",
985 KEY_RSA_CERT_V00, 0, 1 },
986 { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00",
987 KEY_DSA_CERT_V00, 0, 1 },
Damien Miller5be9d9e2013-12-07 11:24:01 +1100988 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
989 KEY_ED25519_CERT, 0, 1 },
Damien Millerea111192013-04-23 19:24:32 +1000990 { NULL, NULL, -1, -1, 0 }
991};
992
993const char *
994key_type(const Key *k)
995{
996 const struct keytype *kt;
997
998 for (kt = keytypes; kt->type != -1; kt++) {
999 if (kt->type == k->type)
1000 return kt->shortname;
1001 }
1002 return "unknown";
1003}
1004
Damien Millereb8b60e2010-08-31 22:41:14 +10001005static const char *
1006key_ssh_name_from_type_nid(int type, int nid)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001007{
Damien Millerea111192013-04-23 19:24:32 +10001008 const struct keytype *kt;
1009
1010 for (kt = keytypes; kt->type != -1; kt++) {
1011 if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
1012 return kt->name;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001013 }
1014 return "ssh-unknown";
1015}
Ben Lindstrom836f0e92002-06-23 21:21:30 +00001016
Damien Millereb8b60e2010-08-31 22:41:14 +10001017const char *
1018key_ssh_name(const Key *k)
1019{
1020 return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
1021}
1022
1023const char *
1024key_ssh_name_plain(const Key *k)
1025{
1026 return key_ssh_name_from_type_nid(key_type_plain(k->type),
1027 k->ecdsa_nid);
1028}
1029
Damien Millerea111192013-04-23 19:24:32 +10001030int
1031key_type_from_name(char *name)
1032{
1033 const struct keytype *kt;
1034
1035 for (kt = keytypes; kt->type != -1; kt++) {
1036 /* Only allow shortname matches for plain key types */
1037 if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
1038 (!kt->cert && strcasecmp(kt->shortname, name) == 0))
1039 return kt->type;
1040 }
1041 debug2("key_type_from_name: unknown key type '%s'", name);
1042 return KEY_UNSPEC;
1043}
1044
1045int
1046key_ecdsa_nid_from_name(const char *name)
1047{
1048 const struct keytype *kt;
1049
1050 for (kt = keytypes; kt->type != -1; kt++) {
1051 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
1052 continue;
1053 if (kt->name != NULL && strcmp(name, kt->name) == 0)
1054 return kt->nid;
1055 }
1056 debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name);
1057 return -1;
1058}
1059
1060char *
Damien Miller5be9d9e2013-12-07 11:24:01 +11001061key_alg_list(int certs_only, int plain_only)
Damien Millerea111192013-04-23 19:24:32 +10001062{
1063 char *ret = NULL;
1064 size_t nlen, rlen = 0;
1065 const struct keytype *kt;
1066
1067 for (kt = keytypes; kt->type != -1; kt++) {
1068 if (kt->name == NULL)
1069 continue;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001070 if ((certs_only && !kt->cert) || (plain_only && kt->cert))
1071 continue;
Damien Millerea111192013-04-23 19:24:32 +10001072 if (ret != NULL)
1073 ret[rlen++] = '\n';
1074 nlen = strlen(kt->name);
1075 ret = xrealloc(ret, 1, rlen + nlen + 2);
1076 memcpy(ret + rlen, kt->name, nlen + 1);
1077 rlen += nlen;
1078 }
1079 return ret;
1080}
1081
Damien Miller4a3a9d42013-10-30 22:19:47 +11001082int
1083key_type_is_cert(int type)
1084{
1085 const struct keytype *kt;
1086
1087 for (kt = keytypes; kt->type != -1; kt++) {
1088 if (kt->type == type)
1089 return kt->cert;
1090 }
1091 return 0;
1092}
1093
Damien Miller0bc1bd82000-11-13 22:57:25 +11001094u_int
Damien Millerf58b58c2003-11-17 21:18:23 +11001095key_size(const Key *k)
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001096{
Damien Millerad833b32000-08-23 10:46:23 +10001097 switch (k->type) {
Damien Miller0bc1bd82000-11-13 22:57:25 +11001098 case KEY_RSA1:
Damien Millerad833b32000-08-23 10:46:23 +10001099 case KEY_RSA:
Damien Miller4e270b02010-04-16 15:56:21 +10001100 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001101 case KEY_RSA_CERT:
Damien Millerad833b32000-08-23 10:46:23 +10001102 return BN_num_bits(k->rsa->n);
Damien Millerad833b32000-08-23 10:46:23 +10001103 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +10001104 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001105 case KEY_DSA_CERT:
Damien Millerad833b32000-08-23 10:46:23 +10001106 return BN_num_bits(k->dsa->p);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001107 case KEY_ED25519:
1108 return 256; /* XXX */
Damien Miller6af914a2010-09-10 11:39:26 +10001109#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001110 case KEY_ECDSA:
1111 case KEY_ECDSA_CERT:
Damien Miller041ab7c2010-09-10 11:23:34 +10001112 return key_curve_nid_to_bits(k->ecdsa_nid);
Damien Miller6af914a2010-09-10 11:39:26 +10001113#endif
Damien Millerad833b32000-08-23 10:46:23 +10001114 }
1115 return 0;
1116}
Damien Miller0bc1bd82000-11-13 22:57:25 +11001117
Ben Lindstrombba81212001-06-25 05:01:22 +00001118static RSA *
Ben Lindstrom46c16222000-12-22 01:43:59 +00001119rsa_generate_private_key(u_int bits)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001120{
Damien Miller4499f4c2010-11-20 15:15:49 +11001121 RSA *private = RSA_new();
1122 BIGNUM *f4 = BN_new();
Damien Miller69b72032006-03-26 14:02:35 +11001123
Kevin Stevesef4eea92001-02-05 12:42:17 +00001124 if (private == NULL)
Damien Miller4499f4c2010-11-20 15:15:49 +11001125 fatal("%s: RSA_new failed", __func__);
1126 if (f4 == NULL)
1127 fatal("%s: BN_new failed", __func__);
1128 if (!BN_set_word(f4, RSA_F4))
1129 fatal("%s: BN_new failed", __func__);
1130 if (!RSA_generate_key_ex(private, bits, f4, NULL))
1131 fatal("%s: key generation failed.", __func__);
1132 BN_free(f4);
Kevin Stevesef4eea92001-02-05 12:42:17 +00001133 return private;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001134}
1135
Ben Lindstrombba81212001-06-25 05:01:22 +00001136static DSA*
Ben Lindstrom46c16222000-12-22 01:43:59 +00001137dsa_generate_private_key(u_int bits)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001138{
Damien Miller4499f4c2010-11-20 15:15:49 +11001139 DSA *private = DSA_new();
Damien Miller69b72032006-03-26 14:02:35 +11001140
Damien Miller0bc1bd82000-11-13 22:57:25 +11001141 if (private == NULL)
Damien Miller4499f4c2010-11-20 15:15:49 +11001142 fatal("%s: DSA_new failed", __func__);
1143 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
1144 NULL, NULL))
1145 fatal("%s: DSA_generate_parameters failed", __func__);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001146 if (!DSA_generate_key(private))
Damien Miller4499f4c2010-11-20 15:15:49 +11001147 fatal("%s: DSA_generate_key failed.", __func__);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001148 return private;
1149}
1150
Damien Millereb8b60e2010-08-31 22:41:14 +10001151int
1152key_ecdsa_bits_to_nid(int bits)
1153{
1154 switch (bits) {
Damien Miller6af914a2010-09-10 11:39:26 +10001155#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001156 case 256:
1157 return NID_X9_62_prime256v1;
1158 case 384:
1159 return NID_secp384r1;
Darren Tucker2c894302013-11-10 12:38:42 +11001160# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10001161 case 521:
1162 return NID_secp521r1;
Darren Tucker37bcef52013-11-09 18:39:25 +11001163# endif
Damien Miller6af914a2010-09-10 11:39:26 +10001164#endif
Damien Millereb8b60e2010-08-31 22:41:14 +10001165 default:
1166 return -1;
1167 }
1168}
1169
Damien Miller6af914a2010-09-10 11:39:26 +10001170#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001171int
Damien Millerb472a902010-11-05 10:19:49 +11001172key_ecdsa_key_to_nid(EC_KEY *k)
Damien Millereb8b60e2010-08-31 22:41:14 +10001173{
1174 EC_GROUP *eg;
1175 int nids[] = {
1176 NID_X9_62_prime256v1,
1177 NID_secp384r1,
Darren Tucker37bcef52013-11-09 18:39:25 +11001178# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10001179 NID_secp521r1,
Darren Tucker37bcef52013-11-09 18:39:25 +11001180# endif
Damien Millereb8b60e2010-08-31 22:41:14 +10001181 -1
1182 };
Damien Millerb472a902010-11-05 10:19:49 +11001183 int nid;
Damien Millereb8b60e2010-08-31 22:41:14 +10001184 u_int i;
1185 BN_CTX *bnctx;
Damien Millerb472a902010-11-05 10:19:49 +11001186 const EC_GROUP *g = EC_KEY_get0_group(k);
Damien Millereb8b60e2010-08-31 22:41:14 +10001187
Damien Millerb472a902010-11-05 10:19:49 +11001188 /*
1189 * The group may be stored in a ASN.1 encoded private key in one of two
1190 * ways: as a "named group", which is reconstituted by ASN.1 object ID
1191 * or explicit group parameters encoded into the key blob. Only the
1192 * "named group" case sets the group NID for us, but we can figure
1193 * it out for the other case by comparing against all the groups that
1194 * are supported.
1195 */
1196 if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1197 return nid;
Damien Millereb8b60e2010-08-31 22:41:14 +10001198 if ((bnctx = BN_CTX_new()) == NULL)
1199 fatal("%s: BN_CTX_new() failed", __func__);
1200 for (i = 0; nids[i] != -1; i++) {
1201 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
1202 fatal("%s: EC_GROUP_new_by_curve_name failed",
1203 __func__);
Damien Millerb472a902010-11-05 10:19:49 +11001204 if (EC_GROUP_cmp(g, eg, bnctx) == 0)
Damien Millereb8b60e2010-08-31 22:41:14 +10001205 break;
Damien Millereb8b60e2010-08-31 22:41:14 +10001206 EC_GROUP_free(eg);
1207 }
1208 BN_CTX_free(bnctx);
1209 debug3("%s: nid = %d", __func__, nids[i]);
Damien Millerb472a902010-11-05 10:19:49 +11001210 if (nids[i] != -1) {
1211 /* Use the group with the NID attached */
1212 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1213 if (EC_KEY_set_group(k, eg) != 1)
1214 fatal("%s: EC_KEY_set_group", __func__);
1215 }
Damien Millereb8b60e2010-08-31 22:41:14 +10001216 return nids[i];
1217}
1218
1219static EC_KEY*
1220ecdsa_generate_private_key(u_int bits, int *nid)
1221{
1222 EC_KEY *private;
1223
1224 if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1)
1225 fatal("%s: invalid key length", __func__);
1226 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL)
1227 fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
1228 if (EC_KEY_generate_key(private) != 1)
1229 fatal("%s: EC_KEY_generate_key failed", __func__);
Damien Millerb472a902010-11-05 10:19:49 +11001230 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
Damien Millereb8b60e2010-08-31 22:41:14 +10001231 return private;
1232}
Damien Miller6af914a2010-09-10 11:39:26 +10001233#endif /* OPENSSL_HAS_ECC */
Damien Millereb8b60e2010-08-31 22:41:14 +10001234
Damien Miller0bc1bd82000-11-13 22:57:25 +11001235Key *
Ben Lindstrom46c16222000-12-22 01:43:59 +00001236key_generate(int type, u_int bits)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001237{
1238 Key *k = key_new(KEY_UNSPEC);
1239 switch (type) {
Kevin Stevesef4eea92001-02-05 12:42:17 +00001240 case KEY_DSA:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001241 k->dsa = dsa_generate_private_key(bits);
1242 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001243#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001244 case KEY_ECDSA:
1245 k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid);
1246 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001247#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001248 case KEY_RSA:
1249 case KEY_RSA1:
1250 k->rsa = rsa_generate_private_key(bits);
1251 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001252 case KEY_ED25519:
1253 k->ed25519_pk = xmalloc(ED25519_PK_SZ);
1254 k->ed25519_sk = xmalloc(ED25519_SK_SZ);
1255 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
1256 break;
Damien Miller4e270b02010-04-16 15:56:21 +10001257 case KEY_RSA_CERT_V00:
1258 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001259 case KEY_RSA_CERT:
1260 case KEY_DSA_CERT:
1261 fatal("key_generate: cert keys cannot be generated directly");
Damien Miller0bc1bd82000-11-13 22:57:25 +11001262 default:
Kevin Stevesef4eea92001-02-05 12:42:17 +00001263 fatal("key_generate: unknown type %d", type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001264 }
Kevin Stevesef4eea92001-02-05 12:42:17 +00001265 k->type = type;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001266 return k;
1267}
1268
Damien Miller0a80ca12010-02-27 07:55:05 +11001269void
1270key_cert_copy(const Key *from_key, struct Key *to_key)
1271{
1272 u_int i;
1273 const struct KeyCert *from;
1274 struct KeyCert *to;
1275
1276 if (to_key->cert != NULL) {
1277 cert_free(to_key->cert);
1278 to_key->cert = NULL;
1279 }
1280
1281 if ((from = from_key->cert) == NULL)
1282 return;
1283
1284 to = to_key->cert = cert_new();
1285
1286 buffer_append(&to->certblob, buffer_ptr(&from->certblob),
1287 buffer_len(&from->certblob));
1288
Damien Miller4e270b02010-04-16 15:56:21 +10001289 buffer_append(&to->critical,
1290 buffer_ptr(&from->critical), buffer_len(&from->critical));
1291 buffer_append(&to->extensions,
1292 buffer_ptr(&from->extensions), buffer_len(&from->extensions));
Damien Miller0a80ca12010-02-27 07:55:05 +11001293
Damien Miller4e270b02010-04-16 15:56:21 +10001294 to->serial = from->serial;
Damien Miller0a80ca12010-02-27 07:55:05 +11001295 to->type = from->type;
1296 to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
1297 to->valid_after = from->valid_after;
1298 to->valid_before = from->valid_before;
1299 to->signature_key = from->signature_key == NULL ?
1300 NULL : key_from_private(from->signature_key);
1301
1302 to->nprincipals = from->nprincipals;
1303 if (to->nprincipals > CERT_MAX_PRINCIPALS)
1304 fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)",
1305 __func__, to->nprincipals, CERT_MAX_PRINCIPALS);
1306 if (to->nprincipals > 0) {
1307 to->principals = xcalloc(from->nprincipals,
1308 sizeof(*to->principals));
1309 for (i = 0; i < to->nprincipals; i++)
1310 to->principals[i] = xstrdup(from->principals[i]);
1311 }
1312}
1313
Damien Miller0bc1bd82000-11-13 22:57:25 +11001314Key *
Damien Millerf58b58c2003-11-17 21:18:23 +11001315key_from_private(const Key *k)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001316{
1317 Key *n = NULL;
1318 switch (k->type) {
Kevin Stevesef4eea92001-02-05 12:42:17 +00001319 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +10001320 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001321 case KEY_DSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001322 n = key_new(k->type);
Darren Tucker0bc85572006-11-07 23:14:41 +11001323 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
1324 (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1325 (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1326 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL))
1327 fatal("key_from_private: BN_copy failed");
Damien Miller0bc1bd82000-11-13 22:57:25 +11001328 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001329#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001330 case KEY_ECDSA:
1331 case KEY_ECDSA_CERT:
1332 n = key_new(k->type);
1333 n->ecdsa_nid = k->ecdsa_nid;
1334 if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)
1335 fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
1336 if (EC_KEY_set_public_key(n->ecdsa,
1337 EC_KEY_get0_public_key(k->ecdsa)) != 1)
1338 fatal("%s: EC_KEY_set_public_key failed", __func__);
1339 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001340#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001341 case KEY_RSA:
1342 case KEY_RSA1:
Damien Miller4e270b02010-04-16 15:56:21 +10001343 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001344 case KEY_RSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001345 n = key_new(k->type);
Darren Tucker0bc85572006-11-07 23:14:41 +11001346 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
1347 (BN_copy(n->rsa->e, k->rsa->e) == NULL))
1348 fatal("key_from_private: BN_copy failed");
Damien Miller0bc1bd82000-11-13 22:57:25 +11001349 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001350 case KEY_ED25519:
1351 case KEY_ED25519_CERT:
1352 n = key_new(k->type);
1353 if (k->ed25519_pk != NULL) {
1354 n->ed25519_pk = xmalloc(ED25519_PK_SZ);
1355 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1356 }
1357 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001358 default:
Kevin Stevesef4eea92001-02-05 12:42:17 +00001359 fatal("key_from_private: unknown type %d", k->type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001360 break;
1361 }
Damien Miller0a80ca12010-02-27 07:55:05 +11001362 if (key_is_cert(k))
1363 key_cert_copy(k, n);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001364 return n;
1365}
1366
1367int
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001368key_names_valid2(const char *names)
1369{
1370 char *s, *cp, *p;
1371
1372 if (names == NULL || strcmp(names, "") == 0)
1373 return 0;
1374 s = cp = xstrdup(names);
1375 for ((p = strsep(&cp, ",")); p && *p != '\0';
Damien Miller9f0f5c62001-12-21 14:45:46 +11001376 (p = strsep(&cp, ","))) {
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001377 switch (key_type_from_name(p)) {
1378 case KEY_RSA1:
1379 case KEY_UNSPEC:
Darren Tuckera627d422013-06-02 07:31:17 +10001380 free(s);
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001381 return 0;
1382 }
1383 }
1384 debug3("key names ok: [%s]", names);
Darren Tuckera627d422013-06-02 07:31:17 +10001385 free(s);
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001386 return 1;
1387}
1388
Damien Miller0a80ca12010-02-27 07:55:05 +11001389static int
1390cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
1391{
Damien Miller4e270b02010-04-16 15:56:21 +10001392 u_char *principals, *critical, *exts, *sig_key, *sig;
1393 u_int signed_len, plen, clen, sklen, slen, kidlen, elen;
Damien Miller0a80ca12010-02-27 07:55:05 +11001394 Buffer tmp;
1395 char *principal;
1396 int ret = -1;
Damien Miller4e270b02010-04-16 15:56:21 +10001397 int v00 = key->type == KEY_DSA_CERT_V00 ||
1398 key->type == KEY_RSA_CERT_V00;
Damien Miller0a80ca12010-02-27 07:55:05 +11001399
1400 buffer_init(&tmp);
1401
1402 /* Copy the entire key blob for verification and later serialisation */
1403 buffer_append(&key->cert->certblob, blob, blen);
1404
Damien Miller4e270b02010-04-16 15:56:21 +10001405 elen = 0; /* Not touched for v00 certs */
1406 principals = exts = critical = sig_key = sig = NULL;
1407 if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) ||
1408 buffer_get_int_ret(&key->cert->type, b) != 0 ||
Damien Millerda108ec2010-08-31 22:36:39 +10001409 (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL ||
Damien Miller0a80ca12010-02-27 07:55:05 +11001410 (principals = buffer_get_string_ret(b, &plen)) == NULL ||
1411 buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
1412 buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
Damien Miller4e270b02010-04-16 15:56:21 +10001413 (critical = buffer_get_string_ret(b, &clen)) == NULL ||
1414 (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) ||
1415 (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */
1416 buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */
Damien Miller0a80ca12010-02-27 07:55:05 +11001417 (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
1418 error("%s: parse error", __func__);
1419 goto out;
1420 }
1421
1422 /* Signature is left in the buffer so we can calculate this length */
1423 signed_len = buffer_len(&key->cert->certblob) - buffer_len(b);
1424
1425 if ((sig = buffer_get_string_ret(b, &slen)) == NULL) {
1426 error("%s: parse error", __func__);
1427 goto out;
1428 }
1429
1430 if (key->cert->type != SSH2_CERT_TYPE_USER &&
1431 key->cert->type != SSH2_CERT_TYPE_HOST) {
1432 error("Unknown certificate type %u", key->cert->type);
1433 goto out;
1434 }
1435
1436 buffer_append(&tmp, principals, plen);
1437 while (buffer_len(&tmp) > 0) {
1438 if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) {
Damien Miller41396572010-03-04 21:51:11 +11001439 error("%s: Too many principals", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001440 goto out;
1441 }
Damien Millerda108ec2010-08-31 22:36:39 +10001442 if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) {
Damien Miller41396572010-03-04 21:51:11 +11001443 error("%s: Principals data invalid", __func__);
1444 goto out;
1445 }
Damien Miller0a80ca12010-02-27 07:55:05 +11001446 key->cert->principals = xrealloc(key->cert->principals,
1447 key->cert->nprincipals + 1, sizeof(*key->cert->principals));
1448 key->cert->principals[key->cert->nprincipals++] = principal;
1449 }
1450
1451 buffer_clear(&tmp);
1452
Damien Miller4e270b02010-04-16 15:56:21 +10001453 buffer_append(&key->cert->critical, critical, clen);
1454 buffer_append(&tmp, critical, clen);
Damien Miller0a80ca12010-02-27 07:55:05 +11001455 /* validate structure */
1456 while (buffer_len(&tmp) != 0) {
Damien Miller2befbad2010-03-04 21:52:18 +11001457 if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
1458 buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
Damien Miller4e270b02010-04-16 15:56:21 +10001459 error("%s: critical option data invalid", __func__);
1460 goto out;
1461 }
1462 }
1463 buffer_clear(&tmp);
1464
1465 buffer_append(&key->cert->extensions, exts, elen);
1466 buffer_append(&tmp, exts, elen);
1467 /* validate structure */
1468 while (buffer_len(&tmp) != 0) {
1469 if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
1470 buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
1471 error("%s: extension data invalid", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001472 goto out;
1473 }
1474 }
1475 buffer_clear(&tmp);
1476
Damien Miller4a3a9d42013-10-30 22:19:47 +11001477 if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0))
1478 == NULL) {
Damien Miller41396572010-03-04 21:51:11 +11001479 error("%s: Signature key invalid", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001480 goto out;
1481 }
1482 if (key->cert->signature_key->type != KEY_RSA &&
Damien Millereb8b60e2010-08-31 22:41:14 +10001483 key->cert->signature_key->type != KEY_DSA &&
1484 key->cert->signature_key->type != KEY_ECDSA) {
Damien Miller41396572010-03-04 21:51:11 +11001485 error("%s: Invalid signature key type %s (%d)", __func__,
Damien Miller0a80ca12010-02-27 07:55:05 +11001486 key_type(key->cert->signature_key),
1487 key->cert->signature_key->type);
1488 goto out;
1489 }
1490
1491 switch (key_verify(key->cert->signature_key, sig, slen,
1492 buffer_ptr(&key->cert->certblob), signed_len)) {
1493 case 1:
Damien Miller41396572010-03-04 21:51:11 +11001494 ret = 0;
Damien Miller0a80ca12010-02-27 07:55:05 +11001495 break; /* Good signature */
1496 case 0:
Damien Miller41396572010-03-04 21:51:11 +11001497 error("%s: Invalid signature on certificate", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001498 goto out;
1499 case -1:
Damien Miller41396572010-03-04 21:51:11 +11001500 error("%s: Certificate signature verification failed",
1501 __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001502 goto out;
1503 }
1504
Damien Miller0a80ca12010-02-27 07:55:05 +11001505 out:
1506 buffer_free(&tmp);
Darren Tuckera627d422013-06-02 07:31:17 +10001507 free(principals);
1508 free(critical);
1509 free(exts);
1510 free(sig_key);
1511 free(sig);
Damien Miller0a80ca12010-02-27 07:55:05 +11001512 return ret;
1513}
1514
Damien Miller4a3a9d42013-10-30 22:19:47 +11001515static Key *
1516key_from_blob2(const u_char *blob, u_int blen, int allow_cert)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001517{
1518 Buffer b;
Darren Tucker8ccb7392010-09-10 12:28:24 +10001519 int rlen, type;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001520 u_int len;
Damien Millereb8b60e2010-08-31 22:41:14 +10001521 char *ktype = NULL, *curve = NULL;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001522 u_char *pk = NULL;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001523 Key *key = NULL;
Damien Miller6af914a2010-09-10 11:39:26 +10001524#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001525 EC_POINT *q = NULL;
Darren Tucker8ccb7392010-09-10 12:28:24 +10001526 int nid = -1;
Damien Miller6af914a2010-09-10 11:39:26 +10001527#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001528
1529#ifdef DEBUG_PK
1530 dump_base64(stderr, blob, blen);
1531#endif
1532 buffer_init(&b);
1533 buffer_append(&b, blob, blen);
Damien Millerda108ec2010-08-31 22:36:39 +10001534 if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) {
Darren Tucker08d04fa2004-11-05 20:42:28 +11001535 error("key_from_blob: can't read key type");
1536 goto out;
1537 }
1538
Damien Miller0bc1bd82000-11-13 22:57:25 +11001539 type = key_type_from_name(ktype);
Damien Miller6af914a2010-09-10 11:39:26 +10001540#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001541 if (key_type_plain(type) == KEY_ECDSA)
1542 nid = key_ecdsa_nid_from_name(ktype);
Damien Miller6af914a2010-09-10 11:39:26 +10001543#endif
Damien Miller4a3a9d42013-10-30 22:19:47 +11001544 if (!allow_cert && key_type_is_cert(type)) {
1545 error("key_from_blob: certificate not allowed in this context");
1546 goto out;
1547 }
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001548 switch (type) {
Damien Miller0a80ca12010-02-27 07:55:05 +11001549 case KEY_RSA_CERT:
Damien Miller4e270b02010-04-16 15:56:21 +10001550 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1551 /* FALLTHROUGH */
1552 case KEY_RSA:
1553 case KEY_RSA_CERT_V00:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001554 key = key_new(type);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001555 if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
1556 buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
1557 error("key_from_blob: can't read rsa key");
Damien Miller0a80ca12010-02-27 07:55:05 +11001558 badkey:
Darren Tucker08d04fa2004-11-05 20:42:28 +11001559 key_free(key);
1560 key = NULL;
1561 goto out;
1562 }
Damien Miller0bc1bd82000-11-13 22:57:25 +11001563#ifdef DEBUG_PK
1564 RSA_print_fp(stderr, key->rsa, 8);
1565#endif
1566 break;
Damien Miller0a80ca12010-02-27 07:55:05 +11001567 case KEY_DSA_CERT:
Damien Miller4e270b02010-04-16 15:56:21 +10001568 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1569 /* FALLTHROUGH */
1570 case KEY_DSA:
1571 case KEY_DSA_CERT_V00:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001572 key = key_new(type);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001573 if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
1574 buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
1575 buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
1576 buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
1577 error("key_from_blob: can't read dsa key");
Damien Miller0a80ca12010-02-27 07:55:05 +11001578 goto badkey;
Darren Tucker08d04fa2004-11-05 20:42:28 +11001579 }
Damien Miller0bc1bd82000-11-13 22:57:25 +11001580#ifdef DEBUG_PK
1581 DSA_print_fp(stderr, key->dsa, 8);
1582#endif
1583 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001584#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001585 case KEY_ECDSA_CERT:
1586 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1587 /* FALLTHROUGH */
1588 case KEY_ECDSA:
1589 key = key_new(type);
1590 key->ecdsa_nid = nid;
1591 if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) {
1592 error("key_from_blob: can't read ecdsa curve");
1593 goto badkey;
1594 }
1595 if (key->ecdsa_nid != key_curve_name_to_nid(curve)) {
1596 error("key_from_blob: ecdsa curve doesn't match type");
1597 goto badkey;
1598 }
1599 if (key->ecdsa != NULL)
1600 EC_KEY_free(key->ecdsa);
1601 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
1602 == NULL)
1603 fatal("key_from_blob: EC_KEY_new_by_curve_name failed");
1604 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL)
1605 fatal("key_from_blob: EC_POINT_new failed");
1606 if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa),
1607 q) == -1) {
1608 error("key_from_blob: can't read ecdsa key point");
1609 goto badkey;
1610 }
1611 if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
1612 q) != 0)
1613 goto badkey;
1614 if (EC_KEY_set_public_key(key->ecdsa, q) != 1)
1615 fatal("key_from_blob: EC_KEY_set_public_key failed");
1616#ifdef DEBUG_PK
1617 key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
1618#endif
1619 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001620#endif /* OPENSSL_HAS_ECC */
Damien Miller5be9d9e2013-12-07 11:24:01 +11001621 case KEY_ED25519_CERT:
1622 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1623 /* FALLTHROUGH */
1624 case KEY_ED25519:
1625 if ((pk = buffer_get_string_ret(&b, &len)) == NULL) {
1626 error("key_from_blob: can't read ed25519 key");
1627 goto badkey;
1628 }
1629 if (len != ED25519_PK_SZ) {
1630 error("key_from_blob: ed25519 len %d != %d",
1631 len, ED25519_PK_SZ);
1632 goto badkey;
1633 }
1634 key = key_new(type);
1635 key->ed25519_pk = pk;
1636 pk = NULL;
1637 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001638 case KEY_UNSPEC:
1639 key = key_new(type);
1640 break;
1641 default:
1642 error("key_from_blob: cannot handle type %s", ktype);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001643 goto out;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001644 }
Damien Miller0a80ca12010-02-27 07:55:05 +11001645 if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) {
1646 error("key_from_blob: can't parse cert data");
1647 goto badkey;
1648 }
Damien Miller0bc1bd82000-11-13 22:57:25 +11001649 rlen = buffer_len(&b);
1650 if (key != NULL && rlen != 0)
1651 error("key_from_blob: remaining bytes in key blob %d", rlen);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001652 out:
Darren Tuckera627d422013-06-02 07:31:17 +10001653 free(ktype);
1654 free(curve);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001655 free(pk);
Damien Miller6af914a2010-09-10 11:39:26 +10001656#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001657 if (q != NULL)
1658 EC_POINT_free(q);
Damien Miller6af914a2010-09-10 11:39:26 +10001659#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001660 buffer_free(&b);
1661 return key;
1662}
1663
Damien Miller4a3a9d42013-10-30 22:19:47 +11001664Key *
1665key_from_blob(const u_char *blob, u_int blen)
1666{
1667 return key_from_blob2(blob, blen, 1);
1668}
1669
Damien Millerf3747bf2013-01-18 11:44:04 +11001670static int
1671to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001672{
1673 Buffer b;
Damien Millerf3747bf2013-01-18 11:44:04 +11001674 int len, type;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001675
Damien Millerf7e8a872013-12-05 10:25:51 +11001676 if (blobp != NULL)
1677 *blobp = NULL;
1678 if (lenp != NULL)
1679 *lenp = 0;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001680 if (key == NULL) {
1681 error("key_to_blob: key == NULL");
1682 return 0;
1683 }
1684 buffer_init(&b);
Damien Millerf3747bf2013-01-18 11:44:04 +11001685 type = force_plain ? key_type_plain(key->type) : key->type;
1686 switch (type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001687 case KEY_DSA_CERT_V00:
1688 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001689 case KEY_DSA_CERT:
Damien Millereb8b60e2010-08-31 22:41:14 +10001690 case KEY_ECDSA_CERT:
Damien Miller0a80ca12010-02-27 07:55:05 +11001691 case KEY_RSA_CERT:
Damien Miller5be9d9e2013-12-07 11:24:01 +11001692 case KEY_ED25519_CERT:
Damien Miller0a80ca12010-02-27 07:55:05 +11001693 /* Use the existing blob */
1694 buffer_append(&b, buffer_ptr(&key->cert->certblob),
1695 buffer_len(&key->cert->certblob));
1696 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001697 case KEY_DSA:
Damien Millerf3747bf2013-01-18 11:44:04 +11001698 buffer_put_cstring(&b,
1699 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
Damien Miller0bc1bd82000-11-13 22:57:25 +11001700 buffer_put_bignum2(&b, key->dsa->p);
1701 buffer_put_bignum2(&b, key->dsa->q);
1702 buffer_put_bignum2(&b, key->dsa->g);
1703 buffer_put_bignum2(&b, key->dsa->pub_key);
1704 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001705#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001706 case KEY_ECDSA:
Damien Millerf3747bf2013-01-18 11:44:04 +11001707 buffer_put_cstring(&b,
1708 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
Damien Millereb8b60e2010-08-31 22:41:14 +10001709 buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid));
1710 buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa),
1711 EC_KEY_get0_public_key(key->ecdsa));
1712 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001713#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001714 case KEY_RSA:
Damien Millerf3747bf2013-01-18 11:44:04 +11001715 buffer_put_cstring(&b,
1716 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
Damien Miller0bc1bd82000-11-13 22:57:25 +11001717 buffer_put_bignum2(&b, key->rsa->e);
Ben Lindstrombf555ba2001-01-18 02:04:35 +00001718 buffer_put_bignum2(&b, key->rsa->n);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001719 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001720 case KEY_ED25519:
1721 buffer_put_cstring(&b,
1722 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
1723 buffer_put_string(&b, key->ed25519_pk, ED25519_PK_SZ);
1724 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001725 default:
Ben Lindstrom99a30f12001-09-18 05:49:14 +00001726 error("key_to_blob: unsupported key type %d", key->type);
1727 buffer_free(&b);
1728 return 0;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001729 }
1730 len = buffer_len(&b);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001731 if (lenp != NULL)
1732 *lenp = len;
Ben Lindstrom2bf759c2002-07-07 22:13:31 +00001733 if (blobp != NULL) {
1734 *blobp = xmalloc(len);
1735 memcpy(*blobp, buffer_ptr(&b), len);
1736 }
1737 memset(buffer_ptr(&b), 0, len);
1738 buffer_free(&b);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001739 return len;
1740}
1741
1742int
Damien Millerf3747bf2013-01-18 11:44:04 +11001743key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
1744{
1745 return to_blob(key, blobp, lenp, 0);
1746}
1747
1748int
Damien Miller0bc1bd82000-11-13 22:57:25 +11001749key_sign(
Damien Millerf58b58c2003-11-17 21:18:23 +11001750 const Key *key,
Ben Lindstrom90fd8142002-02-26 18:09:42 +00001751 u_char **sigp, u_int *lenp,
Damien Millerf58b58c2003-11-17 21:18:23 +11001752 const u_char *data, u_int datalen)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001753{
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001754 switch (key->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001755 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001756 case KEY_DSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001757 case KEY_DSA:
1758 return ssh_dss_sign(key, sigp, lenp, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001759#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001760 case KEY_ECDSA_CERT:
1761 case KEY_ECDSA:
1762 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001763#endif
Damien Miller4e270b02010-04-16 15:56:21 +10001764 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001765 case KEY_RSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001766 case KEY_RSA:
1767 return ssh_rsa_sign(key, sigp, lenp, data, datalen);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001768 case KEY_ED25519:
1769 case KEY_ED25519_CERT:
1770 return ssh_ed25519_sign(key, sigp, lenp, data, datalen);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001771 default:
Darren Tucker5cb30ad2004-08-12 22:40:24 +10001772 error("key_sign: invalid key type %d", key->type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001773 return -1;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001774 }
1775}
1776
Ben Lindstrom01fff0c2002-06-06 20:54:07 +00001777/*
1778 * key_verify returns 1 for a correct signature, 0 for an incorrect signature
1779 * and -1 on error.
1780 */
Damien Miller0bc1bd82000-11-13 22:57:25 +11001781int
1782key_verify(
Damien Millerf58b58c2003-11-17 21:18:23 +11001783 const Key *key,
1784 const u_char *signature, u_int signaturelen,
1785 const u_char *data, u_int datalen)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001786{
Ben Lindstrom5363aee2001-06-25 04:42:20 +00001787 if (signaturelen == 0)
1788 return -1;
1789
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001790 switch (key->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001791 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001792 case KEY_DSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001793 case KEY_DSA:
1794 return ssh_dss_verify(key, signature, signaturelen, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001795#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001796 case KEY_ECDSA_CERT:
1797 case KEY_ECDSA:
1798 return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001799#endif
Damien Miller4e270b02010-04-16 15:56:21 +10001800 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001801 case KEY_RSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001802 case KEY_RSA:
1803 return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001804 case KEY_ED25519:
1805 case KEY_ED25519_CERT:
1806 return ssh_ed25519_verify(key, signature, signaturelen, data, datalen);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001807 default:
Darren Tucker5cb30ad2004-08-12 22:40:24 +10001808 error("key_verify: invalid key type %d", key->type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001809 return -1;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001810 }
1811}
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001812
1813/* Converts a private to a public key */
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001814Key *
Damien Millerf58b58c2003-11-17 21:18:23 +11001815key_demote(const Key *k)
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001816{
1817 Key *pk;
Ben Lindstrom6328ab32002-03-22 02:54:23 +00001818
Damien Miller07d86be2006-03-26 14:19:21 +11001819 pk = xcalloc(1, sizeof(*pk));
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001820 pk->type = k->type;
1821 pk->flags = k->flags;
Damien Millereb8b60e2010-08-31 22:41:14 +10001822 pk->ecdsa_nid = k->ecdsa_nid;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001823 pk->dsa = NULL;
Damien Millereb8b60e2010-08-31 22:41:14 +10001824 pk->ecdsa = NULL;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001825 pk->rsa = NULL;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001826 pk->ed25519_pk = NULL;
1827 pk->ed25519_sk = NULL;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001828
1829 switch (k->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001830 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001831 case KEY_RSA_CERT:
1832 key_cert_copy(k, pk);
1833 /* FALLTHROUGH */
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001834 case KEY_RSA1:
1835 case KEY_RSA:
1836 if ((pk->rsa = RSA_new()) == NULL)
1837 fatal("key_demote: RSA_new failed");
1838 if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL)
1839 fatal("key_demote: BN_dup failed");
1840 if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
1841 fatal("key_demote: BN_dup failed");
1842 break;
Damien Miller4e270b02010-04-16 15:56:21 +10001843 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001844 case KEY_DSA_CERT:
1845 key_cert_copy(k, pk);
1846 /* FALLTHROUGH */
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001847 case KEY_DSA:
1848 if ((pk->dsa = DSA_new()) == NULL)
1849 fatal("key_demote: DSA_new failed");
1850 if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL)
1851 fatal("key_demote: BN_dup failed");
1852 if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL)
1853 fatal("key_demote: BN_dup failed");
1854 if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL)
1855 fatal("key_demote: BN_dup failed");
1856 if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
1857 fatal("key_demote: BN_dup failed");
1858 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001859#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001860 case KEY_ECDSA_CERT:
1861 key_cert_copy(k, pk);
1862 /* FALLTHROUGH */
1863 case KEY_ECDSA:
1864 if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL)
1865 fatal("key_demote: EC_KEY_new_by_curve_name failed");
1866 if (EC_KEY_set_public_key(pk->ecdsa,
1867 EC_KEY_get0_public_key(k->ecdsa)) != 1)
1868 fatal("key_demote: EC_KEY_set_public_key failed");
1869 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001870#endif
Damien Miller5be9d9e2013-12-07 11:24:01 +11001871 case KEY_ED25519_CERT:
1872 key_cert_copy(k, pk);
1873 /* FALLTHROUGH */
1874 case KEY_ED25519:
1875 if (k->ed25519_pk != NULL) {
1876 pk->ed25519_pk = xmalloc(ED25519_PK_SZ);
1877 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1878 }
1879 break;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001880 default:
Damien Miller5be9d9e2013-12-07 11:24:01 +11001881 fatal("key_demote: bad key type %d", k->type);
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001882 break;
1883 }
1884
1885 return (pk);
1886}
Damien Miller0a80ca12010-02-27 07:55:05 +11001887
1888int
1889key_is_cert(const Key *k)
1890{
Damien Miller4e270b02010-04-16 15:56:21 +10001891 if (k == NULL)
1892 return 0;
Damien Miller4a3a9d42013-10-30 22:19:47 +11001893 return key_type_is_cert(k->type);
Damien Miller0a80ca12010-02-27 07:55:05 +11001894}
1895
1896/* Return the cert-less equivalent to a certified key type */
1897int
1898key_type_plain(int type)
1899{
1900 switch (type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001901 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001902 case KEY_RSA_CERT:
1903 return KEY_RSA;
Damien Miller4e270b02010-04-16 15:56:21 +10001904 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001905 case KEY_DSA_CERT:
1906 return KEY_DSA;
Damien Millereb8b60e2010-08-31 22:41:14 +10001907 case KEY_ECDSA_CERT:
1908 return KEY_ECDSA;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001909 case KEY_ED25519_CERT:
1910 return KEY_ED25519;
Damien Miller0a80ca12010-02-27 07:55:05 +11001911 default:
1912 return type;
1913 }
1914}
1915
1916/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */
1917int
Damien Miller4e270b02010-04-16 15:56:21 +10001918key_to_certified(Key *k, int legacy)
Damien Miller0a80ca12010-02-27 07:55:05 +11001919{
1920 switch (k->type) {
1921 case KEY_RSA:
1922 k->cert = cert_new();
Damien Miller4e270b02010-04-16 15:56:21 +10001923 k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT;
Damien Miller0a80ca12010-02-27 07:55:05 +11001924 return 0;
1925 case KEY_DSA:
1926 k->cert = cert_new();
Damien Miller4e270b02010-04-16 15:56:21 +10001927 k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
Damien Miller0a80ca12010-02-27 07:55:05 +11001928 return 0;
Damien Millereb8b60e2010-08-31 22:41:14 +10001929 case KEY_ECDSA:
Damien Miller8f639fe2011-05-20 19:03:08 +10001930 if (legacy)
1931 fatal("%s: legacy ECDSA certificates are not supported",
1932 __func__);
Damien Millereb8b60e2010-08-31 22:41:14 +10001933 k->cert = cert_new();
1934 k->type = KEY_ECDSA_CERT;
1935 return 0;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001936 case KEY_ED25519:
1937 if (legacy)
1938 fatal("%s: legacy ED25519 certificates are not "
1939 "supported", __func__);
1940 k->cert = cert_new();
1941 k->type = KEY_ED25519_CERT;
1942 return 0;
Damien Miller0a80ca12010-02-27 07:55:05 +11001943 default:
1944 error("%s: key has incorrect type %s", __func__, key_type(k));
1945 return -1;
1946 }
1947}
1948
1949/* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */
1950int
1951key_drop_cert(Key *k)
1952{
Damien Miller5be9d9e2013-12-07 11:24:01 +11001953 if (!key_type_is_cert(k->type)) {
Damien Miller0a80ca12010-02-27 07:55:05 +11001954 error("%s: key has incorrect type %s", __func__, key_type(k));
1955 return -1;
1956 }
Damien Miller5be9d9e2013-12-07 11:24:01 +11001957 cert_free(k->cert);
1958 k->type = key_type_plain(k->type);
1959 return 0;
Damien Miller0a80ca12010-02-27 07:55:05 +11001960}
1961
Damien Miller5be9d9e2013-12-07 11:24:01 +11001962/* Sign a certified key, (re-)generating the signed certblob. */
Damien Miller0a80ca12010-02-27 07:55:05 +11001963int
1964key_certify(Key *k, Key *ca)
1965{
1966 Buffer principals;
1967 u_char *ca_blob, *sig_blob, nonce[32];
1968 u_int i, ca_len, sig_len;
1969
1970 if (k->cert == NULL) {
1971 error("%s: key lacks cert info", __func__);
1972 return -1;
1973 }
1974
1975 if (!key_is_cert(k)) {
1976 error("%s: certificate has unknown type %d", __func__,
1977 k->cert->type);
1978 return -1;
1979 }
1980
Damien Millereb8b60e2010-08-31 22:41:14 +10001981 if (ca->type != KEY_RSA && ca->type != KEY_DSA &&
Damien Miller5be9d9e2013-12-07 11:24:01 +11001982 ca->type != KEY_ECDSA && ca->type != KEY_ED25519) {
Damien Miller0a80ca12010-02-27 07:55:05 +11001983 error("%s: CA key has unsupported type %s", __func__,
1984 key_type(ca));
1985 return -1;
1986 }
1987
1988 key_to_blob(ca, &ca_blob, &ca_len);
1989
1990 buffer_clear(&k->cert->certblob);
1991 buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
1992
Damien Miller4e270b02010-04-16 15:56:21 +10001993 /* -v01 certs put nonce first */
Damien Miller0a5f0122011-02-04 11:47:01 +11001994 arc4random_buf(&nonce, sizeof(nonce));
1995 if (!key_cert_is_legacy(k))
Damien Miller4e270b02010-04-16 15:56:21 +10001996 buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
Damien Miller4e270b02010-04-16 15:56:21 +10001997
Damien Millerbcd00ab2013-12-07 10:41:55 +11001998 /* XXX this substantially duplicates to_blob(); refactor */
Damien Miller0a80ca12010-02-27 07:55:05 +11001999 switch (k->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10002000 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11002001 case KEY_DSA_CERT:
2002 buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
2003 buffer_put_bignum2(&k->cert->certblob, k->dsa->q);
2004 buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
2005 buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
2006 break;
Damien Miller6af914a2010-09-10 11:39:26 +10002007#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10002008 case KEY_ECDSA_CERT:
2009 buffer_put_cstring(&k->cert->certblob,
2010 key_curve_nid_to_name(k->ecdsa_nid));
2011 buffer_put_ecpoint(&k->cert->certblob,
2012 EC_KEY_get0_group(k->ecdsa),
2013 EC_KEY_get0_public_key(k->ecdsa));
2014 break;
Damien Miller6af914a2010-09-10 11:39:26 +10002015#endif
Damien Miller4e270b02010-04-16 15:56:21 +10002016 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11002017 case KEY_RSA_CERT:
2018 buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
2019 buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
2020 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11002021 case KEY_ED25519_CERT:
2022 buffer_put_string(&k->cert->certblob,
2023 k->ed25519_pk, ED25519_PK_SZ);
2024 break;
Damien Miller0a80ca12010-02-27 07:55:05 +11002025 default:
2026 error("%s: key has incorrect type %s", __func__, key_type(k));
2027 buffer_clear(&k->cert->certblob);
Darren Tuckera627d422013-06-02 07:31:17 +10002028 free(ca_blob);
Damien Miller0a80ca12010-02-27 07:55:05 +11002029 return -1;
2030 }
2031
Damien Miller4e270b02010-04-16 15:56:21 +10002032 /* -v01 certs have a serial number next */
Damien Millereb8b60e2010-08-31 22:41:14 +10002033 if (!key_cert_is_legacy(k))
Damien Miller4e270b02010-04-16 15:56:21 +10002034 buffer_put_int64(&k->cert->certblob, k->cert->serial);
2035
Damien Miller0a80ca12010-02-27 07:55:05 +11002036 buffer_put_int(&k->cert->certblob, k->cert->type);
2037 buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
2038
2039 buffer_init(&principals);
2040 for (i = 0; i < k->cert->nprincipals; i++)
2041 buffer_put_cstring(&principals, k->cert->principals[i]);
2042 buffer_put_string(&k->cert->certblob, buffer_ptr(&principals),
2043 buffer_len(&principals));
2044 buffer_free(&principals);
2045
2046 buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
2047 buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
2048 buffer_put_string(&k->cert->certblob,
Damien Miller4e270b02010-04-16 15:56:21 +10002049 buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical));
Damien Miller0a80ca12010-02-27 07:55:05 +11002050
Damien Miller4e270b02010-04-16 15:56:21 +10002051 /* -v01 certs have non-critical options here */
Damien Millereb8b60e2010-08-31 22:41:14 +10002052 if (!key_cert_is_legacy(k)) {
Damien Miller4e270b02010-04-16 15:56:21 +10002053 buffer_put_string(&k->cert->certblob,
2054 buffer_ptr(&k->cert->extensions),
2055 buffer_len(&k->cert->extensions));
2056 }
2057
2058 /* -v00 certs put the nonce at the end */
Damien Millereb8b60e2010-08-31 22:41:14 +10002059 if (key_cert_is_legacy(k))
Damien Miller4e270b02010-04-16 15:56:21 +10002060 buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
2061
Damien Miller0a80ca12010-02-27 07:55:05 +11002062 buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
2063 buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
Darren Tuckera627d422013-06-02 07:31:17 +10002064 free(ca_blob);
Damien Miller0a80ca12010-02-27 07:55:05 +11002065
2066 /* Sign the whole mess */
2067 if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob),
2068 buffer_len(&k->cert->certblob)) != 0) {
2069 error("%s: signature operation failed", __func__);
2070 buffer_clear(&k->cert->certblob);
2071 return -1;
2072 }
2073 /* Append signature and we are done */
2074 buffer_put_string(&k->cert->certblob, sig_blob, sig_len);
Darren Tuckera627d422013-06-02 07:31:17 +10002075 free(sig_blob);
Damien Miller0a80ca12010-02-27 07:55:05 +11002076
2077 return 0;
2078}
2079
2080int
2081key_cert_check_authority(const Key *k, int want_host, int require_principal,
2082 const char *name, const char **reason)
2083{
2084 u_int i, principal_matches;
2085 time_t now = time(NULL);
2086
2087 if (want_host) {
2088 if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2089 *reason = "Certificate invalid: not a host certificate";
2090 return -1;
2091 }
2092 } else {
2093 if (k->cert->type != SSH2_CERT_TYPE_USER) {
2094 *reason = "Certificate invalid: not a user certificate";
2095 return -1;
2096 }
2097 }
2098 if (now < 0) {
2099 error("%s: system clock lies before epoch", __func__);
2100 *reason = "Certificate invalid: not yet valid";
2101 return -1;
2102 }
2103 if ((u_int64_t)now < k->cert->valid_after) {
2104 *reason = "Certificate invalid: not yet valid";
2105 return -1;
2106 }
2107 if ((u_int64_t)now >= k->cert->valid_before) {
2108 *reason = "Certificate invalid: expired";
2109 return -1;
2110 }
2111 if (k->cert->nprincipals == 0) {
2112 if (require_principal) {
2113 *reason = "Certificate lacks principal list";
2114 return -1;
2115 }
Damien Miller30da3442010-05-10 11:58:03 +10002116 } else if (name != NULL) {
Damien Miller0a80ca12010-02-27 07:55:05 +11002117 principal_matches = 0;
2118 for (i = 0; i < k->cert->nprincipals; i++) {
2119 if (strcmp(name, k->cert->principals[i]) == 0) {
2120 principal_matches = 1;
2121 break;
2122 }
2123 }
2124 if (!principal_matches) {
2125 *reason = "Certificate invalid: name is not a listed "
2126 "principal";
2127 return -1;
2128 }
2129 }
2130 return 0;
2131}
Damien Miller4e270b02010-04-16 15:56:21 +10002132
2133int
Damien Millerf3747bf2013-01-18 11:44:04 +11002134key_cert_is_legacy(const Key *k)
Damien Miller4e270b02010-04-16 15:56:21 +10002135{
2136 switch (k->type) {
2137 case KEY_DSA_CERT_V00:
2138 case KEY_RSA_CERT_V00:
2139 return 1;
2140 default:
2141 return 0;
2142 }
2143}
Damien Millereb8b60e2010-08-31 22:41:14 +10002144
Damien Miller041ab7c2010-09-10 11:23:34 +10002145/* XXX: these are really begging for a table-driven approach */
Damien Millereb8b60e2010-08-31 22:41:14 +10002146int
2147key_curve_name_to_nid(const char *name)
2148{
Damien Miller6af914a2010-09-10 11:39:26 +10002149#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10002150 if (strcmp(name, "nistp256") == 0)
2151 return NID_X9_62_prime256v1;
2152 else if (strcmp(name, "nistp384") == 0)
2153 return NID_secp384r1;
Darren Tucker37bcef52013-11-09 18:39:25 +11002154# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10002155 else if (strcmp(name, "nistp521") == 0)
2156 return NID_secp521r1;
Darren Tucker37bcef52013-11-09 18:39:25 +11002157# endif
Damien Miller6af914a2010-09-10 11:39:26 +10002158#endif
Damien Millereb8b60e2010-08-31 22:41:14 +10002159
2160 debug("%s: unsupported EC curve name \"%.100s\"", __func__, name);
2161 return -1;
2162}
2163
Damien Miller041ab7c2010-09-10 11:23:34 +10002164u_int
2165key_curve_nid_to_bits(int nid)
2166{
2167 switch (nid) {
Damien Miller6af914a2010-09-10 11:39:26 +10002168#ifdef OPENSSL_HAS_ECC
Damien Miller041ab7c2010-09-10 11:23:34 +10002169 case NID_X9_62_prime256v1:
2170 return 256;
2171 case NID_secp384r1:
2172 return 384;
Darren Tucker2c894302013-11-10 12:38:42 +11002173# ifdef OPENSSL_HAS_NISTP521
Damien Miller041ab7c2010-09-10 11:23:34 +10002174 case NID_secp521r1:
2175 return 521;
Darren Tucker37bcef52013-11-09 18:39:25 +11002176# endif
Damien Miller6af914a2010-09-10 11:39:26 +10002177#endif
Damien Miller041ab7c2010-09-10 11:23:34 +10002178 default:
2179 error("%s: unsupported EC curve nid %d", __func__, nid);
2180 return 0;
2181 }
2182}
2183
Damien Millereb8b60e2010-08-31 22:41:14 +10002184const char *
2185key_curve_nid_to_name(int nid)
2186{
Damien Miller6af914a2010-09-10 11:39:26 +10002187#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10002188 if (nid == NID_X9_62_prime256v1)
2189 return "nistp256";
2190 else if (nid == NID_secp384r1)
2191 return "nistp384";
Darren Tucker37bcef52013-11-09 18:39:25 +11002192# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10002193 else if (nid == NID_secp521r1)
2194 return "nistp521";
Darren Tucker37bcef52013-11-09 18:39:25 +11002195# endif
Damien Miller6af914a2010-09-10 11:39:26 +10002196#endif
Damien Millereb8b60e2010-08-31 22:41:14 +10002197 error("%s: unsupported EC curve nid %d", __func__, nid);
2198 return NULL;
2199}
2200
Damien Miller6af914a2010-09-10 11:39:26 +10002201#ifdef OPENSSL_HAS_ECC
Damien Miller041ab7c2010-09-10 11:23:34 +10002202const EVP_MD *
2203key_ec_nid_to_evpmd(int nid)
2204{
2205 int kbits = key_curve_nid_to_bits(nid);
2206
2207 if (kbits == 0)
2208 fatal("%s: invalid nid %d", __func__, nid);
2209 /* RFC5656 section 6.2.1 */
2210 if (kbits <= 256)
2211 return EVP_sha256();
2212 else if (kbits <= 384)
2213 return EVP_sha384();
2214 else
2215 return EVP_sha512();
2216}
2217
Damien Millereb8b60e2010-08-31 22:41:14 +10002218int
2219key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2220{
2221 BN_CTX *bnctx;
2222 EC_POINT *nq = NULL;
2223 BIGNUM *order, *x, *y, *tmp;
2224 int ret = -1;
2225
2226 if ((bnctx = BN_CTX_new()) == NULL)
2227 fatal("%s: BN_CTX_new failed", __func__);
2228 BN_CTX_start(bnctx);
2229
2230 /*
2231 * We shouldn't ever hit this case because bignum_get_ecpoint()
2232 * refuses to load GF2m points.
2233 */
2234 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2235 NID_X9_62_prime_field) {
2236 error("%s: group is not a prime field", __func__);
2237 goto out;
2238 }
2239
2240 /* Q != infinity */
2241 if (EC_POINT_is_at_infinity(group, public)) {
2242 error("%s: received degenerate public key (infinity)",
2243 __func__);
2244 goto out;
2245 }
2246
2247 if ((x = BN_CTX_get(bnctx)) == NULL ||
2248 (y = BN_CTX_get(bnctx)) == NULL ||
2249 (order = BN_CTX_get(bnctx)) == NULL ||
2250 (tmp = BN_CTX_get(bnctx)) == NULL)
2251 fatal("%s: BN_CTX_get failed", __func__);
2252
2253 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2254 if (EC_GROUP_get_order(group, order, bnctx) != 1)
2255 fatal("%s: EC_GROUP_get_order failed", __func__);
2256 if (EC_POINT_get_affine_coordinates_GFp(group, public,
2257 x, y, bnctx) != 1)
2258 fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__);
2259 if (BN_num_bits(x) <= BN_num_bits(order) / 2) {
2260 error("%s: public key x coordinate too small: "
2261 "bits(x) = %d, bits(order)/2 = %d", __func__,
2262 BN_num_bits(x), BN_num_bits(order) / 2);
2263 goto out;
2264 }
2265 if (BN_num_bits(y) <= BN_num_bits(order) / 2) {
2266 error("%s: public key y coordinate too small: "
2267 "bits(y) = %d, bits(order)/2 = %d", __func__,
2268 BN_num_bits(x), BN_num_bits(order) / 2);
2269 goto out;
2270 }
2271
2272 /* nQ == infinity (n == order of subgroup) */
2273 if ((nq = EC_POINT_new(group)) == NULL)
2274 fatal("%s: BN_CTX_tmp failed", __func__);
2275 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1)
2276 fatal("%s: EC_GROUP_mul failed", __func__);
2277 if (EC_POINT_is_at_infinity(group, nq) != 1) {
2278 error("%s: received degenerate public key (nQ != infinity)",
2279 __func__);
2280 goto out;
2281 }
2282
2283 /* x < order - 1, y < order - 1 */
2284 if (!BN_sub(tmp, order, BN_value_one()))
2285 fatal("%s: BN_sub failed", __func__);
2286 if (BN_cmp(x, tmp) >= 0) {
2287 error("%s: public key x coordinate >= group order - 1",
2288 __func__);
2289 goto out;
2290 }
2291 if (BN_cmp(y, tmp) >= 0) {
2292 error("%s: public key y coordinate >= group order - 1",
2293 __func__);
2294 goto out;
2295 }
2296 ret = 0;
2297 out:
2298 BN_CTX_free(bnctx);
2299 EC_POINT_free(nq);
2300 return ret;
2301}
2302
2303int
2304key_ec_validate_private(const EC_KEY *key)
2305{
2306 BN_CTX *bnctx;
2307 BIGNUM *order, *tmp;
2308 int ret = -1;
2309
2310 if ((bnctx = BN_CTX_new()) == NULL)
2311 fatal("%s: BN_CTX_new failed", __func__);
2312 BN_CTX_start(bnctx);
2313
2314 if ((order = BN_CTX_get(bnctx)) == NULL ||
2315 (tmp = BN_CTX_get(bnctx)) == NULL)
2316 fatal("%s: BN_CTX_get failed", __func__);
2317
2318 /* log2(private) > log2(order)/2 */
2319 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1)
2320 fatal("%s: EC_GROUP_get_order failed", __func__);
2321 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2322 BN_num_bits(order) / 2) {
2323 error("%s: private key too small: "
2324 "bits(y) = %d, bits(order)/2 = %d", __func__,
2325 BN_num_bits(EC_KEY_get0_private_key(key)),
2326 BN_num_bits(order) / 2);
2327 goto out;
2328 }
2329
2330 /* private < order - 1 */
2331 if (!BN_sub(tmp, order, BN_value_one()))
2332 fatal("%s: BN_sub failed", __func__);
2333 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) {
2334 error("%s: private key >= group order - 1", __func__);
2335 goto out;
2336 }
2337 ret = 0;
2338 out:
2339 BN_CTX_free(bnctx);
2340 return ret;
2341}
2342
2343#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK)
2344void
2345key_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
2346{
2347 BIGNUM *x, *y;
2348 BN_CTX *bnctx;
2349
2350 if (point == NULL) {
2351 fputs("point=(NULL)\n", stderr);
2352 return;
2353 }
2354 if ((bnctx = BN_CTX_new()) == NULL)
2355 fatal("%s: BN_CTX_new failed", __func__);
2356 BN_CTX_start(bnctx);
2357 if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL)
2358 fatal("%s: BN_CTX_get failed", __func__);
2359 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2360 NID_X9_62_prime_field)
2361 fatal("%s: group is not a prime field", __func__);
2362 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1)
2363 fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__);
2364 fputs("x=", stderr);
2365 BN_print_fp(stderr, x);
2366 fputs("\ny=", stderr);
2367 BN_print_fp(stderr, y);
2368 fputs("\n", stderr);
2369 BN_CTX_free(bnctx);
2370}
2371
2372void
2373key_dump_ec_key(const EC_KEY *key)
2374{
2375 const BIGNUM *exponent;
2376
2377 key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key));
2378 fputs("exponent=", stderr);
2379 if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
2380 fputs("(NULL)", stderr);
2381 else
2382 BN_print_fp(stderr, EC_KEY_get0_private_key(key));
2383 fputs("\n", stderr);
2384}
2385#endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */
Damien Miller6af914a2010-09-10 11:39:26 +10002386#endif /* OPENSSL_HAS_ECC */
Damien Millerf0e90602013-12-07 10:40:26 +11002387
2388void
2389key_private_serialize(const Key *key, Buffer *b)
2390{
2391 buffer_put_cstring(b, key_ssh_name(key));
2392 switch (key->type) {
2393 case KEY_RSA:
2394 buffer_put_bignum2(b, key->rsa->n);
2395 buffer_put_bignum2(b, key->rsa->e);
2396 buffer_put_bignum2(b, key->rsa->d);
2397 buffer_put_bignum2(b, key->rsa->iqmp);
2398 buffer_put_bignum2(b, key->rsa->p);
2399 buffer_put_bignum2(b, key->rsa->q);
2400 break;
2401 case KEY_RSA_CERT_V00:
2402 case KEY_RSA_CERT:
2403 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2404 fatal("%s: no cert/certblob", __func__);
2405 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2406 buffer_len(&key->cert->certblob));
2407 buffer_put_bignum2(b, key->rsa->d);
2408 buffer_put_bignum2(b, key->rsa->iqmp);
2409 buffer_put_bignum2(b, key->rsa->p);
2410 buffer_put_bignum2(b, key->rsa->q);
2411 break;
2412 case KEY_DSA:
2413 buffer_put_bignum2(b, key->dsa->p);
2414 buffer_put_bignum2(b, key->dsa->q);
2415 buffer_put_bignum2(b, key->dsa->g);
2416 buffer_put_bignum2(b, key->dsa->pub_key);
2417 buffer_put_bignum2(b, key->dsa->priv_key);
2418 break;
2419 case KEY_DSA_CERT_V00:
2420 case KEY_DSA_CERT:
2421 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2422 fatal("%s: no cert/certblob", __func__);
2423 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2424 buffer_len(&key->cert->certblob));
2425 buffer_put_bignum2(b, key->dsa->priv_key);
2426 break;
2427#ifdef OPENSSL_HAS_ECC
2428 case KEY_ECDSA:
2429 buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
2430 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
2431 EC_KEY_get0_public_key(key->ecdsa));
2432 buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
2433 break;
2434 case KEY_ECDSA_CERT:
2435 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2436 fatal("%s: no cert/certblob", __func__);
2437 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2438 buffer_len(&key->cert->certblob));
2439 buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
2440 break;
2441#endif /* OPENSSL_HAS_ECC */
Damien Miller5be9d9e2013-12-07 11:24:01 +11002442 case KEY_ED25519:
2443 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
2444 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
2445 break;
2446 case KEY_ED25519_CERT:
2447 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2448 fatal("%s: no cert/certblob", __func__);
2449 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2450 buffer_len(&key->cert->certblob));
2451 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
2452 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
2453 break;
Damien Millerf0e90602013-12-07 10:40:26 +11002454 }
2455}
2456
2457Key *
2458key_private_deserialize(Buffer *blob)
2459{
2460 char *type_name;
2461 Key *k = NULL;
2462 u_char *cert;
Damien Miller5be9d9e2013-12-07 11:24:01 +11002463 u_int len, pklen, sklen;
Damien Millerf0e90602013-12-07 10:40:26 +11002464 int type;
2465#ifdef OPENSSL_HAS_ECC
2466 char *curve;
2467 BIGNUM *exponent;
2468 EC_POINT *q;
2469#endif
2470
2471 type_name = buffer_get_string(blob, NULL);
2472 type = key_type_from_name(type_name);
2473 switch (type) {
2474 case KEY_DSA:
2475 k = key_new_private(type);
2476 buffer_get_bignum2(blob, k->dsa->p);
2477 buffer_get_bignum2(blob, k->dsa->q);
2478 buffer_get_bignum2(blob, k->dsa->g);
2479 buffer_get_bignum2(blob, k->dsa->pub_key);
2480 buffer_get_bignum2(blob, k->dsa->priv_key);
2481 break;
2482 case KEY_DSA_CERT_V00:
2483 case KEY_DSA_CERT:
2484 cert = buffer_get_string(blob, &len);
2485 if ((k = key_from_blob(cert, len)) == NULL)
2486 fatal("Certificate parse failed");
2487 free(cert);
2488 key_add_private(k);
2489 buffer_get_bignum2(blob, k->dsa->priv_key);
2490 break;
2491#ifdef OPENSSL_HAS_ECC
2492 case KEY_ECDSA:
2493 k = key_new_private(type);
2494 k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
2495 curve = buffer_get_string(blob, NULL);
2496 if (k->ecdsa_nid != key_curve_name_to_nid(curve))
2497 fatal("%s: curve names mismatch", __func__);
2498 free(curve);
2499 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
2500 if (k->ecdsa == NULL)
2501 fatal("%s: EC_KEY_new_by_curve_name failed",
2502 __func__);
2503 q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
2504 if (q == NULL)
2505 fatal("%s: BN_new failed", __func__);
2506 if ((exponent = BN_new()) == NULL)
2507 fatal("%s: BN_new failed", __func__);
2508 buffer_get_ecpoint(blob,
2509 EC_KEY_get0_group(k->ecdsa), q);
2510 buffer_get_bignum2(blob, exponent);
2511 if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
2512 fatal("%s: EC_KEY_set_public_key failed",
2513 __func__);
2514 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
2515 fatal("%s: EC_KEY_set_private_key failed",
2516 __func__);
2517 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2518 EC_KEY_get0_public_key(k->ecdsa)) != 0)
2519 fatal("%s: bad ECDSA public key", __func__);
2520 if (key_ec_validate_private(k->ecdsa) != 0)
2521 fatal("%s: bad ECDSA private key", __func__);
2522 BN_clear_free(exponent);
2523 EC_POINT_free(q);
2524 break;
2525 case KEY_ECDSA_CERT:
2526 cert = buffer_get_string(blob, &len);
2527 if ((k = key_from_blob(cert, len)) == NULL)
2528 fatal("Certificate parse failed");
2529 free(cert);
2530 key_add_private(k);
2531 if ((exponent = BN_new()) == NULL)
2532 fatal("%s: BN_new failed", __func__);
2533 buffer_get_bignum2(blob, exponent);
2534 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
2535 fatal("%s: EC_KEY_set_private_key failed",
2536 __func__);
2537 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2538 EC_KEY_get0_public_key(k->ecdsa)) != 0 ||
2539 key_ec_validate_private(k->ecdsa) != 0)
2540 fatal("%s: bad ECDSA key", __func__);
2541 BN_clear_free(exponent);
2542 break;
2543#endif
2544 case KEY_RSA:
2545 k = key_new_private(type);
2546 buffer_get_bignum2(blob, k->rsa->n);
2547 buffer_get_bignum2(blob, k->rsa->e);
2548 buffer_get_bignum2(blob, k->rsa->d);
2549 buffer_get_bignum2(blob, k->rsa->iqmp);
2550 buffer_get_bignum2(blob, k->rsa->p);
2551 buffer_get_bignum2(blob, k->rsa->q);
2552
2553 /* Generate additional parameters */
2554 rsa_generate_additional_parameters(k->rsa);
2555 break;
2556 case KEY_RSA_CERT_V00:
2557 case KEY_RSA_CERT:
2558 cert = buffer_get_string(blob, &len);
2559 if ((k = key_from_blob(cert, len)) == NULL)
2560 fatal("Certificate parse failed");
2561 free(cert);
2562 key_add_private(k);
2563 buffer_get_bignum2(blob, k->rsa->d);
2564 buffer_get_bignum2(blob, k->rsa->iqmp);
2565 buffer_get_bignum2(blob, k->rsa->p);
2566 buffer_get_bignum2(blob, k->rsa->q);
2567 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11002568 case KEY_ED25519:
2569 k = key_new_private(type);
2570 k->ed25519_pk = buffer_get_string(blob, &pklen);
2571 k->ed25519_sk = buffer_get_string(blob, &sklen);
2572 if (pklen != ED25519_PK_SZ)
2573 fatal("%s: ed25519 pklen %d != %d",
2574 __func__, pklen, ED25519_PK_SZ);
2575 if (sklen != ED25519_SK_SZ)
2576 fatal("%s: ed25519 sklen %d != %d",
2577 __func__, sklen, ED25519_SK_SZ);
2578 break;
2579 case KEY_ED25519_CERT:
2580 cert = buffer_get_string(blob, &len);
2581 if ((k = key_from_blob(cert, len)) == NULL)
2582 fatal("Certificate parse failed");
2583 free(cert);
2584 key_add_private(k);
2585 k->ed25519_pk = buffer_get_string(blob, &pklen);
2586 k->ed25519_sk = buffer_get_string(blob, &sklen);
2587 if (pklen != ED25519_PK_SZ)
2588 fatal("%s: ed25519 pklen %d != %d",
2589 __func__, pklen, ED25519_PK_SZ);
2590 if (sklen != ED25519_SK_SZ)
2591 fatal("%s: ed25519 sklen %d != %d",
2592 __func__, sklen, ED25519_SK_SZ);
2593 break;
Damien Millerf0e90602013-12-07 10:40:26 +11002594 default:
2595 free(type_name);
2596 buffer_clear(blob);
2597 return NULL;
2598 }
2599 free(type_name);
2600
2601 /* enable blinding */
2602 switch (k->type) {
2603 case KEY_RSA:
2604 case KEY_RSA_CERT_V00:
2605 case KEY_RSA_CERT:
2606 case KEY_RSA1:
2607 if (RSA_blinding_on(k->rsa, NULL) != 1) {
2608 error("%s: RSA_blinding_on failed", __func__);
2609 key_free(k);
2610 return NULL;
2611 }
2612 break;
2613 }
2614 return k;
2615}