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