blob: 24023d0368752b793378ad703bf01bb79bcff061 [file] [log] [blame]
Damien Miller86687062014-07-02 15:28:02 +10001/* $OpenBSD: sshkey.c,v 1.2 2014/06/27 18:50:39 markus Exp $ */
2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
5 * Copyright (c) 2010,2011 Damien Miller. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "includes.h"
29
30#include <sys/param.h>
31#include <sys/types.h>
32
33#include <openssl/evp.h>
34#include <openssl/err.h>
35#include <openssl/pem.h>
36
37#include "crypto_api.h"
38
39#include <errno.h>
40#include <stdio.h>
41#include <string.h>
42#include <util.h>
43
44#include "ssh2.h"
45#include "ssherr.h"
46#include "misc.h"
47#include "sshbuf.h"
48#include "rsa.h"
49#include "cipher.h"
50#include "digest.h"
51#define SSHKEY_INTERNAL
52#include "sshkey.h"
53
54/* openssh private key file format */
55#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
56#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
57#define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1)
58#define MARK_END_LEN (sizeof(MARK_END) - 1)
59#define KDFNAME "bcrypt"
60#define AUTH_MAGIC "openssh-key-v1"
61#define SALT_LEN 16
62#define DEFAULT_CIPHERNAME "aes256-cbc"
63#define DEFAULT_ROUNDS 16
64
65/* Version identification string for SSH v1 identity files. */
66#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
67
68static int sshkey_from_blob_internal(const u_char *blob, size_t blen,
69 struct sshkey **keyp, int allow_cert);
70
71/* Supported key types */
72struct keytype {
73 const char *name;
74 const char *shortname;
75 int type;
76 int nid;
77 int cert;
78};
79static const struct keytype keytypes[] = {
80 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 },
81 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
82 KEY_ED25519_CERT, 0, 1 },
83#ifdef WITH_OPENSSL
84 { NULL, "RSA1", KEY_RSA1, 0, 0 },
85 { "ssh-rsa", "RSA", KEY_RSA, 0, 0 },
86 { "ssh-dss", "DSA", KEY_DSA, 0, 0 },
87# ifdef OPENSSL_HAS_ECC
88 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 },
89 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 },
90# ifdef OPENSSL_HAS_NISTP521
91 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 },
92# endif /* OPENSSL_HAS_NISTP521 */
93# endif /* OPENSSL_HAS_ECC */
94 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 },
95 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 },
96# ifdef OPENSSL_HAS_ECC
97 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
98 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 },
99 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
100 KEY_ECDSA_CERT, NID_secp384r1, 1 },
101# ifdef OPENSSL_HAS_NISTP521
102 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
103 KEY_ECDSA_CERT, NID_secp521r1, 1 },
104# endif /* OPENSSL_HAS_NISTP521 */
105# endif /* OPENSSL_HAS_ECC */
106 { "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00",
107 KEY_RSA_CERT_V00, 0, 1 },
108 { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00",
109 KEY_DSA_CERT_V00, 0, 1 },
110#endif /* WITH_OPENSSL */
111 { NULL, NULL, -1, -1, 0 }
112};
113
114const char *
115sshkey_type(const struct sshkey *k)
116{
117 const struct keytype *kt;
118
119 for (kt = keytypes; kt->type != -1; kt++) {
120 if (kt->type == k->type)
121 return kt->shortname;
122 }
123 return "unknown";
124}
125
126static const char *
127sshkey_ssh_name_from_type_nid(int type, int nid)
128{
129 const struct keytype *kt;
130
131 for (kt = keytypes; kt->type != -1; kt++) {
132 if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
133 return kt->name;
134 }
135 return "ssh-unknown";
136}
137
138int
139sshkey_type_is_cert(int type)
140{
141 const struct keytype *kt;
142
143 for (kt = keytypes; kt->type != -1; kt++) {
144 if (kt->type == type)
145 return kt->cert;
146 }
147 return 0;
148}
149
150const char *
151sshkey_ssh_name(const struct sshkey *k)
152{
153 return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
154}
155
156const char *
157sshkey_ssh_name_plain(const struct sshkey *k)
158{
159 return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type),
160 k->ecdsa_nid);
161}
162
163int
164sshkey_type_from_name(const char *name)
165{
166 const struct keytype *kt;
167
168 for (kt = keytypes; kt->type != -1; kt++) {
169 /* Only allow shortname matches for plain key types */
170 if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
171 (!kt->cert && strcasecmp(kt->shortname, name) == 0))
172 return kt->type;
173 }
174 return KEY_UNSPEC;
175}
176
177int
178sshkey_ecdsa_nid_from_name(const char *name)
179{
180 const struct keytype *kt;
181
182 for (kt = keytypes; kt->type != -1; kt++) {
183 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
184 continue;
185 if (kt->name != NULL && strcmp(name, kt->name) == 0)
186 return kt->nid;
187 }
188 return -1;
189}
190
191char *
192key_alg_list(int certs_only, int plain_only)
193{
194 char *tmp, *ret = NULL;
195 size_t nlen, rlen = 0;
196 const struct keytype *kt;
197
198 for (kt = keytypes; kt->type != -1; kt++) {
199 if (kt->name == NULL)
200 continue;
201 if ((certs_only && !kt->cert) || (plain_only && kt->cert))
202 continue;
203 if (ret != NULL)
204 ret[rlen++] = '\n';
205 nlen = strlen(kt->name);
206 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
207 free(ret);
208 return NULL;
209 }
210 ret = tmp;
211 memcpy(ret + rlen, kt->name, nlen + 1);
212 rlen += nlen;
213 }
214 return ret;
215}
216
217int
218sshkey_names_valid2(const char *names)
219{
220 char *s, *cp, *p;
221
222 if (names == NULL || strcmp(names, "") == 0)
223 return 0;
224 if ((s = cp = strdup(names)) == NULL)
225 return 0;
226 for ((p = strsep(&cp, ",")); p && *p != '\0';
227 (p = strsep(&cp, ","))) {
228 switch (sshkey_type_from_name(p)) {
229 case KEY_RSA1:
230 case KEY_UNSPEC:
231 free(s);
232 return 0;
233 }
234 }
235 free(s);
236 return 1;
237}
238
239u_int
240sshkey_size(const struct sshkey *k)
241{
242 switch (k->type) {
243#ifdef WITH_OPENSSL
244 case KEY_RSA1:
245 case KEY_RSA:
246 case KEY_RSA_CERT_V00:
247 case KEY_RSA_CERT:
248 return BN_num_bits(k->rsa->n);
249 case KEY_DSA:
250 case KEY_DSA_CERT_V00:
251 case KEY_DSA_CERT:
252 return BN_num_bits(k->dsa->p);
253 case KEY_ECDSA:
254 case KEY_ECDSA_CERT:
255 return sshkey_curve_nid_to_bits(k->ecdsa_nid);
256#endif /* WITH_OPENSSL */
257 case KEY_ED25519:
258 case KEY_ED25519_CERT:
259 return 256; /* XXX */
260 }
261 return 0;
262}
263
264int
265sshkey_cert_is_legacy(const struct sshkey *k)
266{
267 switch (k->type) {
268 case KEY_DSA_CERT_V00:
269 case KEY_RSA_CERT_V00:
270 return 1;
271 default:
272 return 0;
273 }
274}
275
276static int
277sshkey_type_is_valid_ca(int type)
278{
279 switch (type) {
280 case KEY_RSA:
281 case KEY_DSA:
282 case KEY_ECDSA:
283 case KEY_ED25519:
284 return 1;
285 default:
286 return 0;
287 }
288}
289
290int
291sshkey_is_cert(const struct sshkey *k)
292{
293 if (k == NULL)
294 return 0;
295 return sshkey_type_is_cert(k->type);
296}
297
298/* Return the cert-less equivalent to a certified key type */
299int
300sshkey_type_plain(int type)
301{
302 switch (type) {
303 case KEY_RSA_CERT_V00:
304 case KEY_RSA_CERT:
305 return KEY_RSA;
306 case KEY_DSA_CERT_V00:
307 case KEY_DSA_CERT:
308 return KEY_DSA;
309 case KEY_ECDSA_CERT:
310 return KEY_ECDSA;
311 case KEY_ED25519_CERT:
312 return KEY_ED25519;
313 default:
314 return type;
315 }
316}
317
318#ifdef WITH_OPENSSL
319/* XXX: these are really begging for a table-driven approach */
320int
321sshkey_curve_name_to_nid(const char *name)
322{
323 if (strcmp(name, "nistp256") == 0)
324 return NID_X9_62_prime256v1;
325 else if (strcmp(name, "nistp384") == 0)
326 return NID_secp384r1;
327# ifdef OPENSSL_HAS_NISTP521
328 else if (strcmp(name, "nistp521") == 0)
329 return NID_secp521r1;
330# endif /* OPENSSL_HAS_NISTP521 */
331 else
332 return -1;
333}
334
335u_int
336sshkey_curve_nid_to_bits(int nid)
337{
338 switch (nid) {
339 case NID_X9_62_prime256v1:
340 return 256;
341 case NID_secp384r1:
342 return 384;
343# ifdef OPENSSL_HAS_NISTP521
344 case NID_secp521r1:
345 return 521;
346# endif /* OPENSSL_HAS_NISTP521 */
347 default:
348 return 0;
349 }
350}
351
352int
353sshkey_ecdsa_bits_to_nid(int bits)
354{
355 switch (bits) {
356 case 256:
357 return NID_X9_62_prime256v1;
358 case 384:
359 return NID_secp384r1;
360# ifdef OPENSSL_HAS_NISTP521
361 case 521:
362 return NID_secp521r1;
363# endif /* OPENSSL_HAS_NISTP521 */
364 default:
365 return -1;
366 }
367}
368
369const char *
370sshkey_curve_nid_to_name(int nid)
371{
372 switch (nid) {
373 case NID_X9_62_prime256v1:
374 return "nistp256";
375 case NID_secp384r1:
376 return "nistp384";
377# ifdef OPENSSL_HAS_NISTP521
378 case NID_secp521r1:
379 return "nistp521";
380# endif /* OPENSSL_HAS_NISTP521 */
381 default:
382 return NULL;
383 }
384}
385
386int
387sshkey_ec_nid_to_hash_alg(int nid)
388{
389 int kbits = sshkey_curve_nid_to_bits(nid);
390
391 if (kbits <= 0)
392 return -1;
393
394 /* RFC5656 section 6.2.1 */
395 if (kbits <= 256)
396 return SSH_DIGEST_SHA256;
397 else if (kbits <= 384)
398 return SSH_DIGEST_SHA384;
399 else
400 return SSH_DIGEST_SHA512;
401}
402#endif /* WITH_OPENSSL */
403
404static void
405cert_free(struct sshkey_cert *cert)
406{
407 u_int i;
408
409 if (cert == NULL)
410 return;
411 if (cert->certblob != NULL)
412 sshbuf_free(cert->certblob);
413 if (cert->critical != NULL)
414 sshbuf_free(cert->critical);
415 if (cert->extensions != NULL)
416 sshbuf_free(cert->extensions);
417 if (cert->key_id != NULL)
418 free(cert->key_id);
419 for (i = 0; i < cert->nprincipals; i++)
420 free(cert->principals[i]);
421 if (cert->principals != NULL)
422 free(cert->principals);
423 if (cert->signature_key != NULL)
424 sshkey_free(cert->signature_key);
425 explicit_bzero(cert, sizeof(*cert));
426 free(cert);
427}
428
429static struct sshkey_cert *
430cert_new(void)
431{
432 struct sshkey_cert *cert;
433
434 if ((cert = calloc(1, sizeof(*cert))) == NULL)
435 return NULL;
436 if ((cert->certblob = sshbuf_new()) == NULL ||
437 (cert->critical = sshbuf_new()) == NULL ||
438 (cert->extensions = sshbuf_new()) == NULL) {
439 cert_free(cert);
440 return NULL;
441 }
442 cert->key_id = NULL;
443 cert->principals = NULL;
444 cert->signature_key = NULL;
445 return cert;
446}
447
448struct sshkey *
449sshkey_new(int type)
450{
451 struct sshkey *k;
452#ifdef WITH_OPENSSL
453 RSA *rsa;
454 DSA *dsa;
455#endif /* WITH_OPENSSL */
456
457 if ((k = calloc(1, sizeof(*k))) == NULL)
458 return NULL;
459 k->type = type;
460 k->ecdsa = NULL;
461 k->ecdsa_nid = -1;
462 k->dsa = NULL;
463 k->rsa = NULL;
464 k->cert = NULL;
465 k->ed25519_sk = NULL;
466 k->ed25519_pk = NULL;
467 switch (k->type) {
468#ifdef WITH_OPENSSL
469 case KEY_RSA1:
470 case KEY_RSA:
471 case KEY_RSA_CERT_V00:
472 case KEY_RSA_CERT:
473 if ((rsa = RSA_new()) == NULL ||
474 (rsa->n = BN_new()) == NULL ||
475 (rsa->e = BN_new()) == NULL) {
476 if (rsa != NULL)
477 RSA_free(rsa);
478 free(k);
479 return NULL;
480 }
481 k->rsa = rsa;
482 break;
483 case KEY_DSA:
484 case KEY_DSA_CERT_V00:
485 case KEY_DSA_CERT:
486 if ((dsa = DSA_new()) == NULL ||
487 (dsa->p = BN_new()) == NULL ||
488 (dsa->q = BN_new()) == NULL ||
489 (dsa->g = BN_new()) == NULL ||
490 (dsa->pub_key = BN_new()) == NULL) {
491 if (dsa != NULL)
492 DSA_free(dsa);
493 free(k);
494 return NULL;
495 }
496 k->dsa = dsa;
497 break;
498 case KEY_ECDSA:
499 case KEY_ECDSA_CERT:
500 /* Cannot do anything until we know the group */
501 break;
502#endif /* WITH_OPENSSL */
503 case KEY_ED25519:
504 case KEY_ED25519_CERT:
505 /* no need to prealloc */
506 break;
507 case KEY_UNSPEC:
508 break;
509 default:
510 free(k);
511 return NULL;
512 break;
513 }
514
515 if (sshkey_is_cert(k)) {
516 if ((k->cert = cert_new()) == NULL) {
517 sshkey_free(k);
518 return NULL;
519 }
520 }
521
522 return k;
523}
524
525int
526sshkey_add_private(struct sshkey *k)
527{
528 switch (k->type) {
529#ifdef WITH_OPENSSL
530 case KEY_RSA1:
531 case KEY_RSA:
532 case KEY_RSA_CERT_V00:
533 case KEY_RSA_CERT:
534#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
535 if (bn_maybe_alloc_failed(k->rsa->d) ||
536 bn_maybe_alloc_failed(k->rsa->iqmp) ||
537 bn_maybe_alloc_failed(k->rsa->q) ||
538 bn_maybe_alloc_failed(k->rsa->p) ||
539 bn_maybe_alloc_failed(k->rsa->dmq1) ||
540 bn_maybe_alloc_failed(k->rsa->dmp1))
541 return SSH_ERR_ALLOC_FAIL;
542 break;
543 case KEY_DSA:
544 case KEY_DSA_CERT_V00:
545 case KEY_DSA_CERT:
546 if (bn_maybe_alloc_failed(k->dsa->priv_key))
547 return SSH_ERR_ALLOC_FAIL;
548 break;
549#undef bn_maybe_alloc_failed
550 case KEY_ECDSA:
551 case KEY_ECDSA_CERT:
552 /* Cannot do anything until we know the group */
553 break;
554#endif /* WITH_OPENSSL */
555 case KEY_ED25519:
556 case KEY_ED25519_CERT:
557 /* no need to prealloc */
558 break;
559 case KEY_UNSPEC:
560 break;
561 default:
562 return SSH_ERR_INVALID_ARGUMENT;
563 }
564 return 0;
565}
566
567struct sshkey *
568sshkey_new_private(int type)
569{
570 struct sshkey *k = sshkey_new(type);
571
572 if (k == NULL)
573 return NULL;
574 if (sshkey_add_private(k) != 0) {
575 sshkey_free(k);
576 return NULL;
577 }
578 return k;
579}
580
581void
582sshkey_free(struct sshkey *k)
583{
584 if (k == NULL)
585 return;
586 switch (k->type) {
587#ifdef WITH_OPENSSL
588 case KEY_RSA1:
589 case KEY_RSA:
590 case KEY_RSA_CERT_V00:
591 case KEY_RSA_CERT:
592 if (k->rsa != NULL)
593 RSA_free(k->rsa);
594 k->rsa = NULL;
595 break;
596 case KEY_DSA:
597 case KEY_DSA_CERT_V00:
598 case KEY_DSA_CERT:
599 if (k->dsa != NULL)
600 DSA_free(k->dsa);
601 k->dsa = NULL;
602 break;
603# ifdef OPENSSL_HAS_ECC
604 case KEY_ECDSA:
605 case KEY_ECDSA_CERT:
606 if (k->ecdsa != NULL)
607 EC_KEY_free(k->ecdsa);
608 k->ecdsa = NULL;
609 break;
610# endif /* OPENSSL_HAS_ECC */
611#endif /* WITH_OPENSSL */
612 case KEY_ED25519:
613 case KEY_ED25519_CERT:
614 if (k->ed25519_pk) {
615 explicit_bzero(k->ed25519_pk, ED25519_PK_SZ);
616 free(k->ed25519_pk);
617 k->ed25519_pk = NULL;
618 }
619 if (k->ed25519_sk) {
620 explicit_bzero(k->ed25519_sk, ED25519_SK_SZ);
621 free(k->ed25519_sk);
622 k->ed25519_sk = NULL;
623 }
624 break;
625 case KEY_UNSPEC:
626 break;
627 default:
628 break;
629 }
630 if (sshkey_is_cert(k))
631 cert_free(k->cert);
632 explicit_bzero(k, sizeof(*k));
633 free(k);
634}
635
636static int
637cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
638{
639 if (a == NULL && b == NULL)
640 return 1;
641 if (a == NULL || b == NULL)
642 return 0;
643 if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob))
644 return 0;
645 if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob),
646 sshbuf_len(a->certblob)) != 0)
647 return 0;
648 return 1;
649}
650
651/*
652 * Compare public portions of key only, allowing comparisons between
653 * certificates and plain keys too.
654 */
655int
656sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
657{
658#ifdef WITH_OPENSSL
659 BN_CTX *bnctx;
660#endif /* WITH_OPENSSL */
661
662 if (a == NULL || b == NULL ||
663 sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
664 return 0;
665
666 switch (a->type) {
667#ifdef WITH_OPENSSL
668 case KEY_RSA1:
669 case KEY_RSA_CERT_V00:
670 case KEY_RSA_CERT:
671 case KEY_RSA:
672 return a->rsa != NULL && b->rsa != NULL &&
673 BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
674 BN_cmp(a->rsa->n, b->rsa->n) == 0;
675 case KEY_DSA_CERT_V00:
676 case KEY_DSA_CERT:
677 case KEY_DSA:
678 return a->dsa != NULL && b->dsa != NULL &&
679 BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
680 BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
681 BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
682 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
683# ifdef OPENSSL_HAS_ECC
684 case KEY_ECDSA_CERT:
685 case KEY_ECDSA:
686 if (a->ecdsa == NULL || b->ecdsa == NULL ||
687 EC_KEY_get0_public_key(a->ecdsa) == NULL ||
688 EC_KEY_get0_public_key(b->ecdsa) == NULL)
689 return 0;
690 if ((bnctx = BN_CTX_new()) == NULL)
691 return 0;
692 if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
693 EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||
694 EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
695 EC_KEY_get0_public_key(a->ecdsa),
696 EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {
697 BN_CTX_free(bnctx);
698 return 0;
699 }
700 BN_CTX_free(bnctx);
701 return 1;
702# endif /* OPENSSL_HAS_ECC */
703#endif /* WITH_OPENSSL */
704 case KEY_ED25519:
705 case KEY_ED25519_CERT:
706 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
707 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
708 default:
709 return 0;
710 }
711 /* NOTREACHED */
712}
713
714int
715sshkey_equal(const struct sshkey *a, const struct sshkey *b)
716{
717 if (a == NULL || b == NULL || a->type != b->type)
718 return 0;
719 if (sshkey_is_cert(a)) {
720 if (!cert_compare(a->cert, b->cert))
721 return 0;
722 }
723 return sshkey_equal_public(a, b);
724}
725
726static int
727to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain)
728{
729 int type, ret = SSH_ERR_INTERNAL_ERROR;
730 const char *typename;
731
732 if (key == NULL)
733 return SSH_ERR_INVALID_ARGUMENT;
734
735 type = force_plain ? sshkey_type_plain(key->type) : key->type;
736 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
737
738 switch (type) {
739#ifdef WITH_OPENSSL
740 case KEY_DSA_CERT_V00:
741 case KEY_RSA_CERT_V00:
742 case KEY_DSA_CERT:
743 case KEY_ECDSA_CERT:
744 case KEY_RSA_CERT:
745#endif /* WITH_OPENSSL */
746 case KEY_ED25519_CERT:
747 /* Use the existing blob */
748 /* XXX modified flag? */
749 if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
750 return ret;
751 break;
752#ifdef WITH_OPENSSL
753 case KEY_DSA:
754 if (key->dsa == NULL)
755 return SSH_ERR_INVALID_ARGUMENT;
756 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
757 (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
758 (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
759 (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
760 (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0)
761 return ret;
762 break;
763 case KEY_ECDSA:
764 if (key->ecdsa == NULL)
765 return SSH_ERR_INVALID_ARGUMENT;
766 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
767 (ret = sshbuf_put_cstring(b,
768 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
769 (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)
770 return ret;
771 break;
772 case KEY_RSA:
773 if (key->rsa == NULL)
774 return SSH_ERR_INVALID_ARGUMENT;
775 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
776 (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
777 (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0)
778 return ret;
779 break;
780#endif /* WITH_OPENSSL */
781 case KEY_ED25519:
782 if (key->ed25519_pk == NULL)
783 return SSH_ERR_INVALID_ARGUMENT;
784 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
785 (ret = sshbuf_put_string(b,
786 key->ed25519_pk, ED25519_PK_SZ)) != 0)
787 return ret;
788 break;
789 default:
790 return SSH_ERR_KEY_TYPE_UNKNOWN;
791 }
792 return 0;
793}
794
795int
796sshkey_to_blob_buf(const struct sshkey *key, struct sshbuf *b)
797{
798 return to_blob_buf(key, b, 0);
799}
800
801int
802sshkey_plain_to_blob_buf(const struct sshkey *key, struct sshbuf *b)
803{
804 return to_blob_buf(key, b, 1);
805}
806
807static int
808to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain)
809{
810 int ret = SSH_ERR_INTERNAL_ERROR;
811 size_t len;
812 struct sshbuf *b = NULL;
813
814 if (lenp != NULL)
815 *lenp = 0;
816 if (blobp != NULL)
817 *blobp = NULL;
818 if ((b = sshbuf_new()) == NULL)
819 return SSH_ERR_ALLOC_FAIL;
820 if ((ret = to_blob_buf(key, b, force_plain)) != 0)
821 goto out;
822 len = sshbuf_len(b);
823 if (lenp != NULL)
824 *lenp = len;
825 if (blobp != NULL) {
826 if ((*blobp = malloc(len)) == NULL) {
827 ret = SSH_ERR_ALLOC_FAIL;
828 goto out;
829 }
830 memcpy(*blobp, sshbuf_ptr(b), len);
831 }
832 ret = 0;
833 out:
834 sshbuf_free(b);
835 return ret;
836}
837
838int
839sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
840{
841 return to_blob(key, blobp, lenp, 0);
842}
843
844int
845sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
846{
847 return to_blob(key, blobp, lenp, 1);
848}
849
850int
851sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type,
852 u_char **retp, size_t *lenp)
853{
854 u_char *blob = NULL, *ret = NULL;
855 size_t blob_len = 0;
856 int hash_alg = -1, r = SSH_ERR_INTERNAL_ERROR;
857
858 if (retp != NULL)
859 *retp = NULL;
860 if (lenp != NULL)
861 *lenp = 0;
862
863 switch (dgst_type) {
864 case SSH_FP_MD5:
865 hash_alg = SSH_DIGEST_MD5;
866 break;
867 case SSH_FP_SHA1:
868 hash_alg = SSH_DIGEST_SHA1;
869 break;
870 case SSH_FP_SHA256:
871 hash_alg = SSH_DIGEST_SHA256;
872 break;
873 default:
874 r = SSH_ERR_INVALID_ARGUMENT;
875 goto out;
876 }
877
878 if (k->type == KEY_RSA1) {
879#ifdef WITH_OPENSSL
880 int nlen = BN_num_bytes(k->rsa->n);
881 int elen = BN_num_bytes(k->rsa->e);
882
883 blob_len = nlen + elen;
884 if (nlen >= INT_MAX - elen ||
885 (blob = malloc(blob_len)) == NULL) {
886 r = SSH_ERR_ALLOC_FAIL;
887 goto out;
888 }
889 BN_bn2bin(k->rsa->n, blob);
890 BN_bn2bin(k->rsa->e, blob + nlen);
891#endif /* WITH_OPENSSL */
892 } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0)
893 goto out;
894 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
895 r = SSH_ERR_ALLOC_FAIL;
896 goto out;
897 }
898 if ((r = ssh_digest_memory(hash_alg, blob, blob_len,
899 ret, SSH_DIGEST_MAX_LENGTH)) != 0)
900 goto out;
901 /* success */
902 if (retp != NULL) {
903 *retp = ret;
904 ret = NULL;
905 }
906 if (lenp != NULL)
907 *lenp = ssh_digest_bytes(hash_alg);
908 r = 0;
909 out:
910 free(ret);
911 if (blob != NULL) {
912 explicit_bzero(blob, blob_len);
913 free(blob);
914 }
915 return r;
916}
917
918static char *
919fingerprint_hex(u_char *dgst_raw, size_t dgst_raw_len)
920{
921 char *retval;
922 size_t i;
923
924 if ((retval = calloc(1, dgst_raw_len * 3 + 1)) == NULL)
925 return NULL;
926 for (i = 0; i < dgst_raw_len; i++) {
927 char hex[4];
928 snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
929 strlcat(retval, hex, dgst_raw_len * 3 + 1);
930 }
931
932 /* Remove the trailing ':' character */
933 retval[(dgst_raw_len * 3) - 1] = '\0';
934 return retval;
935}
936
937static char *
938fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
939{
940 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
941 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
942 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
943 u_int i, j = 0, rounds, seed = 1;
944 char *retval;
945
946 rounds = (dgst_raw_len / 2) + 1;
947 if ((retval = calloc(rounds, 6)) == NULL)
948 return NULL;
949 retval[j++] = 'x';
950 for (i = 0; i < rounds; i++) {
951 u_int idx0, idx1, idx2, idx3, idx4;
952 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
953 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
954 seed) % 6;
955 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
956 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
957 (seed / 6)) % 6;
958 retval[j++] = vowels[idx0];
959 retval[j++] = consonants[idx1];
960 retval[j++] = vowels[idx2];
961 if ((i + 1) < rounds) {
962 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
963 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
964 retval[j++] = consonants[idx3];
965 retval[j++] = '-';
966 retval[j++] = consonants[idx4];
967 seed = ((seed * 5) +
968 ((((u_int)(dgst_raw[2 * i])) * 7) +
969 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
970 }
971 } else {
972 idx0 = seed % 6;
973 idx1 = 16;
974 idx2 = seed / 6;
975 retval[j++] = vowels[idx0];
976 retval[j++] = consonants[idx1];
977 retval[j++] = vowels[idx2];
978 }
979 }
980 retval[j++] = 'x';
981 retval[j++] = '\0';
982 return retval;
983}
984
985/*
986 * Draw an ASCII-Art representing the fingerprint so human brain can
987 * profit from its built-in pattern recognition ability.
988 * This technique is called "random art" and can be found in some
989 * scientific publications like this original paper:
990 *
991 * "Hash Visualization: a New Technique to improve Real-World Security",
992 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
993 * Techniques and E-Commerce (CrypTEC '99)
994 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
995 *
996 * The subject came up in a talk by Dan Kaminsky, too.
997 *
998 * If you see the picture is different, the key is different.
999 * If the picture looks the same, you still know nothing.
1000 *
1001 * The algorithm used here is a worm crawling over a discrete plane,
1002 * leaving a trace (augmenting the field) everywhere it goes.
1003 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
1004 * makes the respective movement vector be ignored for this turn.
1005 * Graphs are not unambiguous, because circles in graphs can be
1006 * walked in either direction.
1007 */
1008
1009/*
1010 * Field sizes for the random art. Have to be odd, so the starting point
1011 * can be in the exact middle of the picture, and FLDBASE should be >=8 .
1012 * Else pictures would be too dense, and drawing the frame would
1013 * fail, too, because the key type would not fit in anymore.
1014 */
1015#define FLDBASE 8
1016#define FLDSIZE_Y (FLDBASE + 1)
1017#define FLDSIZE_X (FLDBASE * 2 + 1)
1018static char *
1019fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1020 const struct sshkey *k)
1021{
1022 /*
1023 * Chars to be used after each other every time the worm
1024 * intersects with itself. Matter of taste.
1025 */
1026 char *augmentation_string = " .o+=*BOX@%&#/^SE";
1027 char *retval, *p;
1028 u_char field[FLDSIZE_X][FLDSIZE_Y];
1029 size_t i;
1030 u_int b;
1031 int x, y;
1032 size_t len = strlen(augmentation_string) - 1;
1033
1034 if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)
1035 return NULL;
1036
1037 /* initialize field */
1038 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
1039 x = FLDSIZE_X / 2;
1040 y = FLDSIZE_Y / 2;
1041
1042 /* process raw key */
1043 for (i = 0; i < dgst_raw_len; i++) {
1044 int input;
1045 /* each byte conveys four 2-bit move commands */
1046 input = dgst_raw[i];
1047 for (b = 0; b < 4; b++) {
1048 /* evaluate 2 bit, rest is shifted later */
1049 x += (input & 0x1) ? 1 : -1;
1050 y += (input & 0x2) ? 1 : -1;
1051
1052 /* assure we are still in bounds */
1053 x = MAX(x, 0);
1054 y = MAX(y, 0);
1055 x = MIN(x, FLDSIZE_X - 1);
1056 y = MIN(y, FLDSIZE_Y - 1);
1057
1058 /* augment the field */
1059 if (field[x][y] < len - 2)
1060 field[x][y]++;
1061 input = input >> 2;
1062 }
1063 }
1064
1065 /* mark starting point and end point*/
1066 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
1067 field[x][y] = len;
1068
1069 /* fill in retval */
1070 snprintf(retval, FLDSIZE_X, "+--[%4s %4u]",
1071 sshkey_type(k), sshkey_size(k));
1072 p = strchr(retval, '\0');
1073
1074 /* output upper border */
1075 for (i = p - retval - 1; i < FLDSIZE_X; i++)
1076 *p++ = '-';
1077 *p++ = '+';
1078 *p++ = '\n';
1079
1080 /* output content */
1081 for (y = 0; y < FLDSIZE_Y; y++) {
1082 *p++ = '|';
1083 for (x = 0; x < FLDSIZE_X; x++)
1084 *p++ = augmentation_string[MIN(field[x][y], len)];
1085 *p++ = '|';
1086 *p++ = '\n';
1087 }
1088
1089 /* output lower border */
1090 *p++ = '+';
1091 for (i = 0; i < FLDSIZE_X; i++)
1092 *p++ = '-';
1093 *p++ = '+';
1094
1095 return retval;
1096}
1097
1098char *
1099sshkey_fingerprint(const struct sshkey *k, enum sshkey_fp_type dgst_type,
1100 enum sshkey_fp_rep dgst_rep)
1101{
1102 char *retval = NULL;
1103 u_char *dgst_raw;
1104 size_t dgst_raw_len;
1105
1106 if (sshkey_fingerprint_raw(k, dgst_type, &dgst_raw, &dgst_raw_len) != 0)
1107 return NULL;
1108 switch (dgst_rep) {
1109 case SSH_FP_HEX:
1110 retval = fingerprint_hex(dgst_raw, dgst_raw_len);
1111 break;
1112 case SSH_FP_BUBBLEBABBLE:
1113 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1114 break;
1115 case SSH_FP_RANDOMART:
1116 retval = fingerprint_randomart(dgst_raw, dgst_raw_len, k);
1117 break;
1118 default:
1119 explicit_bzero(dgst_raw, dgst_raw_len);
1120 free(dgst_raw);
1121 return NULL;
1122 }
1123 explicit_bzero(dgst_raw, dgst_raw_len);
1124 free(dgst_raw);
1125 return retval;
1126}
1127
1128#ifdef WITH_SSH1
1129/*
1130 * Reads a multiple-precision integer in decimal from the buffer, and advances
1131 * the pointer. The integer must already be initialized. This function is
1132 * permitted to modify the buffer. This leaves *cpp to point just beyond the
1133 * last processed character.
1134 */
1135static int
1136read_decimal_bignum(char **cpp, BIGNUM *v)
1137{
1138 char *cp;
1139 size_t e;
1140 int skip = 1; /* skip white space */
1141
1142 cp = *cpp;
1143 while (*cp == ' ' || *cp == '\t')
1144 cp++;
1145 e = strspn(cp, "0123456789");
1146 if (e == 0)
1147 return SSH_ERR_INVALID_FORMAT;
1148 if (e > SSHBUF_MAX_BIGNUM * 3)
1149 return SSH_ERR_BIGNUM_TOO_LARGE;
1150 if (cp[e] == '\0')
1151 skip = 0;
1152 else if (index(" \t\r\n", cp[e]) == NULL)
1153 return SSH_ERR_INVALID_FORMAT;
1154 cp[e] = '\0';
1155 if (BN_dec2bn(&v, cp) <= 0)
1156 return SSH_ERR_INVALID_FORMAT;
1157 *cpp = cp + e + skip;
1158 return 0;
1159}
1160#endif /* WITH_SSH1 */
1161
1162/* returns 0 ok, and < 0 error */
1163int
1164sshkey_read(struct sshkey *ret, char **cpp)
1165{
1166 struct sshkey *k;
1167 int retval = SSH_ERR_INVALID_FORMAT;
1168 char *cp, *space;
1169 int r, type, curve_nid = -1;
1170 struct sshbuf *blob;
1171#ifdef WITH_SSH1
1172 char *ep;
1173 u_long bits;
1174#endif /* WITH_SSH1 */
1175
1176 cp = *cpp;
1177
1178 switch (ret->type) {
1179 case KEY_RSA1:
1180#ifdef WITH_SSH1
1181 /* Get number of bits. */
1182 bits = strtoul(cp, &ep, 10);
1183 if (*cp == '\0' || index(" \t\r\n", *ep) == NULL ||
1184 bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8)
1185 return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */
1186 /* Get public exponent, public modulus. */
1187 if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0)
1188 return r;
1189 if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0)
1190 return r;
1191 *cpp = ep;
1192 /* validate the claimed number of bits */
1193 if (BN_num_bits(ret->rsa->n) != (int)bits)
1194 return SSH_ERR_KEY_BITS_MISMATCH;
1195 retval = 0;
1196#endif /* WITH_SSH1 */
1197 break;
1198 case KEY_UNSPEC:
1199 case KEY_RSA:
1200 case KEY_DSA:
1201 case KEY_ECDSA:
1202 case KEY_ED25519:
1203 case KEY_DSA_CERT_V00:
1204 case KEY_RSA_CERT_V00:
1205 case KEY_DSA_CERT:
1206 case KEY_ECDSA_CERT:
1207 case KEY_RSA_CERT:
1208 case KEY_ED25519_CERT:
1209 space = strchr(cp, ' ');
1210 if (space == NULL)
1211 return SSH_ERR_INVALID_FORMAT;
1212 *space = '\0';
1213 type = sshkey_type_from_name(cp);
1214 if (sshkey_type_plain(type) == KEY_ECDSA &&
1215 (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1)
1216 return SSH_ERR_EC_CURVE_INVALID;
1217 *space = ' ';
1218 if (type == KEY_UNSPEC)
1219 return SSH_ERR_INVALID_FORMAT;
1220 cp = space+1;
1221 if (*cp == '\0')
1222 return SSH_ERR_INVALID_FORMAT;
1223 if (ret->type == KEY_UNSPEC) {
1224 ret->type = type;
1225 } else if (ret->type != type)
1226 return SSH_ERR_KEY_TYPE_MISMATCH;
1227 if ((blob = sshbuf_new()) == NULL)
1228 return SSH_ERR_ALLOC_FAIL;
1229 /* trim comment */
1230 space = strchr(cp, ' ');
1231 if (space)
1232 *space = '\0';
1233 if ((r = sshbuf_b64tod(blob, cp)) != 0) {
1234 sshbuf_free(blob);
1235 return r;
1236 }
1237 if ((r = sshkey_from_blob(sshbuf_ptr(blob),
1238 sshbuf_len(blob), &k)) != 0) {
1239 sshbuf_free(blob);
1240 return r;
1241 }
1242 sshbuf_free(blob);
1243 if (k->type != type) {
1244 sshkey_free(k);
1245 return SSH_ERR_KEY_TYPE_MISMATCH;
1246 }
1247 if (sshkey_type_plain(type) == KEY_ECDSA &&
1248 curve_nid != k->ecdsa_nid) {
1249 sshkey_free(k);
1250 return SSH_ERR_EC_CURVE_MISMATCH;
1251 }
1252/*XXXX*/
1253 if (sshkey_is_cert(ret)) {
1254 if (!sshkey_is_cert(k)) {
1255 sshkey_free(k);
1256 return SSH_ERR_EXPECTED_CERT;
1257 }
1258 if (ret->cert != NULL)
1259 cert_free(ret->cert);
1260 ret->cert = k->cert;
1261 k->cert = NULL;
1262 }
1263#ifdef WITH_OPENSSL
1264 if (sshkey_type_plain(ret->type) == KEY_RSA) {
1265 if (ret->rsa != NULL)
1266 RSA_free(ret->rsa);
1267 ret->rsa = k->rsa;
1268 k->rsa = NULL;
1269#ifdef DEBUG_PK
1270 RSA_print_fp(stderr, ret->rsa, 8);
1271#endif
1272 }
1273 if (sshkey_type_plain(ret->type) == KEY_DSA) {
1274 if (ret->dsa != NULL)
1275 DSA_free(ret->dsa);
1276 ret->dsa = k->dsa;
1277 k->dsa = NULL;
1278#ifdef DEBUG_PK
1279 DSA_print_fp(stderr, ret->dsa, 8);
1280#endif
1281 }
1282# ifdef OPENSSL_HAS_ECC
1283 if (sshkey_type_plain(ret->type) == KEY_ECDSA) {
1284 if (ret->ecdsa != NULL)
1285 EC_KEY_free(ret->ecdsa);
1286 ret->ecdsa = k->ecdsa;
1287 ret->ecdsa_nid = k->ecdsa_nid;
1288 k->ecdsa = NULL;
1289 k->ecdsa_nid = -1;
1290#ifdef DEBUG_PK
1291 sshkey_dump_ec_key(ret->ecdsa);
1292#endif
1293 }
1294# endif /* OPENSSL_HAS_ECC */
1295#endif /* WITH_OPENSSL */
1296 if (sshkey_type_plain(ret->type) == KEY_ED25519) {
1297 free(ret->ed25519_pk);
1298 ret->ed25519_pk = k->ed25519_pk;
1299 k->ed25519_pk = NULL;
1300#ifdef DEBUG_PK
1301 /* XXX */
1302#endif
1303 }
1304 retval = 0;
1305/*XXXX*/
1306 sshkey_free(k);
1307 if (retval != 0)
1308 break;
1309 /* advance cp: skip whitespace and data */
1310 while (*cp == ' ' || *cp == '\t')
1311 cp++;
1312 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
1313 cp++;
1314 *cpp = cp;
1315 break;
1316 default:
1317 return SSH_ERR_INVALID_ARGUMENT;
1318 }
1319 return retval;
1320}
1321
1322int
1323sshkey_write(const struct sshkey *key, FILE *f)
1324{
1325 int ret = SSH_ERR_INTERNAL_ERROR;
1326 struct sshbuf *b = NULL, *bb = NULL;
1327 char *uu = NULL;
1328#ifdef WITH_SSH1
1329 u_int bits = 0;
1330 char *dec_e = NULL, *dec_n = NULL;
1331#endif /* WITH_SSH1 */
1332
1333 if (sshkey_is_cert(key)) {
1334 if (key->cert == NULL)
1335 return SSH_ERR_EXPECTED_CERT;
1336 if (sshbuf_len(key->cert->certblob) == 0)
1337 return SSH_ERR_KEY_LACKS_CERTBLOB;
1338 }
1339 if ((b = sshbuf_new()) == NULL)
1340 return SSH_ERR_ALLOC_FAIL;
1341 switch (key->type) {
1342#ifdef WITH_SSH1
1343 case KEY_RSA1:
1344 if (key->rsa == NULL || key->rsa->e == NULL ||
1345 key->rsa->n == NULL) {
1346 ret = SSH_ERR_INVALID_ARGUMENT;
1347 goto out;
1348 }
1349 if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
1350 (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
1351 ret = SSH_ERR_ALLOC_FAIL;
1352 goto out;
1353 }
1354 /* size of modulus 'n' */
1355 if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
1356 ret = SSH_ERR_INVALID_ARGUMENT;
1357 goto out;
1358 }
1359 if ((ret = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
1360 goto out;
1361#endif /* WITH_SSH1 */
1362 break;
1363#ifdef WITH_OPENSSL
1364 case KEY_DSA:
1365 case KEY_DSA_CERT_V00:
1366 case KEY_DSA_CERT:
1367 case KEY_ECDSA:
1368 case KEY_ECDSA_CERT:
1369 case KEY_RSA:
1370 case KEY_RSA_CERT_V00:
1371 case KEY_RSA_CERT:
1372#endif /* WITH_OPENSSL */
1373 case KEY_ED25519:
1374 case KEY_ED25519_CERT:
1375 if ((bb = sshbuf_new()) == NULL) {
1376 ret = SSH_ERR_ALLOC_FAIL;
1377 goto out;
1378 }
1379 if ((ret = sshkey_to_blob_buf(key, bb)) != 0)
1380 goto out;
1381 if ((uu = sshbuf_dtob64(bb)) == NULL) {
1382 ret = SSH_ERR_ALLOC_FAIL;
1383 goto out;
1384 }
1385 if ((ret = sshbuf_putf(b, "%s ", sshkey_ssh_name(key))) != 0)
1386 goto out;
1387 if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0)
1388 goto out;
1389 break;
1390 default:
1391 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
1392 goto out;
1393 }
1394 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
1395 if (feof(f))
1396 errno = EPIPE;
1397 ret = SSH_ERR_SYSTEM_ERROR;
1398 goto out;
1399 }
1400 ret = 0;
1401 out:
1402 if (b != NULL)
1403 sshbuf_free(b);
1404 if (bb != NULL)
1405 sshbuf_free(bb);
1406 if (uu != NULL)
1407 free(uu);
1408#ifdef WITH_SSH1
1409 if (dec_e != NULL)
1410 OPENSSL_free(dec_e);
1411 if (dec_n != NULL)
1412 OPENSSL_free(dec_n);
1413#endif /* WITH_SSH1 */
1414 return ret;
1415}
1416
1417const char *
1418sshkey_cert_type(const struct sshkey *k)
1419{
1420 switch (k->cert->type) {
1421 case SSH2_CERT_TYPE_USER:
1422 return "user";
1423 case SSH2_CERT_TYPE_HOST:
1424 return "host";
1425 default:
1426 return "unknown";
1427 }
1428}
1429
1430#ifdef WITH_OPENSSL
1431static int
1432rsa_generate_private_key(u_int bits, RSA **rsap)
1433{
1434 RSA *private = NULL;
1435 BIGNUM *f4 = NULL;
1436 int ret = SSH_ERR_INTERNAL_ERROR;
1437
1438 if (rsap == NULL ||
1439 bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1440 bits > SSHBUF_MAX_BIGNUM * 8)
1441 return SSH_ERR_INVALID_ARGUMENT;
1442 *rsap = NULL;
1443 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
1444 ret = SSH_ERR_ALLOC_FAIL;
1445 goto out;
1446 }
1447 if (!BN_set_word(f4, RSA_F4) ||
1448 !RSA_generate_key_ex(private, bits, f4, NULL)) {
1449 ret = SSH_ERR_LIBCRYPTO_ERROR;
1450 goto out;
1451 }
1452 *rsap = private;
1453 private = NULL;
1454 ret = 0;
1455 out:
1456 if (private != NULL)
1457 RSA_free(private);
1458 if (f4 != NULL)
1459 BN_free(f4);
1460 return ret;
1461}
1462
1463static int
1464dsa_generate_private_key(u_int bits, DSA **dsap)
1465{
1466 DSA *private;
1467 int ret = SSH_ERR_INTERNAL_ERROR;
1468
1469 if (dsap == NULL || bits != 1024)
1470 return SSH_ERR_INVALID_ARGUMENT;
1471 if ((private = DSA_new()) == NULL) {
1472 ret = SSH_ERR_ALLOC_FAIL;
1473 goto out;
1474 }
1475 *dsap = NULL;
1476 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
1477 NULL, NULL) || !DSA_generate_key(private)) {
1478 DSA_free(private);
1479 ret = SSH_ERR_LIBCRYPTO_ERROR;
1480 goto out;
1481 }
1482 *dsap = private;
1483 private = NULL;
1484 ret = 0;
1485 out:
1486 if (private != NULL)
1487 DSA_free(private);
1488 return ret;
1489}
1490
1491# ifdef OPENSSL_HAS_ECC
1492int
1493sshkey_ecdsa_key_to_nid(EC_KEY *k)
1494{
1495 EC_GROUP *eg;
1496 int nids[] = {
1497 NID_X9_62_prime256v1,
1498 NID_secp384r1,
1499# ifdef OPENSSL_HAS_NISTP521
1500 NID_secp521r1,
1501# endif /* OPENSSL_HAS_NISTP521 */
1502 -1
1503 };
1504 int nid;
1505 u_int i;
1506 BN_CTX *bnctx;
1507 const EC_GROUP *g = EC_KEY_get0_group(k);
1508
1509 /*
1510 * The group may be stored in a ASN.1 encoded private key in one of two
1511 * ways: as a "named group", which is reconstituted by ASN.1 object ID
1512 * or explicit group parameters encoded into the key blob. Only the
1513 * "named group" case sets the group NID for us, but we can figure
1514 * it out for the other case by comparing against all the groups that
1515 * are supported.
1516 */
1517 if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1518 return nid;
1519 if ((bnctx = BN_CTX_new()) == NULL)
1520 return -1;
1521 for (i = 0; nids[i] != -1; i++) {
1522 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) {
1523 BN_CTX_free(bnctx);
1524 return -1;
1525 }
1526 if (EC_GROUP_cmp(g, eg, bnctx) == 0)
1527 break;
1528 EC_GROUP_free(eg);
1529 }
1530 BN_CTX_free(bnctx);
1531 if (nids[i] != -1) {
1532 /* Use the group with the NID attached */
1533 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1534 if (EC_KEY_set_group(k, eg) != 1) {
1535 EC_GROUP_free(eg);
1536 return -1;
1537 }
1538 }
1539 return nids[i];
1540}
1541
1542static int
1543ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
1544{
1545 EC_KEY *private;
1546 int ret = SSH_ERR_INTERNAL_ERROR;
1547
1548 if (nid == NULL || ecdsap == NULL ||
1549 (*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
1550 return SSH_ERR_INVALID_ARGUMENT;
1551 *ecdsap = NULL;
1552 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
1553 ret = SSH_ERR_ALLOC_FAIL;
1554 goto out;
1555 }
1556 if (EC_KEY_generate_key(private) != 1) {
1557 ret = SSH_ERR_LIBCRYPTO_ERROR;
1558 goto out;
1559 }
1560 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
1561 *ecdsap = private;
1562 private = NULL;
1563 ret = 0;
1564 out:
1565 if (private != NULL)
1566 EC_KEY_free(private);
1567 return ret;
1568}
1569# endif /* OPENSSL_HAS_ECC */
1570#endif /* WITH_OPENSSL */
1571
1572int
1573sshkey_generate(int type, u_int bits, struct sshkey **keyp)
1574{
1575 struct sshkey *k;
1576 int ret = SSH_ERR_INTERNAL_ERROR;
1577
1578 if (keyp == NULL)
1579 return SSH_ERR_INVALID_ARGUMENT;
1580 *keyp = NULL;
1581 if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
1582 return SSH_ERR_ALLOC_FAIL;
1583 switch (type) {
1584 case KEY_ED25519:
1585 if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
1586 (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) {
1587 ret = SSH_ERR_ALLOC_FAIL;
1588 break;
1589 }
1590 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
1591 ret = 0;
1592 break;
1593#ifdef WITH_OPENSSL
1594 case KEY_DSA:
1595 ret = dsa_generate_private_key(bits, &k->dsa);
1596 break;
1597# ifdef OPENSSL_HAS_ECC
1598 case KEY_ECDSA:
1599 ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid,
1600 &k->ecdsa);
1601 break;
1602# endif /* OPENSSL_HAS_ECC */
1603 case KEY_RSA:
1604 case KEY_RSA1:
1605 ret = rsa_generate_private_key(bits, &k->rsa);
1606 break;
1607#endif /* WITH_OPENSSL */
1608 default:
1609 ret = SSH_ERR_INVALID_ARGUMENT;
1610 }
1611 if (ret == 0) {
1612 k->type = type;
1613 *keyp = k;
1614 } else
1615 sshkey_free(k);
1616 return ret;
1617}
1618
1619int
1620sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
1621{
1622 u_int i;
1623 const struct sshkey_cert *from;
1624 struct sshkey_cert *to;
1625 int ret = SSH_ERR_INTERNAL_ERROR;
1626
1627 if (to_key->cert != NULL) {
1628 cert_free(to_key->cert);
1629 to_key->cert = NULL;
1630 }
1631
1632 if ((from = from_key->cert) == NULL)
1633 return SSH_ERR_INVALID_ARGUMENT;
1634
1635 if ((to = to_key->cert = cert_new()) == NULL)
1636 return SSH_ERR_ALLOC_FAIL;
1637
1638 if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
1639 (ret = sshbuf_putb(to->critical, from->critical)) != 0 ||
1640 (ret = sshbuf_putb(to->extensions, from->extensions) != 0))
1641 return ret;
1642
1643 to->serial = from->serial;
1644 to->type = from->type;
1645 if (from->key_id == NULL)
1646 to->key_id = NULL;
1647 else if ((to->key_id = strdup(from->key_id)) == NULL)
1648 return SSH_ERR_ALLOC_FAIL;
1649 to->valid_after = from->valid_after;
1650 to->valid_before = from->valid_before;
1651 if (from->signature_key == NULL)
1652 to->signature_key = NULL;
1653 else if ((ret = sshkey_from_private(from->signature_key,
1654 &to->signature_key)) != 0)
1655 return ret;
1656
1657 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS)
1658 return SSH_ERR_INVALID_ARGUMENT;
1659 if (from->nprincipals > 0) {
1660 if ((to->principals = calloc(from->nprincipals,
1661 sizeof(*to->principals))) == NULL)
1662 return SSH_ERR_ALLOC_FAIL;
1663 for (i = 0; i < from->nprincipals; i++) {
1664 to->principals[i] = strdup(from->principals[i]);
1665 if (to->principals[i] == NULL) {
1666 to->nprincipals = i;
1667 return SSH_ERR_ALLOC_FAIL;
1668 }
1669 }
1670 }
1671 to->nprincipals = from->nprincipals;
1672 return 0;
1673}
1674
1675int
1676sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1677{
1678 struct sshkey *n = NULL;
1679 int ret = SSH_ERR_INTERNAL_ERROR;
1680
1681 if (pkp != NULL)
1682 *pkp = NULL;
1683
1684 switch (k->type) {
1685#ifdef WITH_OPENSSL
1686 case KEY_DSA:
1687 case KEY_DSA_CERT_V00:
1688 case KEY_DSA_CERT:
1689 if ((n = sshkey_new(k->type)) == NULL)
1690 return SSH_ERR_ALLOC_FAIL;
1691 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
1692 (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1693 (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1694 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {
1695 sshkey_free(n);
1696 return SSH_ERR_ALLOC_FAIL;
1697 }
1698 break;
1699# ifdef OPENSSL_HAS_ECC
1700 case KEY_ECDSA:
1701 case KEY_ECDSA_CERT:
1702 if ((n = sshkey_new(k->type)) == NULL)
1703 return SSH_ERR_ALLOC_FAIL;
1704 n->ecdsa_nid = k->ecdsa_nid;
1705 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
1706 if (n->ecdsa == NULL) {
1707 sshkey_free(n);
1708 return SSH_ERR_ALLOC_FAIL;
1709 }
1710 if (EC_KEY_set_public_key(n->ecdsa,
1711 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
1712 sshkey_free(n);
1713 return SSH_ERR_LIBCRYPTO_ERROR;
1714 }
1715 break;
1716# endif /* OPENSSL_HAS_ECC */
1717 case KEY_RSA:
1718 case KEY_RSA1:
1719 case KEY_RSA_CERT_V00:
1720 case KEY_RSA_CERT:
1721 if ((n = sshkey_new(k->type)) == NULL)
1722 return SSH_ERR_ALLOC_FAIL;
1723 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
1724 (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
1725 sshkey_free(n);
1726 return SSH_ERR_ALLOC_FAIL;
1727 }
1728 break;
1729#endif /* WITH_OPENSSL */
1730 case KEY_ED25519:
1731 case KEY_ED25519_CERT:
1732 if ((n = sshkey_new(k->type)) == NULL)
1733 return SSH_ERR_ALLOC_FAIL;
1734 if (k->ed25519_pk != NULL) {
1735 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1736 sshkey_free(n);
1737 return SSH_ERR_ALLOC_FAIL;
1738 }
1739 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1740 }
1741 break;
1742 default:
1743 return SSH_ERR_KEY_TYPE_UNKNOWN;
1744 }
1745 if (sshkey_is_cert(k)) {
1746 if ((ret = sshkey_cert_copy(k, n)) != 0) {
1747 sshkey_free(n);
1748 return ret;
1749 }
1750 }
1751 *pkp = n;
1752 return 0;
1753}
1754
1755static int
1756cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob,
1757 size_t blen)
1758{
1759 u_char *principals = NULL, *critical = NULL, *exts = NULL;
1760 u_char *sig_key = NULL, *sig = NULL;
1761 size_t signed_len, plen, clen, sklen, slen, kidlen, elen;
1762 struct sshbuf *tmp;
1763 char *principal;
1764 int ret = SSH_ERR_INTERNAL_ERROR;
1765 int v00 = sshkey_cert_is_legacy(key);
1766 char **oprincipals;
1767
1768 if ((tmp = sshbuf_new()) == NULL)
1769 return SSH_ERR_ALLOC_FAIL;
1770
1771 /* Copy the entire key blob for verification and later serialisation */
1772 if ((ret = sshbuf_put(key->cert->certblob, blob, blen)) != 0)
1773 return ret;
1774
1775 elen = 0; /* Not touched for v00 certs */
1776 principals = exts = critical = sig_key = sig = NULL;
1777 if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) ||
1778 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
1779 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
1780 (ret = sshbuf_get_string(b, &principals, &plen)) != 0 ||
1781 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
1782 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
1783 (ret = sshbuf_get_string(b, &critical, &clen)) != 0 ||
1784 (!v00 && (ret = sshbuf_get_string(b, &exts, &elen)) != 0) ||
1785 (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) ||
1786 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
1787 (ret = sshbuf_get_string(b, &sig_key, &sklen)) != 0) {
1788 /* XXX debug print error for ret */
1789 ret = SSH_ERR_INVALID_FORMAT;
1790 goto out;
1791 }
1792
1793 /* Signature is left in the buffer so we can calculate this length */
1794 signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);
1795
1796 if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {
1797 ret = SSH_ERR_INVALID_FORMAT;
1798 goto out;
1799 }
1800
1801 if (key->cert->type != SSH2_CERT_TYPE_USER &&
1802 key->cert->type != SSH2_CERT_TYPE_HOST) {
1803 ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;
1804 goto out;
1805 }
1806
1807 if ((ret = sshbuf_put(tmp, principals, plen)) != 0)
1808 goto out;
1809 while (sshbuf_len(tmp) > 0) {
1810 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
1811 ret = SSH_ERR_INVALID_FORMAT;
1812 goto out;
1813 }
1814 if ((ret = sshbuf_get_cstring(tmp, &principal, &plen)) != 0) {
1815 ret = SSH_ERR_INVALID_FORMAT;
1816 goto out;
1817 }
1818 oprincipals = key->cert->principals;
1819 key->cert->principals = realloc(key->cert->principals,
1820 (key->cert->nprincipals + 1) *
1821 sizeof(*key->cert->principals));
1822 if (key->cert->principals == NULL) {
1823 free(principal);
1824 key->cert->principals = oprincipals;
1825 ret = SSH_ERR_ALLOC_FAIL;
1826 goto out;
1827 }
1828 key->cert->principals[key->cert->nprincipals++] = principal;
1829 }
1830
1831 sshbuf_reset(tmp);
1832
1833 if ((ret = sshbuf_put(key->cert->critical, critical, clen)) != 0 ||
1834 (ret = sshbuf_put(tmp, critical, clen)) != 0)
1835 goto out;
1836
1837 /* validate structure */
1838 while (sshbuf_len(tmp) != 0) {
1839 if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 ||
1840 (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) {
1841 ret = SSH_ERR_INVALID_FORMAT;
1842 goto out;
1843 }
1844 }
1845 sshbuf_reset(tmp);
1846
1847 if ((ret = sshbuf_put(key->cert->extensions, exts, elen)) != 0 ||
1848 (ret = sshbuf_put(tmp, exts, elen)) != 0)
1849 goto out;
1850
1851 /* validate structure */
1852 while (sshbuf_len(tmp) != 0) {
1853 if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 ||
1854 (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) {
1855 ret = SSH_ERR_INVALID_FORMAT;
1856 goto out;
1857 }
1858 }
1859 sshbuf_reset(tmp);
1860
1861 if (sshkey_from_blob_internal(sig_key, sklen,
1862 &key->cert->signature_key, 0) != 0) {
1863 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1864 goto out;
1865 }
1866 if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {
1867 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1868 goto out;
1869 }
1870
1871 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
1872 sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0)
1873 goto out;
1874 ret = 0;
1875
1876 out:
1877 sshbuf_free(tmp);
1878 free(principals);
1879 free(critical);
1880 free(exts);
1881 free(sig_key);
1882 free(sig);
1883 return ret;
1884}
1885
1886static int
1887sshkey_from_blob_internal(const u_char *blob, size_t blen,
1888 struct sshkey **keyp, int allow_cert)
1889{
1890 struct sshbuf *b = NULL;
1891 int type, nid = -1, ret = SSH_ERR_INTERNAL_ERROR;
1892 char *ktype = NULL, *curve = NULL;
1893 struct sshkey *key = NULL;
1894 size_t len;
1895 u_char *pk = NULL;
1896#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
1897 EC_POINT *q = NULL;
1898#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
1899
1900#ifdef DEBUG_PK /* XXX */
1901 dump_base64(stderr, blob, blen);
1902#endif
1903 *keyp = NULL;
1904 if ((b = sshbuf_from(blob, blen)) == NULL)
1905 return SSH_ERR_ALLOC_FAIL;
1906 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
1907 ret = SSH_ERR_INVALID_FORMAT;
1908 goto out;
1909 }
1910
1911 type = sshkey_type_from_name(ktype);
1912 if (sshkey_type_plain(type) == KEY_ECDSA)
1913 nid = sshkey_ecdsa_nid_from_name(ktype);
1914 if (!allow_cert && sshkey_type_is_cert(type)) {
1915 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1916 goto out;
1917 }
1918 switch (type) {
1919#ifdef WITH_OPENSSL
1920 case KEY_RSA_CERT:
1921 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1922 ret = SSH_ERR_INVALID_FORMAT;
1923 goto out;
1924 }
1925 /* FALLTHROUGH */
1926 case KEY_RSA:
1927 case KEY_RSA_CERT_V00:
1928 if ((key = sshkey_new(type)) == NULL) {
1929 ret = SSH_ERR_ALLOC_FAIL;
1930 goto out;
1931 }
1932 if (sshbuf_get_bignum2(b, key->rsa->e) == -1 ||
1933 sshbuf_get_bignum2(b, key->rsa->n) == -1) {
1934 ret = SSH_ERR_INVALID_FORMAT;
1935 goto out;
1936 }
1937#ifdef DEBUG_PK
1938 RSA_print_fp(stderr, key->rsa, 8);
1939#endif
1940 break;
1941 case KEY_DSA_CERT:
1942 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1943 ret = SSH_ERR_INVALID_FORMAT;
1944 goto out;
1945 }
1946 /* FALLTHROUGH */
1947 case KEY_DSA:
1948 case KEY_DSA_CERT_V00:
1949 if ((key = sshkey_new(type)) == NULL) {
1950 ret = SSH_ERR_ALLOC_FAIL;
1951 goto out;
1952 }
1953 if (sshbuf_get_bignum2(b, key->dsa->p) == -1 ||
1954 sshbuf_get_bignum2(b, key->dsa->q) == -1 ||
1955 sshbuf_get_bignum2(b, key->dsa->g) == -1 ||
1956 sshbuf_get_bignum2(b, key->dsa->pub_key) == -1) {
1957 ret = SSH_ERR_INVALID_FORMAT;
1958 goto out;
1959 }
1960#ifdef DEBUG_PK
1961 DSA_print_fp(stderr, key->dsa, 8);
1962#endif
1963 break;
1964 case KEY_ECDSA_CERT:
1965 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1966 ret = SSH_ERR_INVALID_FORMAT;
1967 goto out;
1968 }
1969 /* FALLTHROUGH */
1970# ifdef OPENSSL_HAS_ECC
1971 case KEY_ECDSA:
1972 if ((key = sshkey_new(type)) == NULL) {
1973 ret = SSH_ERR_ALLOC_FAIL;
1974 goto out;
1975 }
1976 key->ecdsa_nid = nid;
1977 if (sshbuf_get_cstring(b, &curve, NULL) != 0) {
1978 ret = SSH_ERR_INVALID_FORMAT;
1979 goto out;
1980 }
1981 if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
1982 ret = SSH_ERR_EC_CURVE_MISMATCH;
1983 goto out;
1984 }
1985 if (key->ecdsa != NULL)
1986 EC_KEY_free(key->ecdsa);
1987 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
1988 == NULL) {
1989 ret = SSH_ERR_EC_CURVE_INVALID;
1990 goto out;
1991 }
1992 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) {
1993 ret = SSH_ERR_ALLOC_FAIL;
1994 goto out;
1995 }
1996 if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) {
1997 ret = SSH_ERR_INVALID_FORMAT;
1998 goto out;
1999 }
2000 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
2001 q) != 0) {
2002 ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2003 goto out;
2004 }
2005 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
2006 /* XXX assume it is a allocation error */
2007 ret = SSH_ERR_ALLOC_FAIL;
2008 goto out;
2009 }
2010#ifdef DEBUG_PK
2011 sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
2012#endif
2013 break;
2014# endif /* OPENSSL_HAS_ECC */
2015#endif /* WITH_OPENSSL */
2016 case KEY_ED25519_CERT:
2017 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2018 ret = SSH_ERR_INVALID_FORMAT;
2019 goto out;
2020 }
2021 /* FALLTHROUGH */
2022 case KEY_ED25519:
2023 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2024 goto out;
2025 if (len != ED25519_PK_SZ) {
2026 ret = SSH_ERR_INVALID_FORMAT;
2027 goto out;
2028 }
2029 if ((key = sshkey_new(type)) == NULL) {
2030 ret = SSH_ERR_ALLOC_FAIL;
2031 goto out;
2032 }
2033 key->ed25519_pk = pk;
2034 pk = NULL;
2035 break;
2036 case KEY_UNSPEC:
2037 if ((key = sshkey_new(type)) == NULL) {
2038 ret = SSH_ERR_ALLOC_FAIL;
2039 goto out;
2040 }
2041 break;
2042 default:
2043 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2044 goto out;
2045 }
2046
2047 /* Parse certificate potion */
2048 if (sshkey_is_cert(key) &&
2049 (ret = cert_parse(b, key, blob, blen)) != 0)
2050 goto out;
2051
2052 if (key != NULL && sshbuf_len(b) != 0) {
2053 ret = SSH_ERR_INVALID_FORMAT;
2054 goto out;
2055 }
2056 ret = 0;
2057 *keyp = key;
2058 key = NULL;
2059 out:
2060 sshbuf_free(b);
2061 sshkey_free(key);
2062 free(ktype);
2063 free(curve);
2064 free(pk);
2065#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2066 if (q != NULL)
2067 EC_POINT_free(q);
2068#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2069 return ret;
2070}
2071
2072int
2073sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
2074{
2075 return sshkey_from_blob_internal(blob, blen, keyp, 1);
2076}
2077
2078int
2079sshkey_sign(const struct sshkey *key,
2080 u_char **sigp, size_t *lenp,
2081 const u_char *data, size_t datalen, u_int compat)
2082{
2083 if (sigp != NULL)
2084 *sigp = NULL;
2085 if (lenp != NULL)
2086 *lenp = 0;
2087 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2088 return SSH_ERR_INVALID_ARGUMENT;
2089 switch (key->type) {
2090#ifdef WITH_OPENSSL
2091 case KEY_DSA_CERT_V00:
2092 case KEY_DSA_CERT:
2093 case KEY_DSA:
2094 return ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
2095# ifdef OPENSSL_HAS_ECC
2096 case KEY_ECDSA_CERT:
2097 case KEY_ECDSA:
2098 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
2099# endif /* OPENSSL_HAS_ECC */
2100 case KEY_RSA_CERT_V00:
2101 case KEY_RSA_CERT:
2102 case KEY_RSA:
2103 return ssh_rsa_sign(key, sigp, lenp, data, datalen, compat);
2104#endif /* WITH_OPENSSL */
2105 case KEY_ED25519:
2106 case KEY_ED25519_CERT:
2107 return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
2108 default:
2109 return SSH_ERR_KEY_TYPE_UNKNOWN;
2110 }
2111}
2112
2113/*
2114 * ssh_key_verify returns 0 for a correct signature and < 0 on error.
2115 */
2116int
2117sshkey_verify(const struct sshkey *key,
2118 const u_char *sig, size_t siglen,
2119 const u_char *data, size_t dlen, u_int compat)
2120{
2121 if (siglen == 0)
2122 return -1;
2123
2124 if (dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2125 return SSH_ERR_INVALID_ARGUMENT;
2126 switch (key->type) {
2127#ifdef WITH_OPENSSL
2128 case KEY_DSA_CERT_V00:
2129 case KEY_DSA_CERT:
2130 case KEY_DSA:
2131 return ssh_dss_verify(key, sig, siglen, data, dlen, compat);
2132# ifdef OPENSSL_HAS_ECC
2133 case KEY_ECDSA_CERT:
2134 case KEY_ECDSA:
2135 return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
2136# endif /* OPENSSL_HAS_ECC */
2137 case KEY_RSA_CERT_V00:
2138 case KEY_RSA_CERT:
2139 case KEY_RSA:
2140 return ssh_rsa_verify(key, sig, siglen, data, dlen, compat);
2141#endif /* WITH_OPENSSL */
2142 case KEY_ED25519:
2143 case KEY_ED25519_CERT:
2144 return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
2145 default:
2146 return SSH_ERR_KEY_TYPE_UNKNOWN;
2147 }
2148}
2149
2150/* Converts a private to a public key */
2151int
2152sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2153{
2154 struct sshkey *pk;
2155 int ret = SSH_ERR_INTERNAL_ERROR;
2156
2157 if (dkp != NULL)
2158 *dkp = NULL;
2159
2160 if ((pk = calloc(1, sizeof(*pk))) == NULL)
2161 return SSH_ERR_ALLOC_FAIL;
2162 pk->type = k->type;
2163 pk->flags = k->flags;
2164 pk->ecdsa_nid = k->ecdsa_nid;
2165 pk->dsa = NULL;
2166 pk->ecdsa = NULL;
2167 pk->rsa = NULL;
2168 pk->ed25519_pk = NULL;
2169 pk->ed25519_sk = NULL;
2170
2171 switch (k->type) {
2172#ifdef WITH_OPENSSL
2173 case KEY_RSA_CERT_V00:
2174 case KEY_RSA_CERT:
2175 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2176 goto fail;
2177 /* FALLTHROUGH */
2178 case KEY_RSA1:
2179 case KEY_RSA:
2180 if ((pk->rsa = RSA_new()) == NULL ||
2181 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
2182 (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
2183 ret = SSH_ERR_ALLOC_FAIL;
2184 goto fail;
2185 }
2186 break;
2187 case KEY_DSA_CERT_V00:
2188 case KEY_DSA_CERT:
2189 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2190 goto fail;
2191 /* FALLTHROUGH */
2192 case KEY_DSA:
2193 if ((pk->dsa = DSA_new()) == NULL ||
2194 (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
2195 (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
2196 (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
2197 (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
2198 ret = SSH_ERR_ALLOC_FAIL;
2199 goto fail;
2200 }
2201 break;
2202 case KEY_ECDSA_CERT:
2203 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2204 goto fail;
2205 /* FALLTHROUGH */
2206# ifdef OPENSSL_HAS_ECC
2207 case KEY_ECDSA:
2208 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
2209 if (pk->ecdsa == NULL) {
2210 ret = SSH_ERR_ALLOC_FAIL;
2211 goto fail;
2212 }
2213 if (EC_KEY_set_public_key(pk->ecdsa,
2214 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
2215 ret = SSH_ERR_LIBCRYPTO_ERROR;
2216 goto fail;
2217 }
2218 break;
2219# endif /* OPENSSL_HAS_ECC */
2220#endif /* WITH_OPENSSL */
2221 case KEY_ED25519_CERT:
2222 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2223 goto fail;
2224 /* FALLTHROUGH */
2225 case KEY_ED25519:
2226 if (k->ed25519_pk != NULL) {
2227 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
2228 ret = SSH_ERR_ALLOC_FAIL;
2229 goto fail;
2230 }
2231 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
2232 }
2233 break;
2234 default:
2235 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2236 fail:
2237 sshkey_free(pk);
2238 return ret;
2239 }
2240 *dkp = pk;
2241 return 0;
2242}
2243
2244/* Convert a plain key to their _CERT equivalent */
2245int
2246sshkey_to_certified(struct sshkey *k, int legacy)
2247{
2248 int newtype;
2249
2250 switch (k->type) {
2251#ifdef WITH_OPENSSL
2252 case KEY_RSA:
2253 newtype = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT;
2254 break;
2255 case KEY_DSA:
2256 newtype = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
2257 break;
2258 case KEY_ECDSA:
2259 if (legacy)
2260 return SSH_ERR_INVALID_ARGUMENT;
2261 newtype = KEY_ECDSA_CERT;
2262 break;
2263#endif /* WITH_OPENSSL */
2264 case KEY_ED25519:
2265 if (legacy)
2266 return SSH_ERR_INVALID_ARGUMENT;
2267 newtype = KEY_ED25519_CERT;
2268 break;
2269 default:
2270 return SSH_ERR_INVALID_ARGUMENT;
2271 }
2272 if ((k->cert = cert_new()) == NULL)
2273 return SSH_ERR_ALLOC_FAIL;
2274 k->type = newtype;
2275 return 0;
2276}
2277
2278/* Convert a certificate to its raw key equivalent */
2279int
2280sshkey_drop_cert(struct sshkey *k)
2281{
2282 if (!sshkey_type_is_cert(k->type))
2283 return SSH_ERR_KEY_TYPE_UNKNOWN;
2284 cert_free(k->cert);
2285 k->cert = NULL;
2286 k->type = sshkey_type_plain(k->type);
2287 return 0;
2288}
2289
2290/* Sign a certified key, (re-)generating the signed certblob. */
2291int
2292sshkey_certify(struct sshkey *k, struct sshkey *ca)
2293{
2294 struct sshbuf *principals = NULL;
2295 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2296 size_t i, ca_len, sig_len;
2297 int ret = SSH_ERR_INTERNAL_ERROR;
2298 struct sshbuf *cert;
2299
2300 if (k == NULL || k->cert == NULL ||
2301 k->cert->certblob == NULL || ca == NULL)
2302 return SSH_ERR_INVALID_ARGUMENT;
2303 if (!sshkey_is_cert(k))
2304 return SSH_ERR_KEY_TYPE_UNKNOWN;
2305 if (!sshkey_type_is_valid_ca(ca->type))
2306 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2307
2308 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2309 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2310
2311 cert = k->cert->certblob; /* for readability */
2312 sshbuf_reset(cert);
2313 if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)
2314 goto out;
2315
2316 /* -v01 certs put nonce first */
2317 arc4random_buf(&nonce, sizeof(nonce));
2318 if (!sshkey_cert_is_legacy(k)) {
2319 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2320 goto out;
2321 }
2322
2323 /* XXX this substantially duplicates to_blob(); refactor */
2324 switch (k->type) {
2325#ifdef WITH_OPENSSL
2326 case KEY_DSA_CERT_V00:
2327 case KEY_DSA_CERT:
2328 if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||
2329 (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||
2330 (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 ||
2331 (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0)
2332 goto out;
2333 break;
2334# ifdef OPENSSL_HAS_ECC
2335 case KEY_ECDSA_CERT:
2336 if ((ret = sshbuf_put_cstring(cert,
2337 sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 ||
2338 (ret = sshbuf_put_ec(cert,
2339 EC_KEY_get0_public_key(k->ecdsa),
2340 EC_KEY_get0_group(k->ecdsa))) != 0)
2341 goto out;
2342 break;
2343# endif /* OPENSSL_HAS_ECC */
2344 case KEY_RSA_CERT_V00:
2345 case KEY_RSA_CERT:
2346 if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||
2347 (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)
2348 goto out;
2349 break;
2350#endif /* WITH_OPENSSL */
2351 case KEY_ED25519_CERT:
2352 if ((ret = sshbuf_put_string(cert,
2353 k->ed25519_pk, ED25519_PK_SZ)) != 0)
2354 goto out;
2355 break;
2356 default:
2357 ret = SSH_ERR_INVALID_ARGUMENT;
2358 }
2359
2360 /* -v01 certs have a serial number next */
2361 if (!sshkey_cert_is_legacy(k)) {
2362 if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0)
2363 goto out;
2364 }
2365
2366 if ((ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
2367 (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
2368 goto out;
2369
2370 if ((principals = sshbuf_new()) == NULL) {
2371 ret = SSH_ERR_ALLOC_FAIL;
2372 goto out;
2373 }
2374 for (i = 0; i < k->cert->nprincipals; i++) {
2375 if ((ret = sshbuf_put_cstring(principals,
2376 k->cert->principals[i])) != 0)
2377 goto out;
2378 }
2379 if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
2380 (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
2381 (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
2382 (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0)
2383 goto out;
2384
2385 /* -v01 certs have non-critical options here */
2386 if (!sshkey_cert_is_legacy(k)) {
2387 if ((ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0)
2388 goto out;
2389 }
2390
2391 /* -v00 certs put the nonce at the end */
2392 if (sshkey_cert_is_legacy(k)) {
2393 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2394 goto out;
2395 }
2396
2397 if ((ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2398 (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2399 goto out;
2400
2401 /* Sign the whole mess */
2402 if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2403 sshbuf_len(cert), 0)) != 0)
2404 goto out;
2405
2406 /* Append signature and we are done */
2407 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
2408 goto out;
2409 ret = 0;
2410 out:
2411 if (ret != 0)
2412 sshbuf_reset(cert);
2413 if (sig_blob != NULL)
2414 free(sig_blob);
2415 if (ca_blob != NULL)
2416 free(ca_blob);
2417 if (principals != NULL)
2418 sshbuf_free(principals);
2419 return ret;
2420}
2421
2422int
2423sshkey_cert_check_authority(const struct sshkey *k,
2424 int want_host, int require_principal,
2425 const char *name, const char **reason)
2426{
2427 u_int i, principal_matches;
2428 time_t now = time(NULL);
2429
2430 if (reason != NULL)
2431 *reason = NULL;
2432
2433 if (want_host) {
2434 if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2435 *reason = "Certificate invalid: not a host certificate";
2436 return SSH_ERR_KEY_CERT_INVALID;
2437 }
2438 } else {
2439 if (k->cert->type != SSH2_CERT_TYPE_USER) {
2440 *reason = "Certificate invalid: not a user certificate";
2441 return SSH_ERR_KEY_CERT_INVALID;
2442 }
2443 }
2444 if (now < 0) {
2445 /* yikes - system clock before epoch! */
2446 *reason = "Certificate invalid: not yet valid";
2447 return SSH_ERR_KEY_CERT_INVALID;
2448 }
2449 if ((u_int64_t)now < k->cert->valid_after) {
2450 *reason = "Certificate invalid: not yet valid";
2451 return SSH_ERR_KEY_CERT_INVALID;
2452 }
2453 if ((u_int64_t)now >= k->cert->valid_before) {
2454 *reason = "Certificate invalid: expired";
2455 return SSH_ERR_KEY_CERT_INVALID;
2456 }
2457 if (k->cert->nprincipals == 0) {
2458 if (require_principal) {
2459 *reason = "Certificate lacks principal list";
2460 return SSH_ERR_KEY_CERT_INVALID;
2461 }
2462 } else if (name != NULL) {
2463 principal_matches = 0;
2464 for (i = 0; i < k->cert->nprincipals; i++) {
2465 if (strcmp(name, k->cert->principals[i]) == 0) {
2466 principal_matches = 1;
2467 break;
2468 }
2469 }
2470 if (!principal_matches) {
2471 *reason = "Certificate invalid: name is not a listed "
2472 "principal";
2473 return SSH_ERR_KEY_CERT_INVALID;
2474 }
2475 }
2476 return 0;
2477}
2478
2479int
2480sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b)
2481{
2482 int r = SSH_ERR_INTERNAL_ERROR;
2483
2484 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2485 goto out;
2486 switch (key->type) {
2487#ifdef WITH_OPENSSL
2488 case KEY_RSA:
2489 if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 ||
2490 (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
2491 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
2492 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
2493 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
2494 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
2495 goto out;
2496 break;
2497 case KEY_RSA_CERT_V00:
2498 case KEY_RSA_CERT:
2499 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2500 r = SSH_ERR_INVALID_ARGUMENT;
2501 goto out;
2502 }
2503 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2504 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
2505 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
2506 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
2507 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
2508 goto out;
2509 break;
2510 case KEY_DSA:
2511 if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
2512 (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
2513 (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
2514 (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 ||
2515 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
2516 goto out;
2517 break;
2518 case KEY_DSA_CERT_V00:
2519 case KEY_DSA_CERT:
2520 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2521 r = SSH_ERR_INVALID_ARGUMENT;
2522 goto out;
2523 }
2524 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2525 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
2526 goto out;
2527 break;
2528# ifdef OPENSSL_HAS_ECC
2529 case KEY_ECDSA:
2530 if ((r = sshbuf_put_cstring(b,
2531 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
2532 (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||
2533 (r = sshbuf_put_bignum2(b,
2534 EC_KEY_get0_private_key(key->ecdsa))) != 0)
2535 goto out;
2536 break;
2537 case KEY_ECDSA_CERT:
2538 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2539 r = SSH_ERR_INVALID_ARGUMENT;
2540 goto out;
2541 }
2542 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2543 (r = sshbuf_put_bignum2(b,
2544 EC_KEY_get0_private_key(key->ecdsa))) != 0)
2545 goto out;
2546 break;
2547# endif /* OPENSSL_HAS_ECC */
2548#endif /* WITH_OPENSSL */
2549 case KEY_ED25519:
2550 if ((r = sshbuf_put_string(b, key->ed25519_pk,
2551 ED25519_PK_SZ)) != 0 ||
2552 (r = sshbuf_put_string(b, key->ed25519_sk,
2553 ED25519_SK_SZ)) != 0)
2554 goto out;
2555 break;
2556 case KEY_ED25519_CERT:
2557 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2558 r = SSH_ERR_INVALID_ARGUMENT;
2559 goto out;
2560 }
2561 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2562 (r = sshbuf_put_string(b, key->ed25519_pk,
2563 ED25519_PK_SZ)) != 0 ||
2564 (r = sshbuf_put_string(b, key->ed25519_sk,
2565 ED25519_SK_SZ)) != 0)
2566 goto out;
2567 break;
2568 default:
2569 r = SSH_ERR_INVALID_ARGUMENT;
2570 goto out;
2571 }
2572 /* success */
2573 r = 0;
2574 out:
2575 return r;
2576}
2577
2578int
2579sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2580{
2581 char *tname = NULL, *curve = NULL;
2582 struct sshkey *k = NULL;
2583 const u_char *cert;
2584 size_t len, pklen = 0, sklen = 0;
2585 int type, r = SSH_ERR_INTERNAL_ERROR;
2586 u_char *ed25519_pk = NULL, *ed25519_sk = NULL;
2587#ifdef WITH_OPENSSL
2588 BIGNUM *exponent = NULL;
2589#endif /* WITH_OPENSSL */
2590
2591 if (kp != NULL)
2592 *kp = NULL;
2593 if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
2594 goto out;
2595 type = sshkey_type_from_name(tname);
2596 switch (type) {
2597#ifdef WITH_OPENSSL
2598 case KEY_DSA:
2599 if ((k = sshkey_new_private(type)) == NULL) {
2600 r = SSH_ERR_ALLOC_FAIL;
2601 goto out;
2602 }
2603 if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 ||
2604 (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 ||
2605 (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 ||
2606 (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 ||
2607 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
2608 goto out;
2609 break;
2610 case KEY_DSA_CERT_V00:
2611 case KEY_DSA_CERT:
2612 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2613 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2614 (r = sshkey_add_private(k)) != 0 ||
2615 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
2616 goto out;
2617 break;
2618# ifdef OPENSSL_HAS_ECC
2619 case KEY_ECDSA:
2620 if ((k = sshkey_new_private(type)) == NULL) {
2621 r = SSH_ERR_ALLOC_FAIL;
2622 goto out;
2623 }
2624 if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
2625 r = SSH_ERR_INVALID_ARGUMENT;
2626 goto out;
2627 }
2628 if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)
2629 goto out;
2630 if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
2631 r = SSH_ERR_EC_CURVE_MISMATCH;
2632 goto out;
2633 }
2634 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
2635 if (k->ecdsa == NULL || (exponent = BN_new()) == NULL) {
2636 r = SSH_ERR_LIBCRYPTO_ERROR;
2637 goto out;
2638 }
2639 if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||
2640 (r = sshbuf_get_bignum2(buf, exponent)))
2641 goto out;
2642 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
2643 r = SSH_ERR_LIBCRYPTO_ERROR;
2644 goto out;
2645 }
2646 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2647 EC_KEY_get0_public_key(k->ecdsa)) != 0) ||
2648 (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
2649 goto out;
2650 break;
2651 case KEY_ECDSA_CERT:
2652 if ((exponent = BN_new()) == NULL) {
2653 r = SSH_ERR_LIBCRYPTO_ERROR;
2654 goto out;
2655 }
2656 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2657 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2658 (r = sshkey_add_private(k)) != 0 ||
2659 (r = sshbuf_get_bignum2(buf, exponent)) != 0)
2660 goto out;
2661 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
2662 r = SSH_ERR_LIBCRYPTO_ERROR;
2663 goto out;
2664 }
2665 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2666 EC_KEY_get0_public_key(k->ecdsa)) != 0) ||
2667 (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
2668 goto out;
2669 break;
2670# endif /* OPENSSL_HAS_ECC */
2671 case KEY_RSA:
2672 if ((k = sshkey_new_private(type)) == NULL) {
2673 r = SSH_ERR_ALLOC_FAIL;
2674 goto out;
2675 }
2676 if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 ||
2677 (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 ||
2678 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
2679 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
2680 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
2681 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
2682 (r = rsa_generate_additional_parameters(k->rsa)) != 0)
2683 goto out;
2684 break;
2685 case KEY_RSA_CERT_V00:
2686 case KEY_RSA_CERT:
2687 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2688 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2689 (r = sshkey_add_private(k)) != 0 ||
2690 (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) ||
2691 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) ||
2692 (r = sshbuf_get_bignum2(buf, k->rsa->p) != 0) ||
2693 (r = sshbuf_get_bignum2(buf, k->rsa->q) != 0) ||
2694 (r = rsa_generate_additional_parameters(k->rsa)) != 0)
2695 goto out;
2696 break;
2697#endif /* WITH_OPENSSL */
2698 case KEY_ED25519:
2699 if ((k = sshkey_new_private(type)) == NULL) {
2700 r = SSH_ERR_ALLOC_FAIL;
2701 goto out;
2702 }
2703 if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
2704 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
2705 goto out;
2706 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
2707 r = SSH_ERR_INVALID_FORMAT;
2708 goto out;
2709 }
2710 k->ed25519_pk = ed25519_pk;
2711 k->ed25519_sk = ed25519_sk;
2712 ed25519_pk = ed25519_sk = NULL;
2713 break;
2714 case KEY_ED25519_CERT:
2715 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2716 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2717 (r = sshkey_add_private(k)) != 0 ||
2718 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
2719 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
2720 goto out;
2721 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
2722 r = SSH_ERR_INVALID_FORMAT;
2723 goto out;
2724 }
2725 k->ed25519_pk = ed25519_pk;
2726 k->ed25519_sk = ed25519_sk;
2727 ed25519_pk = ed25519_sk = NULL;
2728 break;
2729 default:
2730 r = SSH_ERR_KEY_TYPE_UNKNOWN;
2731 goto out;
2732 }
2733#ifdef WITH_OPENSSL
2734 /* enable blinding */
2735 switch (k->type) {
2736 case KEY_RSA:
2737 case KEY_RSA_CERT_V00:
2738 case KEY_RSA_CERT:
2739 case KEY_RSA1:
2740 if (RSA_blinding_on(k->rsa, NULL) != 1) {
2741 r = SSH_ERR_LIBCRYPTO_ERROR;
2742 goto out;
2743 }
2744 break;
2745 }
2746#endif /* WITH_OPENSSL */
2747 /* success */
2748 r = 0;
2749 if (kp != NULL) {
2750 *kp = k;
2751 k = NULL;
2752 }
2753 out:
2754 free(tname);
2755 free(curve);
2756#ifdef WITH_OPENSSL
2757 if (exponent != NULL)
2758 BN_clear_free(exponent);
2759#endif /* WITH_OPENSSL */
2760 sshkey_free(k);
2761 if (ed25519_pk != NULL) {
2762 explicit_bzero(ed25519_pk, pklen);
2763 free(ed25519_pk);
2764 }
2765 if (ed25519_sk != NULL) {
2766 explicit_bzero(ed25519_sk, sklen);
2767 free(ed25519_sk);
2768 }
2769 return r;
2770}
2771
2772#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2773int
2774sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2775{
2776 BN_CTX *bnctx;
2777 EC_POINT *nq = NULL;
2778 BIGNUM *order, *x, *y, *tmp;
2779 int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2780
2781 if ((bnctx = BN_CTX_new()) == NULL)
2782 return SSH_ERR_ALLOC_FAIL;
2783 BN_CTX_start(bnctx);
2784
2785 /*
2786 * We shouldn't ever hit this case because bignum_get_ecpoint()
2787 * refuses to load GF2m points.
2788 */
2789 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2790 NID_X9_62_prime_field)
2791 goto out;
2792
2793 /* Q != infinity */
2794 if (EC_POINT_is_at_infinity(group, public))
2795 goto out;
2796
2797 if ((x = BN_CTX_get(bnctx)) == NULL ||
2798 (y = BN_CTX_get(bnctx)) == NULL ||
2799 (order = BN_CTX_get(bnctx)) == NULL ||
2800 (tmp = BN_CTX_get(bnctx)) == NULL) {
2801 ret = SSH_ERR_ALLOC_FAIL;
2802 goto out;
2803 }
2804
2805 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2806 if (EC_GROUP_get_order(group, order, bnctx) != 1 ||
2807 EC_POINT_get_affine_coordinates_GFp(group, public,
2808 x, y, bnctx) != 1) {
2809 ret = SSH_ERR_LIBCRYPTO_ERROR;
2810 goto out;
2811 }
2812 if (BN_num_bits(x) <= BN_num_bits(order) / 2 ||
2813 BN_num_bits(y) <= BN_num_bits(order) / 2)
2814 goto out;
2815
2816 /* nQ == infinity (n == order of subgroup) */
2817 if ((nq = EC_POINT_new(group)) == NULL) {
2818 ret = SSH_ERR_ALLOC_FAIL;
2819 goto out;
2820 }
2821 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) {
2822 ret = SSH_ERR_LIBCRYPTO_ERROR;
2823 goto out;
2824 }
2825 if (EC_POINT_is_at_infinity(group, nq) != 1)
2826 goto out;
2827
2828 /* x < order - 1, y < order - 1 */
2829 if (!BN_sub(tmp, order, BN_value_one())) {
2830 ret = SSH_ERR_LIBCRYPTO_ERROR;
2831 goto out;
2832 }
2833 if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)
2834 goto out;
2835 ret = 0;
2836 out:
2837 BN_CTX_free(bnctx);
2838 if (nq != NULL)
2839 EC_POINT_free(nq);
2840 return ret;
2841}
2842
2843int
2844sshkey_ec_validate_private(const EC_KEY *key)
2845{
2846 BN_CTX *bnctx;
2847 BIGNUM *order, *tmp;
2848 int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2849
2850 if ((bnctx = BN_CTX_new()) == NULL)
2851 return SSH_ERR_ALLOC_FAIL;
2852 BN_CTX_start(bnctx);
2853
2854 if ((order = BN_CTX_get(bnctx)) == NULL ||
2855 (tmp = BN_CTX_get(bnctx)) == NULL) {
2856 ret = SSH_ERR_ALLOC_FAIL;
2857 goto out;
2858 }
2859
2860 /* log2(private) > log2(order)/2 */
2861 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) {
2862 ret = SSH_ERR_LIBCRYPTO_ERROR;
2863 goto out;
2864 }
2865 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2866 BN_num_bits(order) / 2)
2867 goto out;
2868
2869 /* private < order - 1 */
2870 if (!BN_sub(tmp, order, BN_value_one())) {
2871 ret = SSH_ERR_LIBCRYPTO_ERROR;
2872 goto out;
2873 }
2874 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)
2875 goto out;
2876 ret = 0;
2877 out:
2878 BN_CTX_free(bnctx);
2879 return ret;
2880}
2881
2882void
2883sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
2884{
2885 BIGNUM *x, *y;
2886 BN_CTX *bnctx;
2887
2888 if (point == NULL) {
2889 fputs("point=(NULL)\n", stderr);
2890 return;
2891 }
2892 if ((bnctx = BN_CTX_new()) == NULL) {
2893 fprintf(stderr, "%s: BN_CTX_new failed\n", __func__);
2894 return;
2895 }
2896 BN_CTX_start(bnctx);
2897 if ((x = BN_CTX_get(bnctx)) == NULL ||
2898 (y = BN_CTX_get(bnctx)) == NULL) {
2899 fprintf(stderr, "%s: BN_CTX_get failed\n", __func__);
2900 return;
2901 }
2902 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2903 NID_X9_62_prime_field) {
2904 fprintf(stderr, "%s: group is not a prime field\n", __func__);
2905 return;
2906 }
2907 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y,
2908 bnctx) != 1) {
2909 fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
2910 __func__);
2911 return;
2912 }
2913 fputs("x=", stderr);
2914 BN_print_fp(stderr, x);
2915 fputs("\ny=", stderr);
2916 BN_print_fp(stderr, y);
2917 fputs("\n", stderr);
2918 BN_CTX_free(bnctx);
2919}
2920
2921void
2922sshkey_dump_ec_key(const EC_KEY *key)
2923{
2924 const BIGNUM *exponent;
2925
2926 sshkey_dump_ec_point(EC_KEY_get0_group(key),
2927 EC_KEY_get0_public_key(key));
2928 fputs("exponent=", stderr);
2929 if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
2930 fputs("(NULL)", stderr);
2931 else
2932 BN_print_fp(stderr, EC_KEY_get0_private_key(key));
2933 fputs("\n", stderr);
2934}
2935#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2936
2937static int
2938sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
2939 const char *passphrase, const char *comment, const char *ciphername,
2940 int rounds)
2941{
2942 u_char *cp, *b64 = NULL, *key = NULL, *pubkeyblob = NULL;
2943 u_char salt[SALT_LEN];
2944 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
2945 u_int check;
2946 int r = SSH_ERR_INTERNAL_ERROR;
2947 struct sshcipher_ctx ciphercontext;
2948 const struct sshcipher *cipher;
2949 const char *kdfname = KDFNAME;
2950 struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;
2951
2952 memset(&ciphercontext, 0, sizeof(ciphercontext));
2953
2954 if (rounds <= 0)
2955 rounds = DEFAULT_ROUNDS;
2956 if (passphrase == NULL || !strlen(passphrase)) {
2957 ciphername = "none";
2958 kdfname = "none";
2959 } else if (ciphername == NULL)
2960 ciphername = DEFAULT_CIPHERNAME;
2961 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) {
2962 r = SSH_ERR_INVALID_ARGUMENT;
2963 goto out;
2964 }
2965 if ((cipher = cipher_by_name(ciphername)) == NULL) {
2966 r = SSH_ERR_INTERNAL_ERROR;
2967 goto out;
2968 }
2969
2970 if ((kdf = sshbuf_new()) == NULL ||
2971 (encoded = sshbuf_new()) == NULL ||
2972 (encrypted = sshbuf_new()) == NULL) {
2973 r = SSH_ERR_ALLOC_FAIL;
2974 goto out;
2975 }
2976 blocksize = cipher_blocksize(cipher);
2977 keylen = cipher_keylen(cipher);
2978 ivlen = cipher_ivlen(cipher);
2979 authlen = cipher_authlen(cipher);
2980 if ((key = calloc(1, keylen + ivlen)) == NULL) {
2981 r = SSH_ERR_ALLOC_FAIL;
2982 goto out;
2983 }
2984 if (strcmp(kdfname, "bcrypt") == 0) {
2985 arc4random_buf(salt, SALT_LEN);
2986 if (bcrypt_pbkdf(passphrase, strlen(passphrase),
2987 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {
2988 r = SSH_ERR_INVALID_ARGUMENT;
2989 goto out;
2990 }
2991 if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||
2992 (r = sshbuf_put_u32(kdf, rounds)) != 0)
2993 goto out;
2994 } else if (strcmp(kdfname, "none") != 0) {
2995 /* Unsupported KDF type */
2996 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
2997 goto out;
2998 }
2999 if ((r = cipher_init(&ciphercontext, cipher, key, keylen,
3000 key + keylen, ivlen, 1)) != 0)
3001 goto out;
3002
3003 if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||
3004 (r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||
3005 (r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||
3006 (r = sshbuf_put_stringb(encoded, kdf)) != 0 ||
3007 (r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */
3008 (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||
3009 (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)
3010 goto out;
3011
3012 /* set up the buffer that will be encrypted */
3013
3014 /* Random check bytes */
3015 check = arc4random();
3016 if ((r = sshbuf_put_u32(encrypted, check)) != 0 ||
3017 (r = sshbuf_put_u32(encrypted, check)) != 0)
3018 goto out;
3019
3020 /* append private key and comment*/
3021 if ((r = sshkey_private_serialize(prv, encrypted)) != 0 ||
3022 (r = sshbuf_put_cstring(encrypted, comment)) != 0)
3023 goto out;
3024
3025 /* padding */
3026 i = 0;
3027 while (sshbuf_len(encrypted) % blocksize) {
3028 if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)
3029 goto out;
3030 }
3031
3032 /* length in destination buffer */
3033 if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)
3034 goto out;
3035
3036 /* encrypt */
3037 if ((r = sshbuf_reserve(encoded,
3038 sshbuf_len(encrypted) + authlen, &cp)) != 0)
3039 goto out;
3040 if ((r = cipher_crypt(&ciphercontext, 0, cp,
3041 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
3042 goto out;
3043
3044 /* uuencode */
3045 if ((b64 = sshbuf_dtob64(encoded)) == NULL) {
3046 r = SSH_ERR_ALLOC_FAIL;
3047 goto out;
3048 }
3049
3050 sshbuf_reset(blob);
3051 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0)
3052 goto out;
3053 for (i = 0; i < strlen(b64); i++) {
3054 if ((r = sshbuf_put_u8(blob, b64[i])) != 0)
3055 goto out;
3056 /* insert line breaks */
3057 if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3058 goto out;
3059 }
3060 if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3061 goto out;
3062 if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
3063 goto out;
3064
3065 /* success */
3066 r = 0;
3067
3068 out:
3069 sshbuf_free(kdf);
3070 sshbuf_free(encoded);
3071 sshbuf_free(encrypted);
3072 cipher_cleanup(&ciphercontext);
3073 explicit_bzero(salt, sizeof(salt));
3074 if (key != NULL) {
3075 explicit_bzero(key, keylen + ivlen);
3076 free(key);
3077 }
3078 if (pubkeyblob != NULL) {
3079 explicit_bzero(pubkeyblob, pubkeylen);
3080 free(pubkeyblob);
3081 }
3082 if (b64 != NULL) {
3083 explicit_bzero(b64, strlen(b64));
3084 free(b64);
3085 }
3086 return r;
3087}
3088
3089static int
3090sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3091 struct sshkey **keyp, char **commentp)
3092{
3093 char *comment = NULL, *ciphername = NULL, *kdfname = NULL;
3094 const struct sshcipher *cipher = NULL;
3095 const u_char *cp;
3096 int r = SSH_ERR_INTERNAL_ERROR;
3097 size_t encoded_len;
3098 size_t i, keylen = 0, ivlen = 0, slen = 0;
3099 struct sshbuf *encoded = NULL, *decoded = NULL;
3100 struct sshbuf *kdf = NULL, *decrypted = NULL;
3101 struct sshcipher_ctx ciphercontext;
3102 struct sshkey *k = NULL;
3103 u_char *key = NULL, *salt = NULL, *dp, pad, last;
3104 u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
3105
3106 memset(&ciphercontext, 0, sizeof(ciphercontext));
3107 if (keyp != NULL)
3108 *keyp = NULL;
3109 if (commentp != NULL)
3110 *commentp = NULL;
3111
3112 if ((encoded = sshbuf_new()) == NULL ||
3113 (decoded = sshbuf_new()) == NULL ||
3114 (decrypted = sshbuf_new()) == NULL) {
3115 r = SSH_ERR_ALLOC_FAIL;
3116 goto out;
3117 }
3118
3119 /* check preamble */
3120 cp = sshbuf_ptr(blob);
3121 encoded_len = sshbuf_len(blob);
3122 if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) ||
3123 memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) {
3124 r = SSH_ERR_INVALID_FORMAT;
3125 goto out;
3126 }
3127 cp += MARK_BEGIN_LEN;
3128 encoded_len -= MARK_BEGIN_LEN;
3129
3130 /* Look for end marker, removing whitespace as we go */
3131 while (encoded_len > 0) {
3132 if (*cp != '\n' && *cp != '\r') {
3133 if ((r = sshbuf_put_u8(encoded, *cp)) != 0)
3134 goto out;
3135 }
3136 last = *cp;
3137 encoded_len--;
3138 cp++;
3139 if (last == '\n') {
3140 if (encoded_len >= MARK_END_LEN &&
3141 memcmp(cp, MARK_END, MARK_END_LEN) == 0) {
3142 /* \0 terminate */
3143 if ((r = sshbuf_put_u8(encoded, 0)) != 0)
3144 goto out;
3145 break;
3146 }
3147 }
3148 }
3149 if (encoded_len == 0) {
3150 r = SSH_ERR_INVALID_FORMAT;
3151 goto out;
3152 }
3153
3154 /* decode base64 */
3155 if ((r = sshbuf_b64tod(decoded, sshbuf_ptr(encoded))) != 0)
3156 goto out;
3157
3158 /* check magic */
3159 if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) ||
3160 memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
3161 r = SSH_ERR_INVALID_FORMAT;
3162 goto out;
3163 }
3164 /* parse public portion of key */
3165 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
3166 (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||
3167 (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||
3168 (r = sshbuf_froms(decoded, &kdf)) != 0 ||
3169 (r = sshbuf_get_u32(decoded, &nkeys)) != 0 ||
3170 (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */
3171 (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
3172 goto out;
3173
3174 if ((cipher = cipher_by_name(ciphername)) == NULL) {
3175 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3176 goto out;
3177 }
3178 if ((passphrase == NULL || strlen(passphrase) == 0) &&
3179 strcmp(ciphername, "none") != 0) {
3180 /* passphrase required */
3181 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3182 goto out;
3183 }
3184 if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) {
3185 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3186 goto out;
3187 }
3188 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
3189 r = SSH_ERR_INVALID_FORMAT;
3190 goto out;
3191 }
3192 if (nkeys != 1) {
3193 /* XXX only one key supported */
3194 r = SSH_ERR_INVALID_FORMAT;
3195 goto out;
3196 }
3197
3198 /* check size of encrypted key blob */
3199 blocksize = cipher_blocksize(cipher);
3200 if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {
3201 r = SSH_ERR_INVALID_FORMAT;
3202 goto out;
3203 }
3204
3205 /* setup key */
3206 keylen = cipher_keylen(cipher);
3207 ivlen = cipher_ivlen(cipher);
3208 if ((key = calloc(1, keylen + ivlen)) == NULL) {
3209 r = SSH_ERR_ALLOC_FAIL;
3210 goto out;
3211 }
3212 if (strcmp(kdfname, "bcrypt") == 0) {
3213 if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 ||
3214 (r = sshbuf_get_u32(kdf, &rounds)) != 0)
3215 goto out;
3216 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
3217 key, keylen + ivlen, rounds) < 0) {
3218 r = SSH_ERR_INVALID_FORMAT;
3219 goto out;
3220 }
3221 }
3222
3223 /* decrypt private portion of key */
3224 if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
3225 (r = cipher_init(&ciphercontext, cipher, key, keylen,
3226 key + keylen, ivlen, 0)) != 0)
3227 goto out;
3228 if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded),
3229 sshbuf_len(decoded), 0, cipher_authlen(cipher))) != 0) {
3230 /* an integrity error here indicates an incorrect passphrase */
3231 if (r == SSH_ERR_MAC_INVALID)
3232 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3233 goto out;
3234 }
3235 if ((r = sshbuf_consume(decoded, encrypted_len)) != 0)
3236 goto out;
3237 /* there should be no trailing data */
3238 if (sshbuf_len(decoded) != 0) {
3239 r = SSH_ERR_INVALID_FORMAT;
3240 goto out;
3241 }
3242
3243 /* check check bytes */
3244 if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 ||
3245 (r = sshbuf_get_u32(decrypted, &check2)) != 0)
3246 goto out;
3247 if (check1 != check2) {
3248 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3249 goto out;
3250 }
3251
3252 /* Load the private key and comment */
3253 if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
3254 (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
3255 goto out;
3256
3257 /* Check deterministic padding */
3258 i = 0;
3259 while (sshbuf_len(decrypted)) {
3260 if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
3261 goto out;
3262 if (pad != (++i & 0xff)) {
3263 r = SSH_ERR_INVALID_FORMAT;
3264 goto out;
3265 }
3266 }
3267
3268 /* XXX decode pubkey and check against private */
3269
3270 /* success */
3271 r = 0;
3272 if (keyp != NULL) {
3273 *keyp = k;
3274 k = NULL;
3275 }
3276 if (commentp != NULL) {
3277 *commentp = comment;
3278 comment = NULL;
3279 }
3280 out:
3281 pad = 0;
3282 cipher_cleanup(&ciphercontext);
3283 free(ciphername);
3284 free(kdfname);
3285 free(comment);
3286 if (salt != NULL) {
3287 explicit_bzero(salt, slen);
3288 free(salt);
3289 }
3290 if (key != NULL) {
3291 explicit_bzero(key, keylen + ivlen);
3292 free(key);
3293 }
3294 sshbuf_free(encoded);
3295 sshbuf_free(decoded);
3296 sshbuf_free(kdf);
3297 sshbuf_free(decrypted);
3298 sshkey_free(k);
3299 return r;
3300}
3301
3302#if WITH_SSH1
3303/*
3304 * Serialises the authentication (private) key to a blob, encrypting it with
3305 * passphrase. The identification of the blob (lowest 64 bits of n) will
3306 * precede the key to provide identification of the key without needing a
3307 * passphrase.
3308 */
3309static int
3310sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob,
3311 const char *passphrase, const char *comment)
3312{
3313 struct sshbuf *buffer = NULL, *encrypted = NULL;
3314 u_char buf[8];
3315 int r, cipher_num;
3316 struct sshcipher_ctx ciphercontext;
3317 const struct sshcipher *cipher;
3318 u_char *cp;
3319
3320 /*
3321 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
3322 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
3323 */
3324 cipher_num = (strcmp(passphrase, "") == 0) ?
3325 SSH_CIPHER_NONE : SSH_CIPHER_3DES;
3326 if ((cipher = cipher_by_number(cipher_num)) == NULL)
3327 return SSH_ERR_INTERNAL_ERROR;
3328
3329 /* This buffer is used to build the secret part of the private key. */
3330 if ((buffer = sshbuf_new()) == NULL)
3331 return SSH_ERR_ALLOC_FAIL;
3332
3333 /* Put checkbytes for checking passphrase validity. */
3334 if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0)
3335 goto out;
3336 arc4random_buf(cp, 2);
3337 memcpy(cp + 2, cp, 2);
3338
3339 /*
3340 * Store the private key (n and e will not be stored because they
3341 * will be stored in plain text, and storing them also in encrypted
3342 * format would just give known plaintext).
3343 * Note: q and p are stored in reverse order to SSL.
3344 */
3345 if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 ||
3346 (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 ||
3347 (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 ||
3348 (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0)
3349 goto out;
3350
3351 /* Pad the part to be encrypted to a size that is a multiple of 8. */
3352 explicit_bzero(buf, 8);
3353 if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0)
3354 goto out;
3355
3356 /* This buffer will be used to contain the data in the file. */
3357 if ((encrypted = sshbuf_new()) == NULL) {
3358 r = SSH_ERR_ALLOC_FAIL;
3359 goto out;
3360 }
3361
3362 /* First store keyfile id string. */
3363 if ((r = sshbuf_put(encrypted, LEGACY_BEGIN,
3364 sizeof(LEGACY_BEGIN))) != 0)
3365 goto out;
3366
3367 /* Store cipher type and "reserved" field. */
3368 if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 ||
3369 (r = sshbuf_put_u32(encrypted, 0)) != 0)
3370 goto out;
3371
3372 /* Store public key. This will be in plain text. */
3373 if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||
3374 (r = sshbuf_put_bignum1(encrypted, key->rsa->n) != 0) ||
3375 (r = sshbuf_put_bignum1(encrypted, key->rsa->e) != 0) ||
3376 (r = sshbuf_put_cstring(encrypted, comment) != 0))
3377 goto out;
3378
3379 /* Allocate space for the private part of the key in the buffer. */
3380 if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0)
3381 goto out;
3382
3383 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
3384 CIPHER_ENCRYPT)) != 0)
3385 goto out;
3386 if ((r = cipher_crypt(&ciphercontext, 0, cp,
3387 sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0)
3388 goto out;
3389 if ((r = cipher_cleanup(&ciphercontext)) != 0)
3390 goto out;
3391
3392 r = sshbuf_putb(blob, encrypted);
3393
3394 out:
3395 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
3396 explicit_bzero(buf, sizeof(buf));
3397 if (buffer != NULL)
3398 sshbuf_free(buffer);
3399 if (encrypted != NULL)
3400 sshbuf_free(encrypted);
3401
3402 return r;
3403}
3404#endif /* WITH_SSH1 */
3405
3406#ifdef WITH_OPENSSL
3407/* convert SSH v2 key in OpenSSL PEM format */
3408static int
3409sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3410 const char *_passphrase, const char *comment)
3411{
3412 int success, r;
3413 int blen, len = strlen(_passphrase);
3414 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
3415#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
3416 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
3417#else
3418 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3419#endif
3420 const u_char *bptr;
3421 BIO *bio = NULL;
3422
3423 if (len > 0 && len <= 4)
3424 return SSH_ERR_PASSPHRASE_TOO_SHORT;
3425 if ((bio = BIO_new(BIO_s_mem())) == NULL)
3426 return SSH_ERR_ALLOC_FAIL;
3427
3428 switch (key->type) {
3429 case KEY_DSA:
3430 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
3431 cipher, passphrase, len, NULL, NULL);
3432 break;
3433#ifdef OPENSSL_HAS_ECC
3434 case KEY_ECDSA:
3435 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
3436 cipher, passphrase, len, NULL, NULL);
3437 break;
3438#endif
3439 case KEY_RSA:
3440 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
3441 cipher, passphrase, len, NULL, NULL);
3442 break;
3443 default:
3444 success = 0;
3445 break;
3446 }
3447 if (success == 0) {
3448 r = SSH_ERR_LIBCRYPTO_ERROR;
3449 goto out;
3450 }
3451 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
3452 r = SSH_ERR_INTERNAL_ERROR;
3453 goto out;
3454 }
3455 if ((r = sshbuf_put(blob, bptr, blen)) != 0)
3456 goto out;
3457 r = 0;
3458 out:
3459 BIO_free(bio);
3460 return r;
3461}
3462#endif /* WITH_OPENSSL */
3463
3464/* Serialise "key" to buffer "blob" */
3465int
3466sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
3467 const char *passphrase, const char *comment,
3468 int force_new_format, const char *new_format_cipher, int new_format_rounds)
3469{
3470 switch (key->type) {
3471#ifdef WITH_OPENSSL
3472 case KEY_RSA1:
3473 return sshkey_private_rsa1_to_blob(key, blob,
3474 passphrase, comment);
3475 case KEY_DSA:
3476 case KEY_ECDSA:
3477 case KEY_RSA:
3478 if (force_new_format) {
3479 return sshkey_private_to_blob2(key, blob, passphrase,
3480 comment, new_format_cipher, new_format_rounds);
3481 }
3482 return sshkey_private_pem_to_blob(key, blob,
3483 passphrase, comment);
3484#endif /* WITH_OPENSSL */
3485 case KEY_ED25519:
3486 return sshkey_private_to_blob2(key, blob, passphrase,
3487 comment, new_format_cipher, new_format_rounds);
3488 default:
3489 return SSH_ERR_KEY_TYPE_UNKNOWN;
3490 }
3491}
3492
3493#ifdef WITH_SSH1
3494/*
3495 * Parse the public, unencrypted portion of a RSA1 key.
3496 */
3497int
3498sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,
3499 struct sshkey **keyp, char **commentp)
3500{
3501 int r;
3502 struct sshkey *pub = NULL;
3503 struct sshbuf *copy = NULL;
3504
3505 if (keyp != NULL)
3506 *keyp = NULL;
3507 if (commentp != NULL)
3508 *commentp = NULL;
3509
3510 /* Check that it is at least big enough to contain the ID string. */
3511 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
3512 return SSH_ERR_INVALID_FORMAT;
3513
3514 /*
3515 * Make sure it begins with the id string. Consume the id string
3516 * from the buffer.
3517 */
3518 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)
3519 return SSH_ERR_INVALID_FORMAT;
3520 /* Make a working copy of the keyblob and skip past the magic */
3521 if ((copy = sshbuf_fromb(blob)) == NULL)
3522 return SSH_ERR_ALLOC_FAIL;
3523 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
3524 goto out;
3525
3526 /* Skip cipher type, reserved data and key bits. */
3527 if ((r = sshbuf_get_u8(copy, NULL)) != 0 || /* cipher type */
3528 (r = sshbuf_get_u32(copy, NULL)) != 0 || /* reserved */
3529 (r = sshbuf_get_u32(copy, NULL)) != 0) /* key bits */
3530 goto out;
3531
3532 /* Read the public key from the buffer. */
3533 if ((pub = sshkey_new(KEY_RSA1)) == NULL ||
3534 (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 ||
3535 (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0)
3536 goto out;
3537
3538 /* Finally, the comment */
3539 if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0)
3540 goto out;
3541
3542 /* The encrypted private part is not parsed by this function. */
3543
3544 r = 0;
3545 if (keyp != NULL)
3546 *keyp = pub;
3547 else
3548 sshkey_free(pub);
3549 pub = NULL;
3550
3551 out:
3552 if (copy != NULL)
3553 sshbuf_free(copy);
3554 if (pub != NULL)
3555 sshkey_free(pub);
3556 return r;
3557}
3558
3559static int
3560sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase,
3561 struct sshkey **keyp, char **commentp)
3562{
3563 int r;
3564 u_int16_t check1, check2;
3565 u_int8_t cipher_type;
3566 struct sshbuf *decrypted = NULL, *copy = NULL;
3567 u_char *cp;
3568 char *comment = NULL;
3569 struct sshcipher_ctx ciphercontext;
3570 const struct sshcipher *cipher;
3571 struct sshkey *prv = NULL;
3572
3573 *keyp = NULL;
3574 if (commentp != NULL)
3575 *commentp = NULL;
3576
3577 /* Check that it is at least big enough to contain the ID string. */
3578 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
3579 return SSH_ERR_INVALID_FORMAT;
3580
3581 /*
3582 * Make sure it begins with the id string. Consume the id string
3583 * from the buffer.
3584 */
3585 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)
3586 return SSH_ERR_INVALID_FORMAT;
3587
3588 if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) {
3589 r = SSH_ERR_ALLOC_FAIL;
3590 goto out;
3591 }
3592 if ((copy = sshbuf_fromb(blob)) == NULL ||
3593 (decrypted = sshbuf_new()) == NULL) {
3594 r = SSH_ERR_ALLOC_FAIL;
3595 goto out;
3596 }
3597 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
3598 goto out;
3599
3600 /* Read cipher type. */
3601 if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 ||
3602 (r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */
3603 goto out;
3604
3605 /* Read the public key and comment from the buffer. */
3606 if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */
3607 (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 ||
3608 (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 ||
3609 (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0)
3610 goto out;
3611
3612 /* Check that it is a supported cipher. */
3613 cipher = cipher_by_number(cipher_type);
3614 if (cipher == NULL) {
3615 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3616 goto out;
3617 }
3618 /* Initialize space for decrypted data. */
3619 if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0)
3620 goto out;
3621
3622 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
3623 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
3624 CIPHER_DECRYPT)) != 0)
3625 goto out;
3626 if ((r = cipher_crypt(&ciphercontext, 0, cp,
3627 sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) {
3628 cipher_cleanup(&ciphercontext);
3629 goto out;
3630 }
3631 if ((r = cipher_cleanup(&ciphercontext)) != 0)
3632 goto out;
3633
3634 if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 ||
3635 (r = sshbuf_get_u16(decrypted, &check2)) != 0)
3636 goto out;
3637 if (check1 != check2) {
3638 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3639 goto out;
3640 }
3641
3642 /* Read the rest of the private key. */
3643 if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 ||
3644 (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 ||
3645 (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 ||
3646 (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0)
3647 goto out;
3648
3649 /* calculate p-1 and q-1 */
3650 if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)
3651 goto out;
3652
3653 /* enable blinding */
3654 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
3655 r = SSH_ERR_LIBCRYPTO_ERROR;
3656 goto out;
3657 }
3658 r = 0;
3659 *keyp = prv;
3660 prv = NULL;
3661 if (commentp != NULL) {
3662 *commentp = comment;
3663 comment = NULL;
3664 }
3665 out:
3666 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
3667 if (comment != NULL)
3668 free(comment);
3669 if (prv != NULL)
3670 sshkey_free(prv);
3671 if (copy != NULL)
3672 sshbuf_free(copy);
3673 if (decrypted != NULL)
3674 sshbuf_free(decrypted);
3675 return r;
3676}
3677#endif /* WITH_SSH1 */
3678
3679#ifdef WITH_OPENSSL
3680/* XXX make private once ssh-keysign.c fixed */
3681int
3682sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3683 const char *passphrase, struct sshkey **keyp, char **commentp)
3684{
3685 EVP_PKEY *pk = NULL;
3686 struct sshkey *prv = NULL;
3687 char *name = "<no key>";
3688 BIO *bio = NULL;
3689 int r;
3690
3691 *keyp = NULL;
3692 if (commentp != NULL)
3693 *commentp = NULL;
3694
3695 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
3696 return SSH_ERR_ALLOC_FAIL;
3697 if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
3698 (int)sshbuf_len(blob)) {
3699 r = SSH_ERR_ALLOC_FAIL;
3700 goto out;
3701 }
3702
3703 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3704 (char *)passphrase)) == NULL) {
3705 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3706 goto out;
3707 }
3708 if (pk->type == EVP_PKEY_RSA &&
3709 (type == KEY_UNSPEC || type == KEY_RSA)) {
3710 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3711 r = SSH_ERR_ALLOC_FAIL;
3712 goto out;
3713 }
3714 prv->rsa = EVP_PKEY_get1_RSA(pk);
3715 prv->type = KEY_RSA;
3716 name = "rsa w/o comment";
3717#ifdef DEBUG_PK
3718 RSA_print_fp(stderr, prv->rsa, 8);
3719#endif
3720 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
3721 r = SSH_ERR_LIBCRYPTO_ERROR;
3722 goto out;
3723 }
3724 } else if (pk->type == EVP_PKEY_DSA &&
3725 (type == KEY_UNSPEC || type == KEY_DSA)) {
3726 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3727 r = SSH_ERR_ALLOC_FAIL;
3728 goto out;
3729 }
3730 prv->dsa = EVP_PKEY_get1_DSA(pk);
3731 prv->type = KEY_DSA;
3732 name = "dsa w/o comment";
3733#ifdef DEBUG_PK
3734 DSA_print_fp(stderr, prv->dsa, 8);
3735#endif
3736#ifdef OPENSSL_HAS_ECC
3737 } else if (pk->type == EVP_PKEY_EC &&
3738 (type == KEY_UNSPEC || type == KEY_ECDSA)) {
3739 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3740 r = SSH_ERR_ALLOC_FAIL;
3741 goto out;
3742 }
3743 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
3744 prv->type = KEY_ECDSA;
3745 prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);
3746 if (prv->ecdsa_nid == -1 ||
3747 sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
3748 sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
3749 EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
3750 sshkey_ec_validate_private(prv->ecdsa) != 0) {
3751 r = SSH_ERR_INVALID_FORMAT;
3752 goto out;
3753 }
3754 name = "ecdsa w/o comment";
3755# ifdef DEBUG_PK
3756 if (prv != NULL && prv->ecdsa != NULL)
3757 sshkey_dump_ec_key(prv->ecdsa);
3758# endif
3759#endif /* OPENSSL_HAS_ECC */
3760 } else {
3761 r = SSH_ERR_INVALID_FORMAT;
3762 goto out;
3763 }
3764 if (commentp != NULL &&
3765 (*commentp = strdup(name)) == NULL) {
3766 r = SSH_ERR_ALLOC_FAIL;
3767 goto out;
3768 }
3769 r = 0;
3770 *keyp = prv;
3771 prv = NULL;
3772 out:
3773 BIO_free(bio);
3774 if (pk != NULL)
3775 EVP_PKEY_free(pk);
3776 if (prv != NULL)
3777 sshkey_free(prv);
3778 return r;
3779}
3780#endif /* WITH_OPENSSL */
3781
3782int
3783sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3784 const char *passphrase, struct sshkey **keyp, char **commentp)
3785{
3786 int r;
3787
3788 *keyp = NULL;
3789 if (commentp != NULL)
3790 *commentp = NULL;
3791
3792 switch (type) {
3793#ifdef WITH_OPENSSL
3794 case KEY_RSA1:
3795 return sshkey_parse_private_rsa1(blob, passphrase,
3796 keyp, commentp);
3797 case KEY_DSA:
3798 case KEY_ECDSA:
3799 case KEY_RSA:
3800 return sshkey_parse_private_pem_fileblob(blob, type, passphrase,
3801 keyp, commentp);
3802#endif /* WITH_OPENSSL */
3803 case KEY_ED25519:
3804 return sshkey_parse_private2(blob, type, passphrase,
3805 keyp, commentp);
3806 case KEY_UNSPEC:
3807 if ((r = sshkey_parse_private2(blob, type, passphrase, keyp,
3808 commentp)) == 0)
3809 return 0;
3810#ifdef WITH_OPENSSL
3811 return sshkey_parse_private_pem_fileblob(blob, type, passphrase,
3812 keyp, commentp);
3813#else
3814 return SSH_ERR_INVALID_FORMAT;
3815#endif /* WITH_OPENSSL */
3816 default:
3817 return SSH_ERR_KEY_TYPE_UNKNOWN;
3818 }
3819}
3820
3821int
3822sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
3823 const char *filename, struct sshkey **keyp, char **commentp)
3824{
3825 int r;
3826
3827 if (keyp != NULL)
3828 *keyp = NULL;
3829 if (commentp != NULL)
3830 *commentp = NULL;
3831
3832#ifdef WITH_SSH1
3833 /* it's a SSH v1 key if the public key part is readable */
3834 if ((r = sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL)) == 0) {
3835 return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1,
3836 passphrase, keyp, commentp);
3837 }
3838#endif /* WITH_SSH1 */
3839 if ((r = sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
3840 passphrase, keyp, commentp)) == 0)
3841 return 0;
3842 return r;
3843}