blob: b0bb46f3d6e12ab536d1dd2548a63c76bb7340c8 [file] [log] [blame]
Damien Miller29ace1c2013-12-29 17:49:31 +11001/* $OpenBSD: key.c,v 1.114 2013/12/29 04:20:04 djm 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 Miller29ace1c2013-12-29 17:49:31 +11001094static int
1095key_type_is_valid_ca(int type)
1096{
1097 switch (type) {
1098 case KEY_RSA:
1099 case KEY_DSA:
1100 case KEY_ECDSA:
1101 case KEY_ED25519:
1102 return 1;
1103 default:
1104 return 0;
1105 }
1106}
1107
Damien Miller0bc1bd82000-11-13 22:57:25 +11001108u_int
Damien Millerf58b58c2003-11-17 21:18:23 +11001109key_size(const Key *k)
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001110{
Damien Millerad833b32000-08-23 10:46:23 +10001111 switch (k->type) {
Damien Miller0bc1bd82000-11-13 22:57:25 +11001112 case KEY_RSA1:
Damien Millerad833b32000-08-23 10:46:23 +10001113 case KEY_RSA:
Damien Miller4e270b02010-04-16 15:56:21 +10001114 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001115 case KEY_RSA_CERT:
Damien Millerad833b32000-08-23 10:46:23 +10001116 return BN_num_bits(k->rsa->n);
Damien Millerad833b32000-08-23 10:46:23 +10001117 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +10001118 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001119 case KEY_DSA_CERT:
Damien Millerad833b32000-08-23 10:46:23 +10001120 return BN_num_bits(k->dsa->p);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001121 case KEY_ED25519:
1122 return 256; /* XXX */
Damien Miller6af914a2010-09-10 11:39:26 +10001123#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001124 case KEY_ECDSA:
1125 case KEY_ECDSA_CERT:
Damien Miller041ab7c2010-09-10 11:23:34 +10001126 return key_curve_nid_to_bits(k->ecdsa_nid);
Damien Miller6af914a2010-09-10 11:39:26 +10001127#endif
Damien Millerad833b32000-08-23 10:46:23 +10001128 }
1129 return 0;
1130}
Damien Miller0bc1bd82000-11-13 22:57:25 +11001131
Ben Lindstrombba81212001-06-25 05:01:22 +00001132static RSA *
Ben Lindstrom46c16222000-12-22 01:43:59 +00001133rsa_generate_private_key(u_int bits)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001134{
Damien Miller4499f4c2010-11-20 15:15:49 +11001135 RSA *private = RSA_new();
1136 BIGNUM *f4 = BN_new();
Damien Miller69b72032006-03-26 14:02:35 +11001137
Kevin Stevesef4eea92001-02-05 12:42:17 +00001138 if (private == NULL)
Damien Miller4499f4c2010-11-20 15:15:49 +11001139 fatal("%s: RSA_new failed", __func__);
1140 if (f4 == NULL)
1141 fatal("%s: BN_new failed", __func__);
1142 if (!BN_set_word(f4, RSA_F4))
1143 fatal("%s: BN_new failed", __func__);
1144 if (!RSA_generate_key_ex(private, bits, f4, NULL))
1145 fatal("%s: key generation failed.", __func__);
1146 BN_free(f4);
Kevin Stevesef4eea92001-02-05 12:42:17 +00001147 return private;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001148}
1149
Ben Lindstrombba81212001-06-25 05:01:22 +00001150static DSA*
Ben Lindstrom46c16222000-12-22 01:43:59 +00001151dsa_generate_private_key(u_int bits)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001152{
Damien Miller4499f4c2010-11-20 15:15:49 +11001153 DSA *private = DSA_new();
Damien Miller69b72032006-03-26 14:02:35 +11001154
Damien Miller0bc1bd82000-11-13 22:57:25 +11001155 if (private == NULL)
Damien Miller4499f4c2010-11-20 15:15:49 +11001156 fatal("%s: DSA_new failed", __func__);
1157 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
1158 NULL, NULL))
1159 fatal("%s: DSA_generate_parameters failed", __func__);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001160 if (!DSA_generate_key(private))
Damien Miller4499f4c2010-11-20 15:15:49 +11001161 fatal("%s: DSA_generate_key failed.", __func__);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001162 return private;
1163}
1164
Damien Millereb8b60e2010-08-31 22:41:14 +10001165int
1166key_ecdsa_bits_to_nid(int bits)
1167{
1168 switch (bits) {
Damien Miller6af914a2010-09-10 11:39:26 +10001169#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001170 case 256:
1171 return NID_X9_62_prime256v1;
1172 case 384:
1173 return NID_secp384r1;
Darren Tucker2c894302013-11-10 12:38:42 +11001174# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10001175 case 521:
1176 return NID_secp521r1;
Darren Tucker37bcef52013-11-09 18:39:25 +11001177# endif
Damien Miller6af914a2010-09-10 11:39:26 +10001178#endif
Damien Millereb8b60e2010-08-31 22:41:14 +10001179 default:
1180 return -1;
1181 }
1182}
1183
Damien Miller6af914a2010-09-10 11:39:26 +10001184#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001185int
Damien Millerb472a902010-11-05 10:19:49 +11001186key_ecdsa_key_to_nid(EC_KEY *k)
Damien Millereb8b60e2010-08-31 22:41:14 +10001187{
1188 EC_GROUP *eg;
1189 int nids[] = {
1190 NID_X9_62_prime256v1,
1191 NID_secp384r1,
Darren Tucker37bcef52013-11-09 18:39:25 +11001192# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10001193 NID_secp521r1,
Darren Tucker37bcef52013-11-09 18:39:25 +11001194# endif
Damien Millereb8b60e2010-08-31 22:41:14 +10001195 -1
1196 };
Damien Millerb472a902010-11-05 10:19:49 +11001197 int nid;
Damien Millereb8b60e2010-08-31 22:41:14 +10001198 u_int i;
1199 BN_CTX *bnctx;
Damien Millerb472a902010-11-05 10:19:49 +11001200 const EC_GROUP *g = EC_KEY_get0_group(k);
Damien Millereb8b60e2010-08-31 22:41:14 +10001201
Damien Millerb472a902010-11-05 10:19:49 +11001202 /*
1203 * The group may be stored in a ASN.1 encoded private key in one of two
1204 * ways: as a "named group", which is reconstituted by ASN.1 object ID
1205 * or explicit group parameters encoded into the key blob. Only the
1206 * "named group" case sets the group NID for us, but we can figure
1207 * it out for the other case by comparing against all the groups that
1208 * are supported.
1209 */
1210 if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1211 return nid;
Damien Millereb8b60e2010-08-31 22:41:14 +10001212 if ((bnctx = BN_CTX_new()) == NULL)
1213 fatal("%s: BN_CTX_new() failed", __func__);
1214 for (i = 0; nids[i] != -1; i++) {
1215 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
1216 fatal("%s: EC_GROUP_new_by_curve_name failed",
1217 __func__);
Damien Millerb472a902010-11-05 10:19:49 +11001218 if (EC_GROUP_cmp(g, eg, bnctx) == 0)
Damien Millereb8b60e2010-08-31 22:41:14 +10001219 break;
Damien Millereb8b60e2010-08-31 22:41:14 +10001220 EC_GROUP_free(eg);
1221 }
1222 BN_CTX_free(bnctx);
1223 debug3("%s: nid = %d", __func__, nids[i]);
Damien Millerb472a902010-11-05 10:19:49 +11001224 if (nids[i] != -1) {
1225 /* Use the group with the NID attached */
1226 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1227 if (EC_KEY_set_group(k, eg) != 1)
1228 fatal("%s: EC_KEY_set_group", __func__);
1229 }
Damien Millereb8b60e2010-08-31 22:41:14 +10001230 return nids[i];
1231}
1232
1233static EC_KEY*
1234ecdsa_generate_private_key(u_int bits, int *nid)
1235{
1236 EC_KEY *private;
1237
1238 if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1)
1239 fatal("%s: invalid key length", __func__);
1240 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL)
1241 fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
1242 if (EC_KEY_generate_key(private) != 1)
1243 fatal("%s: EC_KEY_generate_key failed", __func__);
Damien Millerb472a902010-11-05 10:19:49 +11001244 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
Damien Millereb8b60e2010-08-31 22:41:14 +10001245 return private;
1246}
Damien Miller6af914a2010-09-10 11:39:26 +10001247#endif /* OPENSSL_HAS_ECC */
Damien Millereb8b60e2010-08-31 22:41:14 +10001248
Damien Miller0bc1bd82000-11-13 22:57:25 +11001249Key *
Ben Lindstrom46c16222000-12-22 01:43:59 +00001250key_generate(int type, u_int bits)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001251{
1252 Key *k = key_new(KEY_UNSPEC);
1253 switch (type) {
Kevin Stevesef4eea92001-02-05 12:42:17 +00001254 case KEY_DSA:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001255 k->dsa = dsa_generate_private_key(bits);
1256 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001257#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001258 case KEY_ECDSA:
1259 k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid);
1260 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001261#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001262 case KEY_RSA:
1263 case KEY_RSA1:
1264 k->rsa = rsa_generate_private_key(bits);
1265 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001266 case KEY_ED25519:
1267 k->ed25519_pk = xmalloc(ED25519_PK_SZ);
1268 k->ed25519_sk = xmalloc(ED25519_SK_SZ);
1269 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
1270 break;
Damien Miller4e270b02010-04-16 15:56:21 +10001271 case KEY_RSA_CERT_V00:
1272 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001273 case KEY_RSA_CERT:
1274 case KEY_DSA_CERT:
1275 fatal("key_generate: cert keys cannot be generated directly");
Damien Miller0bc1bd82000-11-13 22:57:25 +11001276 default:
Kevin Stevesef4eea92001-02-05 12:42:17 +00001277 fatal("key_generate: unknown type %d", type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001278 }
Kevin Stevesef4eea92001-02-05 12:42:17 +00001279 k->type = type;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001280 return k;
1281}
1282
Damien Miller0a80ca12010-02-27 07:55:05 +11001283void
1284key_cert_copy(const Key *from_key, struct Key *to_key)
1285{
1286 u_int i;
1287 const struct KeyCert *from;
1288 struct KeyCert *to;
1289
1290 if (to_key->cert != NULL) {
1291 cert_free(to_key->cert);
1292 to_key->cert = NULL;
1293 }
1294
1295 if ((from = from_key->cert) == NULL)
1296 return;
1297
1298 to = to_key->cert = cert_new();
1299
1300 buffer_append(&to->certblob, buffer_ptr(&from->certblob),
1301 buffer_len(&from->certblob));
1302
Damien Miller4e270b02010-04-16 15:56:21 +10001303 buffer_append(&to->critical,
1304 buffer_ptr(&from->critical), buffer_len(&from->critical));
1305 buffer_append(&to->extensions,
1306 buffer_ptr(&from->extensions), buffer_len(&from->extensions));
Damien Miller0a80ca12010-02-27 07:55:05 +11001307
Damien Miller4e270b02010-04-16 15:56:21 +10001308 to->serial = from->serial;
Damien Miller0a80ca12010-02-27 07:55:05 +11001309 to->type = from->type;
1310 to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
1311 to->valid_after = from->valid_after;
1312 to->valid_before = from->valid_before;
1313 to->signature_key = from->signature_key == NULL ?
1314 NULL : key_from_private(from->signature_key);
1315
1316 to->nprincipals = from->nprincipals;
1317 if (to->nprincipals > CERT_MAX_PRINCIPALS)
1318 fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)",
1319 __func__, to->nprincipals, CERT_MAX_PRINCIPALS);
1320 if (to->nprincipals > 0) {
1321 to->principals = xcalloc(from->nprincipals,
1322 sizeof(*to->principals));
1323 for (i = 0; i < to->nprincipals; i++)
1324 to->principals[i] = xstrdup(from->principals[i]);
1325 }
1326}
1327
Damien Miller0bc1bd82000-11-13 22:57:25 +11001328Key *
Damien Millerf58b58c2003-11-17 21:18:23 +11001329key_from_private(const Key *k)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001330{
1331 Key *n = NULL;
1332 switch (k->type) {
Kevin Stevesef4eea92001-02-05 12:42:17 +00001333 case KEY_DSA:
Damien Miller4e270b02010-04-16 15:56:21 +10001334 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001335 case KEY_DSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001336 n = key_new(k->type);
Darren Tucker0bc85572006-11-07 23:14:41 +11001337 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
1338 (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1339 (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1340 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL))
1341 fatal("key_from_private: BN_copy failed");
Damien Miller0bc1bd82000-11-13 22:57:25 +11001342 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001343#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001344 case KEY_ECDSA:
1345 case KEY_ECDSA_CERT:
1346 n = key_new(k->type);
1347 n->ecdsa_nid = k->ecdsa_nid;
1348 if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)
1349 fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
1350 if (EC_KEY_set_public_key(n->ecdsa,
1351 EC_KEY_get0_public_key(k->ecdsa)) != 1)
1352 fatal("%s: EC_KEY_set_public_key failed", __func__);
1353 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001354#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001355 case KEY_RSA:
1356 case KEY_RSA1:
Damien Miller4e270b02010-04-16 15:56:21 +10001357 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001358 case KEY_RSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001359 n = key_new(k->type);
Darren Tucker0bc85572006-11-07 23:14:41 +11001360 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
1361 (BN_copy(n->rsa->e, k->rsa->e) == NULL))
1362 fatal("key_from_private: BN_copy failed");
Damien Miller0bc1bd82000-11-13 22:57:25 +11001363 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001364 case KEY_ED25519:
1365 case KEY_ED25519_CERT:
1366 n = key_new(k->type);
1367 if (k->ed25519_pk != NULL) {
1368 n->ed25519_pk = xmalloc(ED25519_PK_SZ);
1369 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1370 }
1371 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001372 default:
Kevin Stevesef4eea92001-02-05 12:42:17 +00001373 fatal("key_from_private: unknown type %d", k->type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001374 break;
1375 }
Damien Miller0a80ca12010-02-27 07:55:05 +11001376 if (key_is_cert(k))
1377 key_cert_copy(k, n);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001378 return n;
1379}
1380
1381int
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001382key_names_valid2(const char *names)
1383{
1384 char *s, *cp, *p;
1385
1386 if (names == NULL || strcmp(names, "") == 0)
1387 return 0;
1388 s = cp = xstrdup(names);
1389 for ((p = strsep(&cp, ",")); p && *p != '\0';
Damien Miller9f0f5c62001-12-21 14:45:46 +11001390 (p = strsep(&cp, ","))) {
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001391 switch (key_type_from_name(p)) {
1392 case KEY_RSA1:
1393 case KEY_UNSPEC:
Darren Tuckera627d422013-06-02 07:31:17 +10001394 free(s);
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001395 return 0;
1396 }
1397 }
1398 debug3("key names ok: [%s]", names);
Darren Tuckera627d422013-06-02 07:31:17 +10001399 free(s);
Ben Lindstrom982dbbc2001-04-17 18:11:36 +00001400 return 1;
1401}
1402
Damien Miller0a80ca12010-02-27 07:55:05 +11001403static int
1404cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
1405{
Damien Miller4e270b02010-04-16 15:56:21 +10001406 u_char *principals, *critical, *exts, *sig_key, *sig;
1407 u_int signed_len, plen, clen, sklen, slen, kidlen, elen;
Damien Miller0a80ca12010-02-27 07:55:05 +11001408 Buffer tmp;
1409 char *principal;
1410 int ret = -1;
Damien Miller4e270b02010-04-16 15:56:21 +10001411 int v00 = key->type == KEY_DSA_CERT_V00 ||
1412 key->type == KEY_RSA_CERT_V00;
Damien Miller0a80ca12010-02-27 07:55:05 +11001413
1414 buffer_init(&tmp);
1415
1416 /* Copy the entire key blob for verification and later serialisation */
1417 buffer_append(&key->cert->certblob, blob, blen);
1418
Damien Miller4e270b02010-04-16 15:56:21 +10001419 elen = 0; /* Not touched for v00 certs */
1420 principals = exts = critical = sig_key = sig = NULL;
1421 if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) ||
1422 buffer_get_int_ret(&key->cert->type, b) != 0 ||
Damien Millerda108ec2010-08-31 22:36:39 +10001423 (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL ||
Damien Miller0a80ca12010-02-27 07:55:05 +11001424 (principals = buffer_get_string_ret(b, &plen)) == NULL ||
1425 buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
1426 buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
Damien Miller4e270b02010-04-16 15:56:21 +10001427 (critical = buffer_get_string_ret(b, &clen)) == NULL ||
1428 (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) ||
1429 (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */
1430 buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */
Damien Miller0a80ca12010-02-27 07:55:05 +11001431 (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
1432 error("%s: parse error", __func__);
1433 goto out;
1434 }
1435
1436 /* Signature is left in the buffer so we can calculate this length */
1437 signed_len = buffer_len(&key->cert->certblob) - buffer_len(b);
1438
1439 if ((sig = buffer_get_string_ret(b, &slen)) == NULL) {
1440 error("%s: parse error", __func__);
1441 goto out;
1442 }
1443
1444 if (key->cert->type != SSH2_CERT_TYPE_USER &&
1445 key->cert->type != SSH2_CERT_TYPE_HOST) {
1446 error("Unknown certificate type %u", key->cert->type);
1447 goto out;
1448 }
1449
1450 buffer_append(&tmp, principals, plen);
1451 while (buffer_len(&tmp) > 0) {
1452 if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) {
Damien Miller41396572010-03-04 21:51:11 +11001453 error("%s: Too many principals", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001454 goto out;
1455 }
Damien Millerda108ec2010-08-31 22:36:39 +10001456 if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) {
Damien Miller41396572010-03-04 21:51:11 +11001457 error("%s: Principals data invalid", __func__);
1458 goto out;
1459 }
Damien Miller0a80ca12010-02-27 07:55:05 +11001460 key->cert->principals = xrealloc(key->cert->principals,
1461 key->cert->nprincipals + 1, sizeof(*key->cert->principals));
1462 key->cert->principals[key->cert->nprincipals++] = principal;
1463 }
1464
1465 buffer_clear(&tmp);
1466
Damien Miller4e270b02010-04-16 15:56:21 +10001467 buffer_append(&key->cert->critical, critical, clen);
1468 buffer_append(&tmp, critical, clen);
Damien Miller0a80ca12010-02-27 07:55:05 +11001469 /* validate structure */
1470 while (buffer_len(&tmp) != 0) {
Damien Miller2befbad2010-03-04 21:52:18 +11001471 if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
1472 buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
Damien Miller4e270b02010-04-16 15:56:21 +10001473 error("%s: critical option data invalid", __func__);
1474 goto out;
1475 }
1476 }
1477 buffer_clear(&tmp);
1478
1479 buffer_append(&key->cert->extensions, exts, elen);
1480 buffer_append(&tmp, exts, elen);
1481 /* validate structure */
1482 while (buffer_len(&tmp) != 0) {
1483 if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
1484 buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
1485 error("%s: extension data invalid", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001486 goto out;
1487 }
1488 }
1489 buffer_clear(&tmp);
1490
Damien Miller4a3a9d42013-10-30 22:19:47 +11001491 if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0))
1492 == NULL) {
Damien Miller41396572010-03-04 21:51:11 +11001493 error("%s: Signature key invalid", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001494 goto out;
1495 }
Damien Miller29ace1c2013-12-29 17:49:31 +11001496 if (!key_type_is_valid_ca(key->cert->signature_key->type)) {
Damien Miller41396572010-03-04 21:51:11 +11001497 error("%s: Invalid signature key type %s (%d)", __func__,
Damien Miller0a80ca12010-02-27 07:55:05 +11001498 key_type(key->cert->signature_key),
1499 key->cert->signature_key->type);
1500 goto out;
1501 }
1502
1503 switch (key_verify(key->cert->signature_key, sig, slen,
1504 buffer_ptr(&key->cert->certblob), signed_len)) {
1505 case 1:
Damien Miller41396572010-03-04 21:51:11 +11001506 ret = 0;
Damien Miller0a80ca12010-02-27 07:55:05 +11001507 break; /* Good signature */
1508 case 0:
Damien Miller41396572010-03-04 21:51:11 +11001509 error("%s: Invalid signature on certificate", __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001510 goto out;
1511 case -1:
Damien Miller41396572010-03-04 21:51:11 +11001512 error("%s: Certificate signature verification failed",
1513 __func__);
Damien Miller0a80ca12010-02-27 07:55:05 +11001514 goto out;
1515 }
1516
Damien Miller0a80ca12010-02-27 07:55:05 +11001517 out:
1518 buffer_free(&tmp);
Darren Tuckera627d422013-06-02 07:31:17 +10001519 free(principals);
1520 free(critical);
1521 free(exts);
1522 free(sig_key);
1523 free(sig);
Damien Miller0a80ca12010-02-27 07:55:05 +11001524 return ret;
1525}
1526
Damien Miller4a3a9d42013-10-30 22:19:47 +11001527static Key *
1528key_from_blob2(const u_char *blob, u_int blen, int allow_cert)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001529{
1530 Buffer b;
Darren Tucker8ccb7392010-09-10 12:28:24 +10001531 int rlen, type;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001532 u_int len;
Damien Millereb8b60e2010-08-31 22:41:14 +10001533 char *ktype = NULL, *curve = NULL;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001534 u_char *pk = NULL;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001535 Key *key = NULL;
Damien Miller6af914a2010-09-10 11:39:26 +10001536#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001537 EC_POINT *q = NULL;
Darren Tucker8ccb7392010-09-10 12:28:24 +10001538 int nid = -1;
Damien Miller6af914a2010-09-10 11:39:26 +10001539#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001540
1541#ifdef DEBUG_PK
1542 dump_base64(stderr, blob, blen);
1543#endif
1544 buffer_init(&b);
1545 buffer_append(&b, blob, blen);
Damien Millerda108ec2010-08-31 22:36:39 +10001546 if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) {
Darren Tucker08d04fa2004-11-05 20:42:28 +11001547 error("key_from_blob: can't read key type");
1548 goto out;
1549 }
1550
Damien Miller0bc1bd82000-11-13 22:57:25 +11001551 type = key_type_from_name(ktype);
Damien Miller6af914a2010-09-10 11:39:26 +10001552#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001553 if (key_type_plain(type) == KEY_ECDSA)
1554 nid = key_ecdsa_nid_from_name(ktype);
Damien Miller6af914a2010-09-10 11:39:26 +10001555#endif
Damien Miller4a3a9d42013-10-30 22:19:47 +11001556 if (!allow_cert && key_type_is_cert(type)) {
1557 error("key_from_blob: certificate not allowed in this context");
1558 goto out;
1559 }
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001560 switch (type) {
Damien Miller0a80ca12010-02-27 07:55:05 +11001561 case KEY_RSA_CERT:
Damien Miller4e270b02010-04-16 15:56:21 +10001562 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1563 /* FALLTHROUGH */
1564 case KEY_RSA:
1565 case KEY_RSA_CERT_V00:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001566 key = key_new(type);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001567 if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
1568 buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
1569 error("key_from_blob: can't read rsa key");
Damien Miller0a80ca12010-02-27 07:55:05 +11001570 badkey:
Darren Tucker08d04fa2004-11-05 20:42:28 +11001571 key_free(key);
1572 key = NULL;
1573 goto out;
1574 }
Damien Miller0bc1bd82000-11-13 22:57:25 +11001575#ifdef DEBUG_PK
1576 RSA_print_fp(stderr, key->rsa, 8);
1577#endif
1578 break;
Damien Miller0a80ca12010-02-27 07:55:05 +11001579 case KEY_DSA_CERT:
Damien Miller4e270b02010-04-16 15:56:21 +10001580 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1581 /* FALLTHROUGH */
1582 case KEY_DSA:
1583 case KEY_DSA_CERT_V00:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001584 key = key_new(type);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001585 if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
1586 buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
1587 buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
1588 buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
1589 error("key_from_blob: can't read dsa key");
Damien Miller0a80ca12010-02-27 07:55:05 +11001590 goto badkey;
Darren Tucker08d04fa2004-11-05 20:42:28 +11001591 }
Damien Miller0bc1bd82000-11-13 22:57:25 +11001592#ifdef DEBUG_PK
1593 DSA_print_fp(stderr, key->dsa, 8);
1594#endif
1595 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001596#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001597 case KEY_ECDSA_CERT:
1598 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1599 /* FALLTHROUGH */
1600 case KEY_ECDSA:
1601 key = key_new(type);
1602 key->ecdsa_nid = nid;
1603 if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) {
1604 error("key_from_blob: can't read ecdsa curve");
1605 goto badkey;
1606 }
1607 if (key->ecdsa_nid != key_curve_name_to_nid(curve)) {
1608 error("key_from_blob: ecdsa curve doesn't match type");
1609 goto badkey;
1610 }
1611 if (key->ecdsa != NULL)
1612 EC_KEY_free(key->ecdsa);
1613 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
1614 == NULL)
1615 fatal("key_from_blob: EC_KEY_new_by_curve_name failed");
1616 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL)
1617 fatal("key_from_blob: EC_POINT_new failed");
1618 if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa),
1619 q) == -1) {
1620 error("key_from_blob: can't read ecdsa key point");
1621 goto badkey;
1622 }
1623 if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
1624 q) != 0)
1625 goto badkey;
1626 if (EC_KEY_set_public_key(key->ecdsa, q) != 1)
1627 fatal("key_from_blob: EC_KEY_set_public_key failed");
1628#ifdef DEBUG_PK
1629 key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
1630#endif
1631 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001632#endif /* OPENSSL_HAS_ECC */
Damien Miller5be9d9e2013-12-07 11:24:01 +11001633 case KEY_ED25519_CERT:
1634 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1635 /* FALLTHROUGH */
1636 case KEY_ED25519:
1637 if ((pk = buffer_get_string_ret(&b, &len)) == NULL) {
1638 error("key_from_blob: can't read ed25519 key");
1639 goto badkey;
1640 }
1641 if (len != ED25519_PK_SZ) {
1642 error("key_from_blob: ed25519 len %d != %d",
1643 len, ED25519_PK_SZ);
1644 goto badkey;
1645 }
1646 key = key_new(type);
1647 key->ed25519_pk = pk;
1648 pk = NULL;
1649 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001650 case KEY_UNSPEC:
1651 key = key_new(type);
1652 break;
1653 default:
1654 error("key_from_blob: cannot handle type %s", ktype);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001655 goto out;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001656 }
Damien Miller0a80ca12010-02-27 07:55:05 +11001657 if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) {
1658 error("key_from_blob: can't parse cert data");
1659 goto badkey;
1660 }
Damien Miller0bc1bd82000-11-13 22:57:25 +11001661 rlen = buffer_len(&b);
1662 if (key != NULL && rlen != 0)
1663 error("key_from_blob: remaining bytes in key blob %d", rlen);
Darren Tucker08d04fa2004-11-05 20:42:28 +11001664 out:
Darren Tuckera627d422013-06-02 07:31:17 +10001665 free(ktype);
1666 free(curve);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001667 free(pk);
Damien Miller6af914a2010-09-10 11:39:26 +10001668#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001669 if (q != NULL)
1670 EC_POINT_free(q);
Damien Miller6af914a2010-09-10 11:39:26 +10001671#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001672 buffer_free(&b);
1673 return key;
1674}
1675
Damien Miller4a3a9d42013-10-30 22:19:47 +11001676Key *
1677key_from_blob(const u_char *blob, u_int blen)
1678{
1679 return key_from_blob2(blob, blen, 1);
1680}
1681
Damien Millerf3747bf2013-01-18 11:44:04 +11001682static int
1683to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001684{
1685 Buffer b;
Damien Millerf3747bf2013-01-18 11:44:04 +11001686 int len, type;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001687
Damien Millerf7e8a872013-12-05 10:25:51 +11001688 if (blobp != NULL)
1689 *blobp = NULL;
1690 if (lenp != NULL)
1691 *lenp = 0;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001692 if (key == NULL) {
1693 error("key_to_blob: key == NULL");
1694 return 0;
1695 }
1696 buffer_init(&b);
Damien Millerf3747bf2013-01-18 11:44:04 +11001697 type = force_plain ? key_type_plain(key->type) : key->type;
1698 switch (type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001699 case KEY_DSA_CERT_V00:
1700 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001701 case KEY_DSA_CERT:
Damien Millereb8b60e2010-08-31 22:41:14 +10001702 case KEY_ECDSA_CERT:
Damien Miller0a80ca12010-02-27 07:55:05 +11001703 case KEY_RSA_CERT:
Damien Miller5be9d9e2013-12-07 11:24:01 +11001704 case KEY_ED25519_CERT:
Damien Miller0a80ca12010-02-27 07:55:05 +11001705 /* Use the existing blob */
1706 buffer_append(&b, buffer_ptr(&key->cert->certblob),
1707 buffer_len(&key->cert->certblob));
1708 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001709 case KEY_DSA:
Damien Millerf3747bf2013-01-18 11:44:04 +11001710 buffer_put_cstring(&b,
1711 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
Damien Miller0bc1bd82000-11-13 22:57:25 +11001712 buffer_put_bignum2(&b, key->dsa->p);
1713 buffer_put_bignum2(&b, key->dsa->q);
1714 buffer_put_bignum2(&b, key->dsa->g);
1715 buffer_put_bignum2(&b, key->dsa->pub_key);
1716 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001717#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001718 case KEY_ECDSA:
Damien Millerf3747bf2013-01-18 11:44:04 +11001719 buffer_put_cstring(&b,
1720 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
Damien Millereb8b60e2010-08-31 22:41:14 +10001721 buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid));
1722 buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa),
1723 EC_KEY_get0_public_key(key->ecdsa));
1724 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001725#endif
Damien Miller0bc1bd82000-11-13 22:57:25 +11001726 case KEY_RSA:
Damien Millerf3747bf2013-01-18 11:44:04 +11001727 buffer_put_cstring(&b,
1728 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
Damien Miller0bc1bd82000-11-13 22:57:25 +11001729 buffer_put_bignum2(&b, key->rsa->e);
Ben Lindstrombf555ba2001-01-18 02:04:35 +00001730 buffer_put_bignum2(&b, key->rsa->n);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001731 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001732 case KEY_ED25519:
1733 buffer_put_cstring(&b,
1734 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
1735 buffer_put_string(&b, key->ed25519_pk, ED25519_PK_SZ);
1736 break;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001737 default:
Ben Lindstrom99a30f12001-09-18 05:49:14 +00001738 error("key_to_blob: unsupported key type %d", key->type);
1739 buffer_free(&b);
1740 return 0;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001741 }
1742 len = buffer_len(&b);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001743 if (lenp != NULL)
1744 *lenp = len;
Ben Lindstrom2bf759c2002-07-07 22:13:31 +00001745 if (blobp != NULL) {
1746 *blobp = xmalloc(len);
1747 memcpy(*blobp, buffer_ptr(&b), len);
1748 }
1749 memset(buffer_ptr(&b), 0, len);
1750 buffer_free(&b);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001751 return len;
1752}
1753
1754int
Damien Millerf3747bf2013-01-18 11:44:04 +11001755key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
1756{
1757 return to_blob(key, blobp, lenp, 0);
1758}
1759
1760int
Damien Miller0bc1bd82000-11-13 22:57:25 +11001761key_sign(
Damien Millerf58b58c2003-11-17 21:18:23 +11001762 const Key *key,
Ben Lindstrom90fd8142002-02-26 18:09:42 +00001763 u_char **sigp, u_int *lenp,
Damien Millerf58b58c2003-11-17 21:18:23 +11001764 const u_char *data, u_int datalen)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001765{
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001766 switch (key->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001767 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001768 case KEY_DSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001769 case KEY_DSA:
1770 return ssh_dss_sign(key, sigp, lenp, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001771#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001772 case KEY_ECDSA_CERT:
1773 case KEY_ECDSA:
1774 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001775#endif
Damien Miller4e270b02010-04-16 15:56:21 +10001776 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001777 case KEY_RSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001778 case KEY_RSA:
1779 return ssh_rsa_sign(key, sigp, lenp, data, datalen);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001780 case KEY_ED25519:
1781 case KEY_ED25519_CERT:
1782 return ssh_ed25519_sign(key, sigp, lenp, data, datalen);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001783 default:
Darren Tucker5cb30ad2004-08-12 22:40:24 +10001784 error("key_sign: invalid key type %d", key->type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001785 return -1;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001786 }
1787}
1788
Ben Lindstrom01fff0c2002-06-06 20:54:07 +00001789/*
1790 * key_verify returns 1 for a correct signature, 0 for an incorrect signature
1791 * and -1 on error.
1792 */
Damien Miller0bc1bd82000-11-13 22:57:25 +11001793int
1794key_verify(
Damien Millerf58b58c2003-11-17 21:18:23 +11001795 const Key *key,
1796 const u_char *signature, u_int signaturelen,
1797 const u_char *data, u_int datalen)
Damien Miller0bc1bd82000-11-13 22:57:25 +11001798{
Ben Lindstrom5363aee2001-06-25 04:42:20 +00001799 if (signaturelen == 0)
1800 return -1;
1801
Ben Lindstrom1c37c6a2001-12-06 18:00:18 +00001802 switch (key->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001803 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001804 case KEY_DSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001805 case KEY_DSA:
1806 return ssh_dss_verify(key, signature, signaturelen, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001807#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001808 case KEY_ECDSA_CERT:
1809 case KEY_ECDSA:
1810 return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen);
Damien Miller6af914a2010-09-10 11:39:26 +10001811#endif
Damien Miller4e270b02010-04-16 15:56:21 +10001812 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001813 case KEY_RSA_CERT:
Damien Miller0bc1bd82000-11-13 22:57:25 +11001814 case KEY_RSA:
1815 return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
Damien Miller5be9d9e2013-12-07 11:24:01 +11001816 case KEY_ED25519:
1817 case KEY_ED25519_CERT:
1818 return ssh_ed25519_verify(key, signature, signaturelen, data, datalen);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001819 default:
Darren Tucker5cb30ad2004-08-12 22:40:24 +10001820 error("key_verify: invalid key type %d", key->type);
Damien Miller0bc1bd82000-11-13 22:57:25 +11001821 return -1;
Damien Miller0bc1bd82000-11-13 22:57:25 +11001822 }
1823}
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001824
1825/* Converts a private to a public key */
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001826Key *
Damien Millerf58b58c2003-11-17 21:18:23 +11001827key_demote(const Key *k)
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001828{
1829 Key *pk;
Ben Lindstrom6328ab32002-03-22 02:54:23 +00001830
Damien Miller07d86be2006-03-26 14:19:21 +11001831 pk = xcalloc(1, sizeof(*pk));
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001832 pk->type = k->type;
1833 pk->flags = k->flags;
Damien Millereb8b60e2010-08-31 22:41:14 +10001834 pk->ecdsa_nid = k->ecdsa_nid;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001835 pk->dsa = NULL;
Damien Millereb8b60e2010-08-31 22:41:14 +10001836 pk->ecdsa = NULL;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001837 pk->rsa = NULL;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001838 pk->ed25519_pk = NULL;
1839 pk->ed25519_sk = NULL;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001840
1841 switch (k->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001842 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001843 case KEY_RSA_CERT:
1844 key_cert_copy(k, pk);
1845 /* FALLTHROUGH */
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001846 case KEY_RSA1:
1847 case KEY_RSA:
1848 if ((pk->rsa = RSA_new()) == NULL)
1849 fatal("key_demote: RSA_new failed");
1850 if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL)
1851 fatal("key_demote: BN_dup failed");
1852 if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
1853 fatal("key_demote: BN_dup failed");
1854 break;
Damien Miller4e270b02010-04-16 15:56:21 +10001855 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001856 case KEY_DSA_CERT:
1857 key_cert_copy(k, pk);
1858 /* FALLTHROUGH */
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001859 case KEY_DSA:
1860 if ((pk->dsa = DSA_new()) == NULL)
1861 fatal("key_demote: DSA_new failed");
1862 if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL)
1863 fatal("key_demote: BN_dup failed");
1864 if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL)
1865 fatal("key_demote: BN_dup failed");
1866 if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL)
1867 fatal("key_demote: BN_dup failed");
1868 if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
1869 fatal("key_demote: BN_dup failed");
1870 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001871#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10001872 case KEY_ECDSA_CERT:
1873 key_cert_copy(k, pk);
1874 /* FALLTHROUGH */
1875 case KEY_ECDSA:
1876 if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL)
1877 fatal("key_demote: EC_KEY_new_by_curve_name failed");
1878 if (EC_KEY_set_public_key(pk->ecdsa,
1879 EC_KEY_get0_public_key(k->ecdsa)) != 1)
1880 fatal("key_demote: EC_KEY_set_public_key failed");
1881 break;
Damien Miller6af914a2010-09-10 11:39:26 +10001882#endif
Damien Miller5be9d9e2013-12-07 11:24:01 +11001883 case KEY_ED25519_CERT:
1884 key_cert_copy(k, pk);
1885 /* FALLTHROUGH */
1886 case KEY_ED25519:
1887 if (k->ed25519_pk != NULL) {
1888 pk->ed25519_pk = xmalloc(ED25519_PK_SZ);
1889 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1890 }
1891 break;
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001892 default:
Damien Miller5be9d9e2013-12-07 11:24:01 +11001893 fatal("key_demote: bad key type %d", k->type);
Ben Lindstroma674e8d2002-03-22 01:45:53 +00001894 break;
1895 }
1896
1897 return (pk);
1898}
Damien Miller0a80ca12010-02-27 07:55:05 +11001899
1900int
1901key_is_cert(const Key *k)
1902{
Damien Miller4e270b02010-04-16 15:56:21 +10001903 if (k == NULL)
1904 return 0;
Damien Miller4a3a9d42013-10-30 22:19:47 +11001905 return key_type_is_cert(k->type);
Damien Miller0a80ca12010-02-27 07:55:05 +11001906}
1907
1908/* Return the cert-less equivalent to a certified key type */
1909int
1910key_type_plain(int type)
1911{
1912 switch (type) {
Damien Miller4e270b02010-04-16 15:56:21 +10001913 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001914 case KEY_RSA_CERT:
1915 return KEY_RSA;
Damien Miller4e270b02010-04-16 15:56:21 +10001916 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11001917 case KEY_DSA_CERT:
1918 return KEY_DSA;
Damien Millereb8b60e2010-08-31 22:41:14 +10001919 case KEY_ECDSA_CERT:
1920 return KEY_ECDSA;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001921 case KEY_ED25519_CERT:
1922 return KEY_ED25519;
Damien Miller0a80ca12010-02-27 07:55:05 +11001923 default:
1924 return type;
1925 }
1926}
1927
Damien Miller5baeacf2013-12-29 17:48:55 +11001928/* Convert a plain key to their _CERT equivalent */
Damien Miller0a80ca12010-02-27 07:55:05 +11001929int
Damien Miller4e270b02010-04-16 15:56:21 +10001930key_to_certified(Key *k, int legacy)
Damien Miller0a80ca12010-02-27 07:55:05 +11001931{
1932 switch (k->type) {
1933 case KEY_RSA:
1934 k->cert = cert_new();
Damien Miller4e270b02010-04-16 15:56:21 +10001935 k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT;
Damien Miller0a80ca12010-02-27 07:55:05 +11001936 return 0;
1937 case KEY_DSA:
1938 k->cert = cert_new();
Damien Miller4e270b02010-04-16 15:56:21 +10001939 k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
Damien Miller0a80ca12010-02-27 07:55:05 +11001940 return 0;
Damien Millereb8b60e2010-08-31 22:41:14 +10001941 case KEY_ECDSA:
Damien Miller8f639fe2011-05-20 19:03:08 +10001942 if (legacy)
1943 fatal("%s: legacy ECDSA certificates are not supported",
1944 __func__);
Damien Millereb8b60e2010-08-31 22:41:14 +10001945 k->cert = cert_new();
1946 k->type = KEY_ECDSA_CERT;
1947 return 0;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001948 case KEY_ED25519:
1949 if (legacy)
1950 fatal("%s: legacy ED25519 certificates are not "
1951 "supported", __func__);
1952 k->cert = cert_new();
1953 k->type = KEY_ED25519_CERT;
1954 return 0;
Damien Miller0a80ca12010-02-27 07:55:05 +11001955 default:
1956 error("%s: key has incorrect type %s", __func__, key_type(k));
1957 return -1;
1958 }
1959}
1960
Damien Miller9de4fcd2013-12-29 17:49:13 +11001961/* Convert a certificate to its raw key equivalent */
Damien Miller0a80ca12010-02-27 07:55:05 +11001962int
1963key_drop_cert(Key *k)
1964{
Damien Miller5be9d9e2013-12-07 11:24:01 +11001965 if (!key_type_is_cert(k->type)) {
Damien Miller0a80ca12010-02-27 07:55:05 +11001966 error("%s: key has incorrect type %s", __func__, key_type(k));
1967 return -1;
1968 }
Damien Miller5be9d9e2013-12-07 11:24:01 +11001969 cert_free(k->cert);
Damien Millerca570a52013-12-07 11:29:09 +11001970 k->cert = NULL;
Damien Miller5be9d9e2013-12-07 11:24:01 +11001971 k->type = key_type_plain(k->type);
1972 return 0;
Damien Miller0a80ca12010-02-27 07:55:05 +11001973}
1974
Damien Miller5be9d9e2013-12-07 11:24:01 +11001975/* Sign a certified key, (re-)generating the signed certblob. */
Damien Miller0a80ca12010-02-27 07:55:05 +11001976int
1977key_certify(Key *k, Key *ca)
1978{
1979 Buffer principals;
1980 u_char *ca_blob, *sig_blob, nonce[32];
1981 u_int i, ca_len, sig_len;
1982
1983 if (k->cert == NULL) {
1984 error("%s: key lacks cert info", __func__);
1985 return -1;
1986 }
1987
1988 if (!key_is_cert(k)) {
1989 error("%s: certificate has unknown type %d", __func__,
1990 k->cert->type);
1991 return -1;
1992 }
1993
Damien Miller29ace1c2013-12-29 17:49:31 +11001994 if (!key_type_is_valid_ca(ca->type)) {
Damien Miller0a80ca12010-02-27 07:55:05 +11001995 error("%s: CA key has unsupported type %s", __func__,
1996 key_type(ca));
1997 return -1;
1998 }
1999
2000 key_to_blob(ca, &ca_blob, &ca_len);
2001
2002 buffer_clear(&k->cert->certblob);
2003 buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
2004
Damien Miller4e270b02010-04-16 15:56:21 +10002005 /* -v01 certs put nonce first */
Damien Miller0a5f0122011-02-04 11:47:01 +11002006 arc4random_buf(&nonce, sizeof(nonce));
2007 if (!key_cert_is_legacy(k))
Damien Miller4e270b02010-04-16 15:56:21 +10002008 buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
Damien Miller4e270b02010-04-16 15:56:21 +10002009
Damien Millerbcd00ab2013-12-07 10:41:55 +11002010 /* XXX this substantially duplicates to_blob(); refactor */
Damien Miller0a80ca12010-02-27 07:55:05 +11002011 switch (k->type) {
Damien Miller4e270b02010-04-16 15:56:21 +10002012 case KEY_DSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11002013 case KEY_DSA_CERT:
2014 buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
2015 buffer_put_bignum2(&k->cert->certblob, k->dsa->q);
2016 buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
2017 buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
2018 break;
Damien Miller6af914a2010-09-10 11:39:26 +10002019#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10002020 case KEY_ECDSA_CERT:
2021 buffer_put_cstring(&k->cert->certblob,
2022 key_curve_nid_to_name(k->ecdsa_nid));
2023 buffer_put_ecpoint(&k->cert->certblob,
2024 EC_KEY_get0_group(k->ecdsa),
2025 EC_KEY_get0_public_key(k->ecdsa));
2026 break;
Damien Miller6af914a2010-09-10 11:39:26 +10002027#endif
Damien Miller4e270b02010-04-16 15:56:21 +10002028 case KEY_RSA_CERT_V00:
Damien Miller0a80ca12010-02-27 07:55:05 +11002029 case KEY_RSA_CERT:
2030 buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
2031 buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
2032 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11002033 case KEY_ED25519_CERT:
2034 buffer_put_string(&k->cert->certblob,
2035 k->ed25519_pk, ED25519_PK_SZ);
2036 break;
Damien Miller0a80ca12010-02-27 07:55:05 +11002037 default:
2038 error("%s: key has incorrect type %s", __func__, key_type(k));
2039 buffer_clear(&k->cert->certblob);
Darren Tuckera627d422013-06-02 07:31:17 +10002040 free(ca_blob);
Damien Miller0a80ca12010-02-27 07:55:05 +11002041 return -1;
2042 }
2043
Damien Miller4e270b02010-04-16 15:56:21 +10002044 /* -v01 certs have a serial number next */
Damien Millereb8b60e2010-08-31 22:41:14 +10002045 if (!key_cert_is_legacy(k))
Damien Miller4e270b02010-04-16 15:56:21 +10002046 buffer_put_int64(&k->cert->certblob, k->cert->serial);
2047
Damien Miller0a80ca12010-02-27 07:55:05 +11002048 buffer_put_int(&k->cert->certblob, k->cert->type);
2049 buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
2050
2051 buffer_init(&principals);
2052 for (i = 0; i < k->cert->nprincipals; i++)
2053 buffer_put_cstring(&principals, k->cert->principals[i]);
2054 buffer_put_string(&k->cert->certblob, buffer_ptr(&principals),
2055 buffer_len(&principals));
2056 buffer_free(&principals);
2057
2058 buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
2059 buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
2060 buffer_put_string(&k->cert->certblob,
Damien Miller4e270b02010-04-16 15:56:21 +10002061 buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical));
Damien Miller0a80ca12010-02-27 07:55:05 +11002062
Damien Miller4e270b02010-04-16 15:56:21 +10002063 /* -v01 certs have non-critical options here */
Damien Millereb8b60e2010-08-31 22:41:14 +10002064 if (!key_cert_is_legacy(k)) {
Damien Miller4e270b02010-04-16 15:56:21 +10002065 buffer_put_string(&k->cert->certblob,
2066 buffer_ptr(&k->cert->extensions),
2067 buffer_len(&k->cert->extensions));
2068 }
2069
2070 /* -v00 certs put the nonce at the end */
Damien Millereb8b60e2010-08-31 22:41:14 +10002071 if (key_cert_is_legacy(k))
Damien Miller4e270b02010-04-16 15:56:21 +10002072 buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
2073
Damien Miller0a80ca12010-02-27 07:55:05 +11002074 buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
2075 buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
Darren Tuckera627d422013-06-02 07:31:17 +10002076 free(ca_blob);
Damien Miller0a80ca12010-02-27 07:55:05 +11002077
2078 /* Sign the whole mess */
2079 if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob),
2080 buffer_len(&k->cert->certblob)) != 0) {
2081 error("%s: signature operation failed", __func__);
2082 buffer_clear(&k->cert->certblob);
2083 return -1;
2084 }
2085 /* Append signature and we are done */
2086 buffer_put_string(&k->cert->certblob, sig_blob, sig_len);
Darren Tuckera627d422013-06-02 07:31:17 +10002087 free(sig_blob);
Damien Miller0a80ca12010-02-27 07:55:05 +11002088
2089 return 0;
2090}
2091
2092int
2093key_cert_check_authority(const Key *k, int want_host, int require_principal,
2094 const char *name, const char **reason)
2095{
2096 u_int i, principal_matches;
2097 time_t now = time(NULL);
2098
2099 if (want_host) {
2100 if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2101 *reason = "Certificate invalid: not a host certificate";
2102 return -1;
2103 }
2104 } else {
2105 if (k->cert->type != SSH2_CERT_TYPE_USER) {
2106 *reason = "Certificate invalid: not a user certificate";
2107 return -1;
2108 }
2109 }
2110 if (now < 0) {
2111 error("%s: system clock lies before epoch", __func__);
2112 *reason = "Certificate invalid: not yet valid";
2113 return -1;
2114 }
2115 if ((u_int64_t)now < k->cert->valid_after) {
2116 *reason = "Certificate invalid: not yet valid";
2117 return -1;
2118 }
2119 if ((u_int64_t)now >= k->cert->valid_before) {
2120 *reason = "Certificate invalid: expired";
2121 return -1;
2122 }
2123 if (k->cert->nprincipals == 0) {
2124 if (require_principal) {
2125 *reason = "Certificate lacks principal list";
2126 return -1;
2127 }
Damien Miller30da3442010-05-10 11:58:03 +10002128 } else if (name != NULL) {
Damien Miller0a80ca12010-02-27 07:55:05 +11002129 principal_matches = 0;
2130 for (i = 0; i < k->cert->nprincipals; i++) {
2131 if (strcmp(name, k->cert->principals[i]) == 0) {
2132 principal_matches = 1;
2133 break;
2134 }
2135 }
2136 if (!principal_matches) {
2137 *reason = "Certificate invalid: name is not a listed "
2138 "principal";
2139 return -1;
2140 }
2141 }
2142 return 0;
2143}
Damien Miller4e270b02010-04-16 15:56:21 +10002144
2145int
Damien Millerf3747bf2013-01-18 11:44:04 +11002146key_cert_is_legacy(const Key *k)
Damien Miller4e270b02010-04-16 15:56:21 +10002147{
2148 switch (k->type) {
2149 case KEY_DSA_CERT_V00:
2150 case KEY_RSA_CERT_V00:
2151 return 1;
2152 default:
2153 return 0;
2154 }
2155}
Damien Millereb8b60e2010-08-31 22:41:14 +10002156
Damien Miller041ab7c2010-09-10 11:23:34 +10002157/* XXX: these are really begging for a table-driven approach */
Damien Millereb8b60e2010-08-31 22:41:14 +10002158int
2159key_curve_name_to_nid(const char *name)
2160{
Damien Miller6af914a2010-09-10 11:39:26 +10002161#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10002162 if (strcmp(name, "nistp256") == 0)
2163 return NID_X9_62_prime256v1;
2164 else if (strcmp(name, "nistp384") == 0)
2165 return NID_secp384r1;
Darren Tucker37bcef52013-11-09 18:39:25 +11002166# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10002167 else if (strcmp(name, "nistp521") == 0)
2168 return NID_secp521r1;
Darren Tucker37bcef52013-11-09 18:39:25 +11002169# endif
Damien Miller6af914a2010-09-10 11:39:26 +10002170#endif
Damien Millereb8b60e2010-08-31 22:41:14 +10002171
2172 debug("%s: unsupported EC curve name \"%.100s\"", __func__, name);
2173 return -1;
2174}
2175
Damien Miller041ab7c2010-09-10 11:23:34 +10002176u_int
2177key_curve_nid_to_bits(int nid)
2178{
2179 switch (nid) {
Damien Miller6af914a2010-09-10 11:39:26 +10002180#ifdef OPENSSL_HAS_ECC
Damien Miller041ab7c2010-09-10 11:23:34 +10002181 case NID_X9_62_prime256v1:
2182 return 256;
2183 case NID_secp384r1:
2184 return 384;
Darren Tucker2c894302013-11-10 12:38:42 +11002185# ifdef OPENSSL_HAS_NISTP521
Damien Miller041ab7c2010-09-10 11:23:34 +10002186 case NID_secp521r1:
2187 return 521;
Darren Tucker37bcef52013-11-09 18:39:25 +11002188# endif
Damien Miller6af914a2010-09-10 11:39:26 +10002189#endif
Damien Miller041ab7c2010-09-10 11:23:34 +10002190 default:
2191 error("%s: unsupported EC curve nid %d", __func__, nid);
2192 return 0;
2193 }
2194}
2195
Damien Millereb8b60e2010-08-31 22:41:14 +10002196const char *
2197key_curve_nid_to_name(int nid)
2198{
Damien Miller6af914a2010-09-10 11:39:26 +10002199#ifdef OPENSSL_HAS_ECC
Damien Millereb8b60e2010-08-31 22:41:14 +10002200 if (nid == NID_X9_62_prime256v1)
2201 return "nistp256";
2202 else if (nid == NID_secp384r1)
2203 return "nistp384";
Darren Tucker37bcef52013-11-09 18:39:25 +11002204# ifdef OPENSSL_HAS_NISTP521
Damien Millereb8b60e2010-08-31 22:41:14 +10002205 else if (nid == NID_secp521r1)
2206 return "nistp521";
Darren Tucker37bcef52013-11-09 18:39:25 +11002207# endif
Damien Miller6af914a2010-09-10 11:39:26 +10002208#endif
Damien Millereb8b60e2010-08-31 22:41:14 +10002209 error("%s: unsupported EC curve nid %d", __func__, nid);
2210 return NULL;
2211}
2212
Damien Miller6af914a2010-09-10 11:39:26 +10002213#ifdef OPENSSL_HAS_ECC
Damien Miller041ab7c2010-09-10 11:23:34 +10002214const EVP_MD *
2215key_ec_nid_to_evpmd(int nid)
2216{
2217 int kbits = key_curve_nid_to_bits(nid);
2218
2219 if (kbits == 0)
2220 fatal("%s: invalid nid %d", __func__, nid);
2221 /* RFC5656 section 6.2.1 */
2222 if (kbits <= 256)
2223 return EVP_sha256();
2224 else if (kbits <= 384)
2225 return EVP_sha384();
2226 else
2227 return EVP_sha512();
2228}
2229
Damien Millereb8b60e2010-08-31 22:41:14 +10002230int
2231key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2232{
2233 BN_CTX *bnctx;
2234 EC_POINT *nq = NULL;
2235 BIGNUM *order, *x, *y, *tmp;
2236 int ret = -1;
2237
2238 if ((bnctx = BN_CTX_new()) == NULL)
2239 fatal("%s: BN_CTX_new failed", __func__);
2240 BN_CTX_start(bnctx);
2241
2242 /*
2243 * We shouldn't ever hit this case because bignum_get_ecpoint()
2244 * refuses to load GF2m points.
2245 */
2246 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2247 NID_X9_62_prime_field) {
2248 error("%s: group is not a prime field", __func__);
2249 goto out;
2250 }
2251
2252 /* Q != infinity */
2253 if (EC_POINT_is_at_infinity(group, public)) {
2254 error("%s: received degenerate public key (infinity)",
2255 __func__);
2256 goto out;
2257 }
2258
2259 if ((x = BN_CTX_get(bnctx)) == NULL ||
2260 (y = BN_CTX_get(bnctx)) == NULL ||
2261 (order = BN_CTX_get(bnctx)) == NULL ||
2262 (tmp = BN_CTX_get(bnctx)) == NULL)
2263 fatal("%s: BN_CTX_get failed", __func__);
2264
2265 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2266 if (EC_GROUP_get_order(group, order, bnctx) != 1)
2267 fatal("%s: EC_GROUP_get_order failed", __func__);
2268 if (EC_POINT_get_affine_coordinates_GFp(group, public,
2269 x, y, bnctx) != 1)
2270 fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__);
2271 if (BN_num_bits(x) <= BN_num_bits(order) / 2) {
2272 error("%s: public key x coordinate too small: "
2273 "bits(x) = %d, bits(order)/2 = %d", __func__,
2274 BN_num_bits(x), BN_num_bits(order) / 2);
2275 goto out;
2276 }
2277 if (BN_num_bits(y) <= BN_num_bits(order) / 2) {
2278 error("%s: public key y coordinate too small: "
2279 "bits(y) = %d, bits(order)/2 = %d", __func__,
2280 BN_num_bits(x), BN_num_bits(order) / 2);
2281 goto out;
2282 }
2283
2284 /* nQ == infinity (n == order of subgroup) */
2285 if ((nq = EC_POINT_new(group)) == NULL)
2286 fatal("%s: BN_CTX_tmp failed", __func__);
2287 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1)
2288 fatal("%s: EC_GROUP_mul failed", __func__);
2289 if (EC_POINT_is_at_infinity(group, nq) != 1) {
2290 error("%s: received degenerate public key (nQ != infinity)",
2291 __func__);
2292 goto out;
2293 }
2294
2295 /* x < order - 1, y < order - 1 */
2296 if (!BN_sub(tmp, order, BN_value_one()))
2297 fatal("%s: BN_sub failed", __func__);
2298 if (BN_cmp(x, tmp) >= 0) {
2299 error("%s: public key x coordinate >= group order - 1",
2300 __func__);
2301 goto out;
2302 }
2303 if (BN_cmp(y, tmp) >= 0) {
2304 error("%s: public key y coordinate >= group order - 1",
2305 __func__);
2306 goto out;
2307 }
2308 ret = 0;
2309 out:
2310 BN_CTX_free(bnctx);
2311 EC_POINT_free(nq);
2312 return ret;
2313}
2314
2315int
2316key_ec_validate_private(const EC_KEY *key)
2317{
2318 BN_CTX *bnctx;
2319 BIGNUM *order, *tmp;
2320 int ret = -1;
2321
2322 if ((bnctx = BN_CTX_new()) == NULL)
2323 fatal("%s: BN_CTX_new failed", __func__);
2324 BN_CTX_start(bnctx);
2325
2326 if ((order = BN_CTX_get(bnctx)) == NULL ||
2327 (tmp = BN_CTX_get(bnctx)) == NULL)
2328 fatal("%s: BN_CTX_get failed", __func__);
2329
2330 /* log2(private) > log2(order)/2 */
2331 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1)
2332 fatal("%s: EC_GROUP_get_order failed", __func__);
2333 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2334 BN_num_bits(order) / 2) {
2335 error("%s: private key too small: "
2336 "bits(y) = %d, bits(order)/2 = %d", __func__,
2337 BN_num_bits(EC_KEY_get0_private_key(key)),
2338 BN_num_bits(order) / 2);
2339 goto out;
2340 }
2341
2342 /* private < order - 1 */
2343 if (!BN_sub(tmp, order, BN_value_one()))
2344 fatal("%s: BN_sub failed", __func__);
2345 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) {
2346 error("%s: private key >= group order - 1", __func__);
2347 goto out;
2348 }
2349 ret = 0;
2350 out:
2351 BN_CTX_free(bnctx);
2352 return ret;
2353}
2354
2355#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK)
2356void
2357key_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
2358{
2359 BIGNUM *x, *y;
2360 BN_CTX *bnctx;
2361
2362 if (point == NULL) {
2363 fputs("point=(NULL)\n", stderr);
2364 return;
2365 }
2366 if ((bnctx = BN_CTX_new()) == NULL)
2367 fatal("%s: BN_CTX_new failed", __func__);
2368 BN_CTX_start(bnctx);
2369 if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL)
2370 fatal("%s: BN_CTX_get failed", __func__);
2371 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2372 NID_X9_62_prime_field)
2373 fatal("%s: group is not a prime field", __func__);
2374 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1)
2375 fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__);
2376 fputs("x=", stderr);
2377 BN_print_fp(stderr, x);
2378 fputs("\ny=", stderr);
2379 BN_print_fp(stderr, y);
2380 fputs("\n", stderr);
2381 BN_CTX_free(bnctx);
2382}
2383
2384void
2385key_dump_ec_key(const EC_KEY *key)
2386{
2387 const BIGNUM *exponent;
2388
2389 key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key));
2390 fputs("exponent=", stderr);
2391 if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
2392 fputs("(NULL)", stderr);
2393 else
2394 BN_print_fp(stderr, EC_KEY_get0_private_key(key));
2395 fputs("\n", stderr);
2396}
2397#endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */
Damien Miller6af914a2010-09-10 11:39:26 +10002398#endif /* OPENSSL_HAS_ECC */
Damien Millerf0e90602013-12-07 10:40:26 +11002399
2400void
2401key_private_serialize(const Key *key, Buffer *b)
2402{
2403 buffer_put_cstring(b, key_ssh_name(key));
2404 switch (key->type) {
2405 case KEY_RSA:
2406 buffer_put_bignum2(b, key->rsa->n);
2407 buffer_put_bignum2(b, key->rsa->e);
2408 buffer_put_bignum2(b, key->rsa->d);
2409 buffer_put_bignum2(b, key->rsa->iqmp);
2410 buffer_put_bignum2(b, key->rsa->p);
2411 buffer_put_bignum2(b, key->rsa->q);
2412 break;
2413 case KEY_RSA_CERT_V00:
2414 case KEY_RSA_CERT:
2415 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2416 fatal("%s: no cert/certblob", __func__);
2417 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2418 buffer_len(&key->cert->certblob));
2419 buffer_put_bignum2(b, key->rsa->d);
2420 buffer_put_bignum2(b, key->rsa->iqmp);
2421 buffer_put_bignum2(b, key->rsa->p);
2422 buffer_put_bignum2(b, key->rsa->q);
2423 break;
2424 case KEY_DSA:
2425 buffer_put_bignum2(b, key->dsa->p);
2426 buffer_put_bignum2(b, key->dsa->q);
2427 buffer_put_bignum2(b, key->dsa->g);
2428 buffer_put_bignum2(b, key->dsa->pub_key);
2429 buffer_put_bignum2(b, key->dsa->priv_key);
2430 break;
2431 case KEY_DSA_CERT_V00:
2432 case KEY_DSA_CERT:
2433 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2434 fatal("%s: no cert/certblob", __func__);
2435 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2436 buffer_len(&key->cert->certblob));
2437 buffer_put_bignum2(b, key->dsa->priv_key);
2438 break;
2439#ifdef OPENSSL_HAS_ECC
2440 case KEY_ECDSA:
2441 buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
2442 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
2443 EC_KEY_get0_public_key(key->ecdsa));
2444 buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
2445 break;
2446 case KEY_ECDSA_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_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
2452 break;
2453#endif /* OPENSSL_HAS_ECC */
Damien Miller5be9d9e2013-12-07 11:24:01 +11002454 case KEY_ED25519:
2455 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
2456 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
2457 break;
2458 case KEY_ED25519_CERT:
2459 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2460 fatal("%s: no cert/certblob", __func__);
2461 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2462 buffer_len(&key->cert->certblob));
2463 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
2464 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
2465 break;
Damien Millerf0e90602013-12-07 10:40:26 +11002466 }
2467}
2468
2469Key *
2470key_private_deserialize(Buffer *blob)
2471{
2472 char *type_name;
2473 Key *k = NULL;
2474 u_char *cert;
Damien Miller5be9d9e2013-12-07 11:24:01 +11002475 u_int len, pklen, sklen;
Damien Millerf0e90602013-12-07 10:40:26 +11002476 int type;
2477#ifdef OPENSSL_HAS_ECC
2478 char *curve;
2479 BIGNUM *exponent;
2480 EC_POINT *q;
2481#endif
2482
2483 type_name = buffer_get_string(blob, NULL);
2484 type = key_type_from_name(type_name);
2485 switch (type) {
2486 case KEY_DSA:
2487 k = key_new_private(type);
2488 buffer_get_bignum2(blob, k->dsa->p);
2489 buffer_get_bignum2(blob, k->dsa->q);
2490 buffer_get_bignum2(blob, k->dsa->g);
2491 buffer_get_bignum2(blob, k->dsa->pub_key);
2492 buffer_get_bignum2(blob, k->dsa->priv_key);
2493 break;
2494 case KEY_DSA_CERT_V00:
2495 case KEY_DSA_CERT:
2496 cert = buffer_get_string(blob, &len);
2497 if ((k = key_from_blob(cert, len)) == NULL)
2498 fatal("Certificate parse failed");
2499 free(cert);
2500 key_add_private(k);
2501 buffer_get_bignum2(blob, k->dsa->priv_key);
2502 break;
2503#ifdef OPENSSL_HAS_ECC
2504 case KEY_ECDSA:
2505 k = key_new_private(type);
2506 k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
2507 curve = buffer_get_string(blob, NULL);
2508 if (k->ecdsa_nid != key_curve_name_to_nid(curve))
2509 fatal("%s: curve names mismatch", __func__);
2510 free(curve);
2511 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
2512 if (k->ecdsa == NULL)
2513 fatal("%s: EC_KEY_new_by_curve_name failed",
2514 __func__);
2515 q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
2516 if (q == NULL)
2517 fatal("%s: BN_new failed", __func__);
2518 if ((exponent = BN_new()) == NULL)
2519 fatal("%s: BN_new failed", __func__);
2520 buffer_get_ecpoint(blob,
2521 EC_KEY_get0_group(k->ecdsa), q);
2522 buffer_get_bignum2(blob, exponent);
2523 if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
2524 fatal("%s: EC_KEY_set_public_key failed",
2525 __func__);
2526 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
2527 fatal("%s: EC_KEY_set_private_key failed",
2528 __func__);
2529 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2530 EC_KEY_get0_public_key(k->ecdsa)) != 0)
2531 fatal("%s: bad ECDSA public key", __func__);
2532 if (key_ec_validate_private(k->ecdsa) != 0)
2533 fatal("%s: bad ECDSA private key", __func__);
2534 BN_clear_free(exponent);
2535 EC_POINT_free(q);
2536 break;
2537 case KEY_ECDSA_CERT:
2538 cert = buffer_get_string(blob, &len);
2539 if ((k = key_from_blob(cert, len)) == NULL)
2540 fatal("Certificate parse failed");
2541 free(cert);
2542 key_add_private(k);
2543 if ((exponent = BN_new()) == NULL)
2544 fatal("%s: BN_new failed", __func__);
2545 buffer_get_bignum2(blob, exponent);
2546 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
2547 fatal("%s: EC_KEY_set_private_key failed",
2548 __func__);
2549 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2550 EC_KEY_get0_public_key(k->ecdsa)) != 0 ||
2551 key_ec_validate_private(k->ecdsa) != 0)
2552 fatal("%s: bad ECDSA key", __func__);
2553 BN_clear_free(exponent);
2554 break;
2555#endif
2556 case KEY_RSA:
2557 k = key_new_private(type);
2558 buffer_get_bignum2(blob, k->rsa->n);
2559 buffer_get_bignum2(blob, k->rsa->e);
2560 buffer_get_bignum2(blob, k->rsa->d);
2561 buffer_get_bignum2(blob, k->rsa->iqmp);
2562 buffer_get_bignum2(blob, k->rsa->p);
2563 buffer_get_bignum2(blob, k->rsa->q);
2564
2565 /* Generate additional parameters */
2566 rsa_generate_additional_parameters(k->rsa);
2567 break;
2568 case KEY_RSA_CERT_V00:
2569 case KEY_RSA_CERT:
2570 cert = buffer_get_string(blob, &len);
2571 if ((k = key_from_blob(cert, len)) == NULL)
2572 fatal("Certificate parse failed");
2573 free(cert);
2574 key_add_private(k);
2575 buffer_get_bignum2(blob, k->rsa->d);
2576 buffer_get_bignum2(blob, k->rsa->iqmp);
2577 buffer_get_bignum2(blob, k->rsa->p);
2578 buffer_get_bignum2(blob, k->rsa->q);
2579 break;
Damien Miller5be9d9e2013-12-07 11:24:01 +11002580 case KEY_ED25519:
2581 k = key_new_private(type);
2582 k->ed25519_pk = buffer_get_string(blob, &pklen);
2583 k->ed25519_sk = buffer_get_string(blob, &sklen);
2584 if (pklen != ED25519_PK_SZ)
2585 fatal("%s: ed25519 pklen %d != %d",
2586 __func__, pklen, ED25519_PK_SZ);
2587 if (sklen != ED25519_SK_SZ)
2588 fatal("%s: ed25519 sklen %d != %d",
2589 __func__, sklen, ED25519_SK_SZ);
2590 break;
2591 case KEY_ED25519_CERT:
2592 cert = buffer_get_string(blob, &len);
2593 if ((k = key_from_blob(cert, len)) == NULL)
2594 fatal("Certificate parse failed");
2595 free(cert);
2596 key_add_private(k);
2597 k->ed25519_pk = buffer_get_string(blob, &pklen);
2598 k->ed25519_sk = buffer_get_string(blob, &sklen);
2599 if (pklen != ED25519_PK_SZ)
2600 fatal("%s: ed25519 pklen %d != %d",
2601 __func__, pklen, ED25519_PK_SZ);
2602 if (sklen != ED25519_SK_SZ)
2603 fatal("%s: ed25519 sklen %d != %d",
2604 __func__, sklen, ED25519_SK_SZ);
2605 break;
Damien Millerf0e90602013-12-07 10:40:26 +11002606 default:
2607 free(type_name);
2608 buffer_clear(blob);
2609 return NULL;
2610 }
2611 free(type_name);
2612
2613 /* enable blinding */
2614 switch (k->type) {
2615 case KEY_RSA:
2616 case KEY_RSA_CERT_V00:
2617 case KEY_RSA_CERT:
2618 case KEY_RSA1:
2619 if (RSA_blinding_on(k->rsa, NULL) != 1) {
2620 error("%s: RSA_blinding_on failed", __func__);
2621 key_free(k);
2622 return NULL;
2623 }
2624 break;
2625 }
2626 return k;
2627}