]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/sshkey.c
ssh: Update to OpenSSH 9.4p1
[FreeBSD/FreeBSD.git] / crypto / openssh / sshkey.c
1 /* $OpenBSD: sshkey.c,v 1.137 2023/07/27 22:23:05 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          24
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, int plain_only)
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                 } else if (plain_only && sshkey_type_is_cert(type)) {
377                         free(s);
378                         return 0;
379                 }
380         }
381         free(s);
382         return 1;
383 }
384
385 u_int
386 sshkey_size(const struct sshkey *k)
387 {
388         const struct sshkey_impl *impl;
389
390         if ((impl = sshkey_impl_from_key(k)) == NULL)
391                 return 0;
392         if (impl->funcs->size != NULL)
393                 return impl->funcs->size(k);
394         return impl->keybits;
395 }
396
397 static int
398 sshkey_type_is_valid_ca(int type)
399 {
400         const struct sshkey_impl *impl;
401
402         if ((impl = sshkey_impl_from_type(type)) == NULL)
403                 return 0;
404         /* All non-certificate types may act as CAs */
405         return !impl->cert;
406 }
407
408 int
409 sshkey_is_cert(const struct sshkey *k)
410 {
411         if (k == NULL)
412                 return 0;
413         return sshkey_type_is_cert(k->type);
414 }
415
416 int
417 sshkey_is_sk(const struct sshkey *k)
418 {
419         if (k == NULL)
420                 return 0;
421         switch (sshkey_type_plain(k->type)) {
422         case KEY_ECDSA_SK:
423         case KEY_ED25519_SK:
424                 return 1;
425         default:
426                 return 0;
427         }
428 }
429
430 /* Return the cert-less equivalent to a certified key type */
431 int
432 sshkey_type_plain(int type)
433 {
434         switch (type) {
435         case KEY_RSA_CERT:
436                 return KEY_RSA;
437         case KEY_DSA_CERT:
438                 return KEY_DSA;
439         case KEY_ECDSA_CERT:
440                 return KEY_ECDSA;
441         case KEY_ECDSA_SK_CERT:
442                 return KEY_ECDSA_SK;
443         case KEY_ED25519_CERT:
444                 return KEY_ED25519;
445         case KEY_ED25519_SK_CERT:
446                 return KEY_ED25519_SK;
447         case KEY_XMSS_CERT:
448                 return KEY_XMSS;
449         default:
450                 return type;
451         }
452 }
453
454 /* Return the cert equivalent to a plain key type */
455 static int
456 sshkey_type_certified(int type)
457 {
458         switch (type) {
459         case KEY_RSA:
460                 return KEY_RSA_CERT;
461         case KEY_DSA:
462                 return KEY_DSA_CERT;
463         case KEY_ECDSA:
464                 return KEY_ECDSA_CERT;
465         case KEY_ECDSA_SK:
466                 return KEY_ECDSA_SK_CERT;
467         case KEY_ED25519:
468                 return KEY_ED25519_CERT;
469         case KEY_ED25519_SK:
470                 return KEY_ED25519_SK_CERT;
471         case KEY_XMSS:
472                 return KEY_XMSS_CERT;
473         default:
474                 return -1;
475         }
476 }
477
478 #ifdef WITH_OPENSSL
479 /* XXX: these are really begging for a table-driven approach */
480 int
481 sshkey_curve_name_to_nid(const char *name)
482 {
483         if (strcmp(name, "nistp256") == 0)
484                 return NID_X9_62_prime256v1;
485         else if (strcmp(name, "nistp384") == 0)
486                 return NID_secp384r1;
487 # ifdef OPENSSL_HAS_NISTP521
488         else if (strcmp(name, "nistp521") == 0)
489                 return NID_secp521r1;
490 # endif /* OPENSSL_HAS_NISTP521 */
491         else
492                 return -1;
493 }
494
495 u_int
496 sshkey_curve_nid_to_bits(int nid)
497 {
498         switch (nid) {
499         case NID_X9_62_prime256v1:
500                 return 256;
501         case NID_secp384r1:
502                 return 384;
503 # ifdef OPENSSL_HAS_NISTP521
504         case NID_secp521r1:
505                 return 521;
506 # endif /* OPENSSL_HAS_NISTP521 */
507         default:
508                 return 0;
509         }
510 }
511
512 int
513 sshkey_ecdsa_bits_to_nid(int bits)
514 {
515         switch (bits) {
516         case 256:
517                 return NID_X9_62_prime256v1;
518         case 384:
519                 return NID_secp384r1;
520 # ifdef OPENSSL_HAS_NISTP521
521         case 521:
522                 return NID_secp521r1;
523 # endif /* OPENSSL_HAS_NISTP521 */
524         default:
525                 return -1;
526         }
527 }
528
529 const char *
530 sshkey_curve_nid_to_name(int nid)
531 {
532         switch (nid) {
533         case NID_X9_62_prime256v1:
534                 return "nistp256";
535         case NID_secp384r1:
536                 return "nistp384";
537 # ifdef OPENSSL_HAS_NISTP521
538         case NID_secp521r1:
539                 return "nistp521";
540 # endif /* OPENSSL_HAS_NISTP521 */
541         default:
542                 return NULL;
543         }
544 }
545
546 int
547 sshkey_ec_nid_to_hash_alg(int nid)
548 {
549         int kbits = sshkey_curve_nid_to_bits(nid);
550
551         if (kbits <= 0)
552                 return -1;
553
554         /* RFC5656 section 6.2.1 */
555         if (kbits <= 256)
556                 return SSH_DIGEST_SHA256;
557         else if (kbits <= 384)
558                 return SSH_DIGEST_SHA384;
559         else
560                 return SSH_DIGEST_SHA512;
561 }
562 #endif /* WITH_OPENSSL */
563
564 static void
565 cert_free(struct sshkey_cert *cert)
566 {
567         u_int i;
568
569         if (cert == NULL)
570                 return;
571         sshbuf_free(cert->certblob);
572         sshbuf_free(cert->critical);
573         sshbuf_free(cert->extensions);
574         free(cert->key_id);
575         for (i = 0; i < cert->nprincipals; i++)
576                 free(cert->principals[i]);
577         free(cert->principals);
578         sshkey_free(cert->signature_key);
579         free(cert->signature_type);
580         freezero(cert, sizeof(*cert));
581 }
582
583 static struct sshkey_cert *
584 cert_new(void)
585 {
586         struct sshkey_cert *cert;
587
588         if ((cert = calloc(1, sizeof(*cert))) == NULL)
589                 return NULL;
590         if ((cert->certblob = sshbuf_new()) == NULL ||
591             (cert->critical = sshbuf_new()) == NULL ||
592             (cert->extensions = sshbuf_new()) == NULL) {
593                 cert_free(cert);
594                 return NULL;
595         }
596         cert->key_id = NULL;
597         cert->principals = NULL;
598         cert->signature_key = NULL;
599         cert->signature_type = NULL;
600         return cert;
601 }
602
603 struct sshkey *
604 sshkey_new(int type)
605 {
606         struct sshkey *k;
607         const struct sshkey_impl *impl = NULL;
608
609         if (type != KEY_UNSPEC &&
610             (impl = sshkey_impl_from_type(type)) == NULL)
611                 return NULL;
612
613         /* All non-certificate types may act as CAs */
614         if ((k = calloc(1, sizeof(*k))) == NULL)
615                 return NULL;
616         k->type = type;
617         k->ecdsa_nid = -1;
618         if (impl != NULL && impl->funcs->alloc != NULL) {
619                 if (impl->funcs->alloc(k) != 0) {
620                         free(k);
621                         return NULL;
622                 }
623         }
624         if (sshkey_is_cert(k)) {
625                 if ((k->cert = cert_new()) == NULL) {
626                         sshkey_free(k);
627                         return NULL;
628                 }
629         }
630
631         return k;
632 }
633
634 /* Frees common FIDO fields */
635 void
636 sshkey_sk_cleanup(struct sshkey *k)
637 {
638         free(k->sk_application);
639         sshbuf_free(k->sk_key_handle);
640         sshbuf_free(k->sk_reserved);
641         k->sk_application = NULL;
642         k->sk_key_handle = k->sk_reserved = NULL;
643 }
644
645 static void
646 sshkey_free_contents(struct sshkey *k)
647 {
648         const struct sshkey_impl *impl;
649
650         if (k == NULL)
651                 return;
652         if ((impl = sshkey_impl_from_type(k->type)) != NULL &&
653             impl->funcs->cleanup != NULL)
654                 impl->funcs->cleanup(k);
655         if (sshkey_is_cert(k))
656                 cert_free(k->cert);
657         freezero(k->shielded_private, k->shielded_len);
658         freezero(k->shield_prekey, k->shield_prekey_len);
659 }
660
661 void
662 sshkey_free(struct sshkey *k)
663 {
664         sshkey_free_contents(k);
665         freezero(k, sizeof(*k));
666 }
667
668 static int
669 cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
670 {
671         if (a == NULL && b == NULL)
672                 return 1;
673         if (a == NULL || b == NULL)
674                 return 0;
675         if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob))
676                 return 0;
677         if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob),
678             sshbuf_len(a->certblob)) != 0)
679                 return 0;
680         return 1;
681 }
682
683 /* Compares FIDO-specific pubkey fields only */
684 int
685 sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b)
686 {
687         if (a->sk_application == NULL || b->sk_application == NULL)
688                 return 0;
689         if (strcmp(a->sk_application, b->sk_application) != 0)
690                 return 0;
691         return 1;
692 }
693
694 /*
695  * Compare public portions of key only, allowing comparisons between
696  * certificates and plain keys too.
697  */
698 int
699 sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
700 {
701         const struct sshkey_impl *impl;
702
703         if (a == NULL || b == NULL ||
704             sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
705                 return 0;
706         if ((impl = sshkey_impl_from_type(a->type)) == NULL)
707                 return 0;
708         return impl->funcs->equal(a, b);
709 }
710
711 int
712 sshkey_equal(const struct sshkey *a, const struct sshkey *b)
713 {
714         if (a == NULL || b == NULL || a->type != b->type)
715                 return 0;
716         if (sshkey_is_cert(a)) {
717                 if (!cert_compare(a->cert, b->cert))
718                         return 0;
719         }
720         return sshkey_equal_public(a, b);
721 }
722
723
724 /* Serialise common FIDO key parts */
725 int
726 sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b)
727 {
728         int r;
729
730         if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0)
731                 return r;
732
733         return 0;
734 }
735
736 static int
737 to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
738   enum sshkey_serialize_rep opts)
739 {
740         int type, ret = SSH_ERR_INTERNAL_ERROR;
741         const char *typename;
742         const struct sshkey_impl *impl;
743
744         if (key == NULL)
745                 return SSH_ERR_INVALID_ARGUMENT;
746
747         type = force_plain ? sshkey_type_plain(key->type) : key->type;
748
749         if (sshkey_type_is_cert(type)) {
750                 if (key->cert == NULL)
751                         return SSH_ERR_EXPECTED_CERT;
752                 if (sshbuf_len(key->cert->certblob) == 0)
753                         return SSH_ERR_KEY_LACKS_CERTBLOB;
754                 /* Use the existing blob */
755                 if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
756                         return ret;
757                 return 0;
758         }
759         if ((impl = sshkey_impl_from_type(type)) == NULL)
760                 return SSH_ERR_KEY_TYPE_UNKNOWN;
761
762         typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
763         if ((ret = sshbuf_put_cstring(b, typename)) != 0)
764                 return ret;
765         return impl->funcs->serialize_public(key, b, opts);
766 }
767
768 int
769 sshkey_putb(const struct sshkey *key, struct sshbuf *b)
770 {
771         return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT);
772 }
773
774 int
775 sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b,
776     enum sshkey_serialize_rep opts)
777 {
778         struct sshbuf *tmp;
779         int r;
780
781         if ((tmp = sshbuf_new()) == NULL)
782                 return SSH_ERR_ALLOC_FAIL;
783         r = to_blob_buf(key, tmp, 0, opts);
784         if (r == 0)
785                 r = sshbuf_put_stringb(b, tmp);
786         sshbuf_free(tmp);
787         return r;
788 }
789
790 int
791 sshkey_puts(const struct sshkey *key, struct sshbuf *b)
792 {
793         return sshkey_puts_opts(key, b, SSHKEY_SERIALIZE_DEFAULT);
794 }
795
796 int
797 sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
798 {
799         return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT);
800 }
801
802 static int
803 to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain,
804     enum sshkey_serialize_rep opts)
805 {
806         int ret = SSH_ERR_INTERNAL_ERROR;
807         size_t len;
808         struct sshbuf *b = NULL;
809
810         if (lenp != NULL)
811                 *lenp = 0;
812         if (blobp != NULL)
813                 *blobp = NULL;
814         if ((b = sshbuf_new()) == NULL)
815                 return SSH_ERR_ALLOC_FAIL;
816         if ((ret = to_blob_buf(key, b, force_plain, opts)) != 0)
817                 goto out;
818         len = sshbuf_len(b);
819         if (lenp != NULL)
820                 *lenp = len;
821         if (blobp != NULL) {
822                 if ((*blobp = malloc(len)) == NULL) {
823                         ret = SSH_ERR_ALLOC_FAIL;
824                         goto out;
825                 }
826                 memcpy(*blobp, sshbuf_ptr(b), len);
827         }
828         ret = 0;
829  out:
830         sshbuf_free(b);
831         return ret;
832 }
833
834 int
835 sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
836 {
837         return to_blob(key, blobp, lenp, 0, SSHKEY_SERIALIZE_DEFAULT);
838 }
839
840 int
841 sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
842 {
843         return to_blob(key, blobp, lenp, 1, SSHKEY_SERIALIZE_DEFAULT);
844 }
845
846 int
847 sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
848     u_char **retp, size_t *lenp)
849 {
850         u_char *blob = NULL, *ret = NULL;
851         size_t blob_len = 0;
852         int r = SSH_ERR_INTERNAL_ERROR;
853
854         if (retp != NULL)
855                 *retp = NULL;
856         if (lenp != NULL)
857                 *lenp = 0;
858         if (ssh_digest_bytes(dgst_alg) == 0) {
859                 r = SSH_ERR_INVALID_ARGUMENT;
860                 goto out;
861         }
862         if ((r = to_blob(k, &blob, &blob_len, 1, SSHKEY_SERIALIZE_DEFAULT))
863             != 0)
864                 goto out;
865         if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
866                 r = SSH_ERR_ALLOC_FAIL;
867                 goto out;
868         }
869         if ((r = ssh_digest_memory(dgst_alg, blob, blob_len,
870             ret, SSH_DIGEST_MAX_LENGTH)) != 0)
871                 goto out;
872         /* success */
873         if (retp != NULL) {
874                 *retp = ret;
875                 ret = NULL;
876         }
877         if (lenp != NULL)
878                 *lenp = ssh_digest_bytes(dgst_alg);
879         r = 0;
880  out:
881         free(ret);
882         if (blob != NULL)
883                 freezero(blob, blob_len);
884         return r;
885 }
886
887 static char *
888 fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
889 {
890         char *ret;
891         size_t plen = strlen(alg) + 1;
892         size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
893
894         if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
895                 return NULL;
896         strlcpy(ret, alg, rlen);
897         strlcat(ret, ":", rlen);
898         if (dgst_raw_len == 0)
899                 return ret;
900         if (b64_ntop(dgst_raw, dgst_raw_len, ret + plen, rlen - plen) == -1) {
901                 freezero(ret, rlen);
902                 return NULL;
903         }
904         /* Trim padding characters from end */
905         ret[strcspn(ret, "=")] = '\0';
906         return ret;
907 }
908
909 static char *
910 fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
911 {
912         char *retval, hex[5];
913         size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;
914
915         if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)
916                 return NULL;
917         strlcpy(retval, alg, rlen);
918         strlcat(retval, ":", rlen);
919         for (i = 0; i < dgst_raw_len; i++) {
920                 snprintf(hex, sizeof(hex), "%s%02x",
921                     i > 0 ? ":" : "", dgst_raw[i]);
922                 strlcat(retval, hex, rlen);
923         }
924         return retval;
925 }
926
927 static char *
928 fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
929 {
930         char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
931         char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
932             'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
933         u_int i, j = 0, rounds, seed = 1;
934         char *retval;
935
936         rounds = (dgst_raw_len / 2) + 1;
937         if ((retval = calloc(rounds, 6)) == NULL)
938                 return NULL;
939         retval[j++] = 'x';
940         for (i = 0; i < rounds; i++) {
941                 u_int idx0, idx1, idx2, idx3, idx4;
942                 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
943                         idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
944                             seed) % 6;
945                         idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
946                         idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
947                             (seed / 6)) % 6;
948                         retval[j++] = vowels[idx0];
949                         retval[j++] = consonants[idx1];
950                         retval[j++] = vowels[idx2];
951                         if ((i + 1) < rounds) {
952                                 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
953                                 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
954                                 retval[j++] = consonants[idx3];
955                                 retval[j++] = '-';
956                                 retval[j++] = consonants[idx4];
957                                 seed = ((seed * 5) +
958                                     ((((u_int)(dgst_raw[2 * i])) * 7) +
959                                     ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
960                         }
961                 } else {
962                         idx0 = seed % 6;
963                         idx1 = 16;
964                         idx2 = seed / 6;
965                         retval[j++] = vowels[idx0];
966                         retval[j++] = consonants[idx1];
967                         retval[j++] = vowels[idx2];
968                 }
969         }
970         retval[j++] = 'x';
971         retval[j++] = '\0';
972         return retval;
973 }
974
975 /*
976  * Draw an ASCII-Art representing the fingerprint so human brain can
977  * profit from its built-in pattern recognition ability.
978  * This technique is called "random art" and can be found in some
979  * scientific publications like this original paper:
980  *
981  * "Hash Visualization: a New Technique to improve Real-World Security",
982  * Perrig A. and Song D., 1999, International Workshop on Cryptographic
983  * Techniques and E-Commerce (CrypTEC '99)
984  * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
985  *
986  * The subject came up in a talk by Dan Kaminsky, too.
987  *
988  * If you see the picture is different, the key is different.
989  * If the picture looks the same, you still know nothing.
990  *
991  * The algorithm used here is a worm crawling over a discrete plane,
992  * leaving a trace (augmenting the field) everywhere it goes.
993  * Movement is taken from dgst_raw 2bit-wise.  Bumping into walls
994  * makes the respective movement vector be ignored for this turn.
995  * Graphs are not unambiguous, because circles in graphs can be
996  * walked in either direction.
997  */
998
999 /*
1000  * Field sizes for the random art.  Have to be odd, so the starting point
1001  * can be in the exact middle of the picture, and FLDBASE should be >=8 .
1002  * Else pictures would be too dense, and drawing the frame would
1003  * fail, too, because the key type would not fit in anymore.
1004  */
1005 #define FLDBASE         8
1006 #define FLDSIZE_Y       (FLDBASE + 1)
1007 #define FLDSIZE_X       (FLDBASE * 2 + 1)
1008 static char *
1009 fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,
1010     const struct sshkey *k)
1011 {
1012         /*
1013          * Chars to be used after each other every time the worm
1014          * intersects with itself.  Matter of taste.
1015          */
1016         char    *augmentation_string = " .o+=*BOX@%&#/^SE";
1017         char    *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
1018         u_char   field[FLDSIZE_X][FLDSIZE_Y];
1019         size_t   i, tlen, hlen;
1020         u_int    b;
1021         int      x, y, r;
1022         size_t   len = strlen(augmentation_string) - 1;
1023
1024         if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)
1025                 return NULL;
1026
1027         /* initialize field */
1028         memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
1029         x = FLDSIZE_X / 2;
1030         y = FLDSIZE_Y / 2;
1031
1032         /* process raw key */
1033         for (i = 0; i < dgst_raw_len; i++) {
1034                 int input;
1035                 /* each byte conveys four 2-bit move commands */
1036                 input = dgst_raw[i];
1037                 for (b = 0; b < 4; b++) {
1038                         /* evaluate 2 bit, rest is shifted later */
1039                         x += (input & 0x1) ? 1 : -1;
1040                         y += (input & 0x2) ? 1 : -1;
1041
1042                         /* assure we are still in bounds */
1043                         x = MAXIMUM(x, 0);
1044                         y = MAXIMUM(y, 0);
1045                         x = MINIMUM(x, FLDSIZE_X - 1);
1046                         y = MINIMUM(y, FLDSIZE_Y - 1);
1047
1048                         /* augment the field */
1049                         if (field[x][y] < len - 2)
1050                                 field[x][y]++;
1051                         input = input >> 2;
1052                 }
1053         }
1054
1055         /* mark starting point and end point*/
1056         field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
1057         field[x][y] = len;
1058
1059         /* assemble title */
1060         r = snprintf(title, sizeof(title), "[%s %u]",
1061                 sshkey_type(k), sshkey_size(k));
1062         /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
1063         if (r < 0 || r > (int)sizeof(title))
1064                 r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
1065         tlen = (r <= 0) ? 0 : strlen(title);
1066
1067         /* assemble hash ID. */
1068         r = snprintf(hash, sizeof(hash), "[%s]", alg);
1069         hlen = (r <= 0) ? 0 : strlen(hash);
1070
1071         /* output upper border */
1072         p = retval;
1073         *p++ = '+';
1074         for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)
1075                 *p++ = '-';
1076         memcpy(p, title, tlen);
1077         p += tlen;
1078         for (i += tlen; i < FLDSIZE_X; i++)
1079                 *p++ = '-';
1080         *p++ = '+';
1081         *p++ = '\n';
1082
1083         /* output content */
1084         for (y = 0; y < FLDSIZE_Y; y++) {
1085                 *p++ = '|';
1086                 for (x = 0; x < FLDSIZE_X; x++)
1087                         *p++ = augmentation_string[MINIMUM(field[x][y], len)];
1088                 *p++ = '|';
1089                 *p++ = '\n';
1090         }
1091
1092         /* output lower border */
1093         *p++ = '+';
1094         for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
1095                 *p++ = '-';
1096         memcpy(p, hash, hlen);
1097         p += hlen;
1098         for (i += hlen; i < FLDSIZE_X; i++)
1099                 *p++ = '-';
1100         *p++ = '+';
1101
1102         return retval;
1103 }
1104
1105 char *
1106 sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
1107     enum sshkey_fp_rep dgst_rep)
1108 {
1109         char *retval = NULL;
1110         u_char *dgst_raw;
1111         size_t dgst_raw_len;
1112
1113         if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
1114                 return NULL;
1115         switch (dgst_rep) {
1116         case SSH_FP_DEFAULT:
1117                 if (dgst_alg == SSH_DIGEST_MD5) {
1118                         retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1119                             dgst_raw, dgst_raw_len);
1120                 } else {
1121                         retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1122                             dgst_raw, dgst_raw_len);
1123                 }
1124                 break;
1125         case SSH_FP_HEX:
1126                 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1127                     dgst_raw, dgst_raw_len);
1128                 break;
1129         case SSH_FP_BASE64:
1130                 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1131                     dgst_raw, dgst_raw_len);
1132                 break;
1133         case SSH_FP_BUBBLEBABBLE:
1134                 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1135                 break;
1136         case SSH_FP_RANDOMART:
1137                 retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),
1138                     dgst_raw, dgst_raw_len, k);
1139                 break;
1140         default:
1141                 freezero(dgst_raw, dgst_raw_len);
1142                 return NULL;
1143         }
1144         freezero(dgst_raw, dgst_raw_len);
1145         return retval;
1146 }
1147
1148 static int
1149 peek_type_nid(const char *s, size_t l, int *nid)
1150 {
1151         const struct sshkey_impl *impl;
1152         int i;
1153
1154         for (i = 0; keyimpls[i] != NULL; i++) {
1155                 impl = keyimpls[i];
1156                 if (impl->name == NULL || strlen(impl->name) != l)
1157                         continue;
1158                 if (memcmp(s, impl->name, l) == 0) {
1159                         *nid = -1;
1160                         if (key_type_is_ecdsa_variant(impl->type))
1161                                 *nid = impl->nid;
1162                         return impl->type;
1163                 }
1164         }
1165         return KEY_UNSPEC;
1166 }
1167
1168 /* XXX this can now be made const char * */
1169 int
1170 sshkey_read(struct sshkey *ret, char **cpp)
1171 {
1172         struct sshkey *k;
1173         char *cp, *blobcopy;
1174         size_t space;
1175         int r, type, curve_nid = -1;
1176         struct sshbuf *blob;
1177
1178         if (ret == NULL)
1179                 return SSH_ERR_INVALID_ARGUMENT;
1180         if (ret->type != KEY_UNSPEC && sshkey_impl_from_type(ret->type) == NULL)
1181                 return SSH_ERR_INVALID_ARGUMENT;
1182
1183         /* Decode type */
1184         cp = *cpp;
1185         space = strcspn(cp, " \t");
1186         if (space == strlen(cp))
1187                 return SSH_ERR_INVALID_FORMAT;
1188         if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC)
1189                 return SSH_ERR_INVALID_FORMAT;
1190
1191         /* skip whitespace */
1192         for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1193                 ;
1194         if (*cp == '\0')
1195                 return SSH_ERR_INVALID_FORMAT;
1196         if (ret->type != KEY_UNSPEC && ret->type != type)
1197                 return SSH_ERR_KEY_TYPE_MISMATCH;
1198         if ((blob = sshbuf_new()) == NULL)
1199                 return SSH_ERR_ALLOC_FAIL;
1200
1201         /* find end of keyblob and decode */
1202         space = strcspn(cp, " \t");
1203         if ((blobcopy = strndup(cp, space)) == NULL) {
1204                 sshbuf_free(blob);
1205                 return SSH_ERR_ALLOC_FAIL;
1206         }
1207         if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) {
1208                 free(blobcopy);
1209                 sshbuf_free(blob);
1210                 return r;
1211         }
1212         free(blobcopy);
1213         if ((r = sshkey_fromb(blob, &k)) != 0) {
1214                 sshbuf_free(blob);
1215                 return r;
1216         }
1217         sshbuf_free(blob);
1218
1219         /* skip whitespace and leave cp at start of comment */
1220         for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1221                 ;
1222
1223         /* ensure type of blob matches type at start of line */
1224         if (k->type != type) {
1225                 sshkey_free(k);
1226                 return SSH_ERR_KEY_TYPE_MISMATCH;
1227         }
1228         if (key_type_is_ecdsa_variant(type) && curve_nid != k->ecdsa_nid) {
1229                 sshkey_free(k);
1230                 return SSH_ERR_EC_CURVE_MISMATCH;
1231         }
1232
1233         /* Fill in ret from parsed key */
1234         sshkey_free_contents(ret);
1235         *ret = *k;
1236         freezero(k, sizeof(*k));
1237
1238         /* success */
1239         *cpp = cp;
1240         return 0;
1241 }
1242
1243 int
1244 sshkey_to_base64(const struct sshkey *key, char **b64p)
1245 {
1246         int r = SSH_ERR_INTERNAL_ERROR;
1247         struct sshbuf *b = NULL;
1248         char *uu = NULL;
1249
1250         if (b64p != NULL)
1251                 *b64p = NULL;
1252         if ((b = sshbuf_new()) == NULL)
1253                 return SSH_ERR_ALLOC_FAIL;
1254         if ((r = sshkey_putb(key, b)) != 0)
1255                 goto out;
1256         if ((uu = sshbuf_dtob64_string(b, 0)) == NULL) {
1257                 r = SSH_ERR_ALLOC_FAIL;
1258                 goto out;
1259         }
1260         /* Success */
1261         if (b64p != NULL) {
1262                 *b64p = uu;
1263                 uu = NULL;
1264         }
1265         r = 0;
1266  out:
1267         sshbuf_free(b);
1268         free(uu);
1269         return r;
1270 }
1271
1272 int
1273 sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1274 {
1275         int r = SSH_ERR_INTERNAL_ERROR;
1276         char *uu = NULL;
1277
1278         if ((r = sshkey_to_base64(key, &uu)) != 0)
1279                 goto out;
1280         if ((r = sshbuf_putf(b, "%s %s",
1281             sshkey_ssh_name(key), uu)) != 0)
1282                 goto out;
1283         r = 0;
1284  out:
1285         free(uu);
1286         return r;
1287 }
1288
1289 int
1290 sshkey_write(const struct sshkey *key, FILE *f)
1291 {
1292         struct sshbuf *b = NULL;
1293         int r = SSH_ERR_INTERNAL_ERROR;
1294
1295         if ((b = sshbuf_new()) == NULL)
1296                 return SSH_ERR_ALLOC_FAIL;
1297         if ((r = sshkey_format_text(key, b)) != 0)
1298                 goto out;
1299         if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
1300                 if (feof(f))
1301                         errno = EPIPE;
1302                 r = SSH_ERR_SYSTEM_ERROR;
1303                 goto out;
1304         }
1305         /* Success */
1306         r = 0;
1307  out:
1308         sshbuf_free(b);
1309         return r;
1310 }
1311
1312 const char *
1313 sshkey_cert_type(const struct sshkey *k)
1314 {
1315         switch (k->cert->type) {
1316         case SSH2_CERT_TYPE_USER:
1317                 return "user";
1318         case SSH2_CERT_TYPE_HOST:
1319                 return "host";
1320         default:
1321                 return "unknown";
1322         }
1323 }
1324
1325 int
1326 sshkey_check_rsa_length(const struct sshkey *k, int min_size)
1327 {
1328 #ifdef WITH_OPENSSL
1329         const BIGNUM *rsa_n;
1330         int nbits;
1331
1332         if (k == NULL || k->rsa == NULL ||
1333             (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
1334                 return 0;
1335         RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
1336         nbits = BN_num_bits(rsa_n);
1337         if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1338             (min_size > 0 && nbits < min_size))
1339                 return SSH_ERR_KEY_LENGTH;
1340 #endif /* WITH_OPENSSL */
1341         return 0;
1342 }
1343
1344 #ifdef WITH_OPENSSL
1345 # ifdef OPENSSL_HAS_ECC
1346 int
1347 sshkey_ecdsa_key_to_nid(EC_KEY *k)
1348 {
1349         EC_GROUP *eg;
1350         int nids[] = {
1351                 NID_X9_62_prime256v1,
1352                 NID_secp384r1,
1353 #  ifdef OPENSSL_HAS_NISTP521
1354                 NID_secp521r1,
1355 #  endif /* OPENSSL_HAS_NISTP521 */
1356                 -1
1357         };
1358         int nid;
1359         u_int i;
1360         const EC_GROUP *g = EC_KEY_get0_group(k);
1361
1362         /*
1363          * The group may be stored in a ASN.1 encoded private key in one of two
1364          * ways: as a "named group", which is reconstituted by ASN.1 object ID
1365          * or explicit group parameters encoded into the key blob. Only the
1366          * "named group" case sets the group NID for us, but we can figure
1367          * it out for the other case by comparing against all the groups that
1368          * are supported.
1369          */
1370         if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1371                 return nid;
1372         for (i = 0; nids[i] != -1; i++) {
1373                 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
1374                         return -1;
1375                 if (EC_GROUP_cmp(g, eg, NULL) == 0)
1376                         break;
1377                 EC_GROUP_free(eg);
1378         }
1379         if (nids[i] != -1) {
1380                 /* Use the group with the NID attached */
1381                 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1382                 if (EC_KEY_set_group(k, eg) != 1) {
1383                         EC_GROUP_free(eg);
1384                         return -1;
1385                 }
1386         }
1387         return nids[i];
1388 }
1389 # endif /* OPENSSL_HAS_ECC */
1390 #endif /* WITH_OPENSSL */
1391
1392 int
1393 sshkey_generate(int type, u_int bits, struct sshkey **keyp)
1394 {
1395         struct sshkey *k;
1396         int ret = SSH_ERR_INTERNAL_ERROR;
1397         const struct sshkey_impl *impl;
1398
1399         if (keyp == NULL || sshkey_type_is_cert(type))
1400                 return SSH_ERR_INVALID_ARGUMENT;
1401         *keyp = NULL;
1402         if ((impl = sshkey_impl_from_type(type)) == NULL)
1403                 return SSH_ERR_KEY_TYPE_UNKNOWN;
1404         if (impl->funcs->generate == NULL)
1405                 return SSH_ERR_FEATURE_UNSUPPORTED;
1406         if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
1407                 return SSH_ERR_ALLOC_FAIL;
1408         k->type = type;
1409         if ((ret = impl->funcs->generate(k, bits)) != 0) {
1410                 sshkey_free(k);
1411                 return ret;
1412         }
1413         /* success */
1414         *keyp = k;
1415         return 0;
1416 }
1417
1418 int
1419 sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
1420 {
1421         u_int i;
1422         const struct sshkey_cert *from;
1423         struct sshkey_cert *to;
1424         int r = SSH_ERR_INTERNAL_ERROR;
1425
1426         if (to_key == NULL || (from = from_key->cert) == NULL)
1427                 return SSH_ERR_INVALID_ARGUMENT;
1428
1429         if ((to = cert_new()) == NULL)
1430                 return SSH_ERR_ALLOC_FAIL;
1431
1432         if ((r = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
1433             (r = sshbuf_putb(to->critical, from->critical)) != 0 ||
1434             (r = sshbuf_putb(to->extensions, from->extensions)) != 0)
1435                 goto out;
1436
1437         to->serial = from->serial;
1438         to->type = from->type;
1439         if (from->key_id == NULL)
1440                 to->key_id = NULL;
1441         else if ((to->key_id = strdup(from->key_id)) == NULL) {
1442                 r = SSH_ERR_ALLOC_FAIL;
1443                 goto out;
1444         }
1445         to->valid_after = from->valid_after;
1446         to->valid_before = from->valid_before;
1447         if (from->signature_key == NULL)
1448                 to->signature_key = NULL;
1449         else if ((r = sshkey_from_private(from->signature_key,
1450             &to->signature_key)) != 0)
1451                 goto out;
1452         if (from->signature_type != NULL &&
1453             (to->signature_type = strdup(from->signature_type)) == NULL) {
1454                 r = SSH_ERR_ALLOC_FAIL;
1455                 goto out;
1456         }
1457         if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) {
1458                 r = SSH_ERR_INVALID_ARGUMENT;
1459                 goto out;
1460         }
1461         if (from->nprincipals > 0) {
1462                 if ((to->principals = calloc(from->nprincipals,
1463                     sizeof(*to->principals))) == NULL) {
1464                         r = SSH_ERR_ALLOC_FAIL;
1465                         goto out;
1466                 }
1467                 for (i = 0; i < from->nprincipals; i++) {
1468                         to->principals[i] = strdup(from->principals[i]);
1469                         if (to->principals[i] == NULL) {
1470                                 to->nprincipals = i;
1471                                 r = SSH_ERR_ALLOC_FAIL;
1472                                 goto out;
1473                         }
1474                 }
1475         }
1476         to->nprincipals = from->nprincipals;
1477
1478         /* success */
1479         cert_free(to_key->cert);
1480         to_key->cert = to;
1481         to = NULL;
1482         r = 0;
1483  out:
1484         cert_free(to);
1485         return r;
1486 }
1487
1488 int
1489 sshkey_copy_public_sk(const struct sshkey *from, struct sshkey *to)
1490 {
1491         /* Append security-key application string */
1492         if ((to->sk_application = strdup(from->sk_application)) == NULL)
1493                 return SSH_ERR_ALLOC_FAIL;
1494         return 0;
1495 }
1496
1497 int
1498 sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1499 {
1500         struct sshkey *n = NULL;
1501         int r = SSH_ERR_INTERNAL_ERROR;
1502         const struct sshkey_impl *impl;
1503
1504         *pkp = NULL;
1505         if ((impl = sshkey_impl_from_key(k)) == NULL)
1506                 return SSH_ERR_KEY_TYPE_UNKNOWN;
1507         if ((n = sshkey_new(k->type)) == NULL) {
1508                 r = SSH_ERR_ALLOC_FAIL;
1509                 goto out;
1510         }
1511         if ((r = impl->funcs->copy_public(k, n)) != 0)
1512                 goto out;
1513         if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0)
1514                 goto out;
1515         /* success */
1516         *pkp = n;
1517         n = NULL;
1518         r = 0;
1519  out:
1520         sshkey_free(n);
1521         return r;
1522 }
1523
1524 int
1525 sshkey_is_shielded(struct sshkey *k)
1526 {
1527         return k != NULL && k->shielded_private != NULL;
1528 }
1529
1530 int
1531 sshkey_shield_private(struct sshkey *k)
1532 {
1533         struct sshbuf *prvbuf = NULL;
1534         u_char *prekey = NULL, *enc = NULL, keyiv[SSH_DIGEST_MAX_LENGTH];
1535         struct sshcipher_ctx *cctx = NULL;
1536         const struct sshcipher *cipher;
1537         size_t i, enclen = 0;
1538         struct sshkey *kswap = NULL, tmp;
1539         int r = SSH_ERR_INTERNAL_ERROR;
1540
1541 #ifdef DEBUG_PK
1542         fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
1543 #endif
1544         if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
1545                 r = SSH_ERR_INVALID_ARGUMENT;
1546                 goto out;
1547         }
1548         if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
1549             ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
1550                 r = SSH_ERR_INTERNAL_ERROR;
1551                 goto out;
1552         }
1553
1554         /* Prepare a random pre-key, and from it an ephemeral key */
1555         if ((prekey = malloc(SSHKEY_SHIELD_PREKEY_LEN)) == NULL) {
1556                 r = SSH_ERR_ALLOC_FAIL;
1557                 goto out;
1558         }
1559         arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1560         if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
1561             prekey, SSHKEY_SHIELD_PREKEY_LEN,
1562             keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
1563                 goto out;
1564 #ifdef DEBUG_PK
1565         fprintf(stderr, "%s: key+iv\n", __func__);
1566         sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
1567             stderr);
1568 #endif
1569         if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
1570             keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0)
1571                 goto out;
1572
1573         /* Serialise and encrypt the private key using the ephemeral key */
1574         if ((prvbuf = sshbuf_new()) == NULL) {
1575                 r = SSH_ERR_ALLOC_FAIL;
1576                 goto out;
1577         }
1578         if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0)
1579                 goto out;
1580         if ((r = sshkey_private_serialize_opt(k, prvbuf,
1581             SSHKEY_SERIALIZE_SHIELD)) != 0)
1582                 goto out;
1583         /* pad to cipher blocksize */
1584         i = 0;
1585         while (sshbuf_len(prvbuf) % cipher_blocksize(cipher)) {
1586                 if ((r = sshbuf_put_u8(prvbuf, ++i & 0xff)) != 0)
1587                         goto out;
1588         }
1589 #ifdef DEBUG_PK
1590         fprintf(stderr, "%s: serialised\n", __func__);
1591         sshbuf_dump(prvbuf, stderr);
1592 #endif
1593         /* encrypt */
1594         enclen = sshbuf_len(prvbuf);
1595         if ((enc = malloc(enclen)) == NULL) {
1596                 r = SSH_ERR_ALLOC_FAIL;
1597                 goto out;
1598         }
1599         if ((r = cipher_crypt(cctx, 0, enc,
1600             sshbuf_ptr(prvbuf), sshbuf_len(prvbuf), 0, 0)) != 0)
1601                 goto out;
1602 #ifdef DEBUG_PK
1603         fprintf(stderr, "%s: encrypted\n", __func__);
1604         sshbuf_dump_data(enc, enclen, stderr);
1605 #endif
1606
1607         /* Make a scrubbed, public-only copy of our private key argument */
1608         if ((r = sshkey_from_private(k, &kswap)) != 0)
1609                 goto out;
1610
1611         /* Swap the private key out (it will be destroyed below) */
1612         tmp = *kswap;
1613         *kswap = *k;
1614         *k = tmp;
1615
1616         /* Insert the shielded key into our argument */
1617         k->shielded_private = enc;
1618         k->shielded_len = enclen;
1619         k->shield_prekey = prekey;
1620         k->shield_prekey_len = SSHKEY_SHIELD_PREKEY_LEN;
1621         enc = prekey = NULL; /* transferred */
1622         enclen = 0;
1623
1624         /* preserve key fields that are required for correct operation */
1625         k->sk_flags = kswap->sk_flags;
1626
1627         /* success */
1628         r = 0;
1629
1630  out:
1631         /* XXX behaviour on error - invalidate original private key? */
1632         cipher_free(cctx);
1633         explicit_bzero(keyiv, sizeof(keyiv));
1634         explicit_bzero(&tmp, sizeof(tmp));
1635         freezero(enc, enclen);
1636         freezero(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1637         sshkey_free(kswap);
1638         sshbuf_free(prvbuf);
1639         return r;
1640 }
1641
1642 /* Check deterministic padding after private key */
1643 static int
1644 private2_check_padding(struct sshbuf *decrypted)
1645 {
1646         u_char pad;
1647         size_t i;
1648         int r;
1649
1650         i = 0;
1651         while (sshbuf_len(decrypted)) {
1652                 if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
1653                         goto out;
1654                 if (pad != (++i & 0xff)) {
1655                         r = SSH_ERR_INVALID_FORMAT;
1656                         goto out;
1657                 }
1658         }
1659         /* success */
1660         r = 0;
1661  out:
1662         explicit_bzero(&pad, sizeof(pad));
1663         explicit_bzero(&i, sizeof(i));
1664         return r;
1665 }
1666
1667 int
1668 sshkey_unshield_private(struct sshkey *k)
1669 {
1670         struct sshbuf *prvbuf = NULL;
1671         u_char *cp, keyiv[SSH_DIGEST_MAX_LENGTH];
1672         struct sshcipher_ctx *cctx = NULL;
1673         const struct sshcipher *cipher;
1674         struct sshkey *kswap = NULL, tmp;
1675         int r = SSH_ERR_INTERNAL_ERROR;
1676
1677 #ifdef DEBUG_PK
1678         fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
1679 #endif
1680         if (!sshkey_is_shielded(k))
1681                 return 0; /* nothing to do */
1682
1683         if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
1684                 r = SSH_ERR_INVALID_ARGUMENT;
1685                 goto out;
1686         }
1687         if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
1688             ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
1689                 r = SSH_ERR_INTERNAL_ERROR;
1690                 goto out;
1691         }
1692         /* check size of shielded key blob */
1693         if (k->shielded_len < cipher_blocksize(cipher) ||
1694             (k->shielded_len % cipher_blocksize(cipher)) != 0) {
1695                 r = SSH_ERR_INVALID_FORMAT;
1696                 goto out;
1697         }
1698
1699         /* Calculate the ephemeral key from the prekey */
1700         if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
1701             k->shield_prekey, k->shield_prekey_len,
1702             keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
1703                 goto out;
1704         if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
1705             keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0)
1706                 goto out;
1707 #ifdef DEBUG_PK
1708         fprintf(stderr, "%s: key+iv\n", __func__);
1709         sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
1710             stderr);
1711 #endif
1712
1713         /* Decrypt and parse the shielded private key using the ephemeral key */
1714         if ((prvbuf = sshbuf_new()) == NULL) {
1715                 r = SSH_ERR_ALLOC_FAIL;
1716                 goto out;
1717         }
1718         if ((r = sshbuf_reserve(prvbuf, k->shielded_len, &cp)) != 0)
1719                 goto out;
1720         /* decrypt */
1721 #ifdef DEBUG_PK
1722         fprintf(stderr, "%s: encrypted\n", __func__);
1723         sshbuf_dump_data(k->shielded_private, k->shielded_len, stderr);
1724 #endif
1725         if ((r = cipher_crypt(cctx, 0, cp,
1726             k->shielded_private, k->shielded_len, 0, 0)) != 0)
1727                 goto out;
1728 #ifdef DEBUG_PK
1729         fprintf(stderr, "%s: serialised\n", __func__);
1730         sshbuf_dump(prvbuf, stderr);
1731 #endif
1732         /* Parse private key */
1733         if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0)
1734                 goto out;
1735
1736         if ((r = private2_check_padding(prvbuf)) != 0)
1737                 goto out;
1738
1739         /* Swap the parsed key back into place */
1740         tmp = *kswap;
1741         *kswap = *k;
1742         *k = tmp;
1743
1744         /* success */
1745         r = 0;
1746
1747  out:
1748         cipher_free(cctx);
1749         explicit_bzero(keyiv, sizeof(keyiv));
1750         explicit_bzero(&tmp, sizeof(tmp));
1751         sshkey_free(kswap);
1752         sshbuf_free(prvbuf);
1753         return r;
1754 }
1755
1756 static int
1757 cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1758 {
1759         struct sshbuf *principals = NULL, *crit = NULL;
1760         struct sshbuf *exts = NULL, *ca = NULL;
1761         u_char *sig = NULL;
1762         size_t signed_len = 0, slen = 0, kidlen = 0;
1763         int ret = SSH_ERR_INTERNAL_ERROR;
1764
1765         /* Copy the entire key blob for verification and later serialisation */
1766         if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
1767                 return ret;
1768
1769         /* Parse body of certificate up to signature */
1770         if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 ||
1771             (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
1772             (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
1773             (ret = sshbuf_froms(b, &principals)) != 0 ||
1774             (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
1775             (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
1776             (ret = sshbuf_froms(b, &crit)) != 0 ||
1777             (ret = sshbuf_froms(b, &exts)) != 0 ||
1778             (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
1779             (ret = sshbuf_froms(b, &ca)) != 0) {
1780                 /* XXX debug print error for ret */
1781                 ret = SSH_ERR_INVALID_FORMAT;
1782                 goto out;
1783         }
1784
1785         /* Signature is left in the buffer so we can calculate this length */
1786         signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);
1787
1788         if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {
1789                 ret = SSH_ERR_INVALID_FORMAT;
1790                 goto out;
1791         }
1792
1793         if (key->cert->type != SSH2_CERT_TYPE_USER &&
1794             key->cert->type != SSH2_CERT_TYPE_HOST) {
1795                 ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;
1796                 goto out;
1797         }
1798
1799         /* Parse principals section */
1800         while (sshbuf_len(principals) > 0) {
1801                 char *principal = NULL;
1802                 char **oprincipals = NULL;
1803
1804                 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
1805                         ret = SSH_ERR_INVALID_FORMAT;
1806                         goto out;
1807                 }
1808                 if ((ret = sshbuf_get_cstring(principals, &principal,
1809                     NULL)) != 0) {
1810                         ret = SSH_ERR_INVALID_FORMAT;
1811                         goto out;
1812                 }
1813                 oprincipals = key->cert->principals;
1814                 key->cert->principals = recallocarray(key->cert->principals,
1815                     key->cert->nprincipals, key->cert->nprincipals + 1,
1816                     sizeof(*key->cert->principals));
1817                 if (key->cert->principals == NULL) {
1818                         free(principal);
1819                         key->cert->principals = oprincipals;
1820                         ret = SSH_ERR_ALLOC_FAIL;
1821                         goto out;
1822                 }
1823                 key->cert->principals[key->cert->nprincipals++] = principal;
1824         }
1825
1826         /*
1827          * Stash a copies of the critical options and extensions sections
1828          * for later use.
1829          */
1830         if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 ||
1831             (exts != NULL &&
1832             (ret = sshbuf_putb(key->cert->extensions, exts)) != 0))
1833                 goto out;
1834
1835         /*
1836          * Validate critical options and extensions sections format.
1837          */
1838         while (sshbuf_len(crit) != 0) {
1839                 if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||
1840                     (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) {
1841                         sshbuf_reset(key->cert->critical);
1842                         ret = SSH_ERR_INVALID_FORMAT;
1843                         goto out;
1844                 }
1845         }
1846         while (exts != NULL && sshbuf_len(exts) != 0) {
1847                 if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 ||
1848                     (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) {
1849                         sshbuf_reset(key->cert->extensions);
1850                         ret = SSH_ERR_INVALID_FORMAT;
1851                         goto out;
1852                 }
1853         }
1854
1855         /* Parse CA key and check signature */
1856         if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {
1857                 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1858                 goto out;
1859         }
1860         if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {
1861                 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1862                 goto out;
1863         }
1864         if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
1865             sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0)
1866                 goto out;
1867         if ((ret = sshkey_get_sigtype(sig, slen,
1868             &key->cert->signature_type)) != 0)
1869                 goto out;
1870
1871         /* Success */
1872         ret = 0;
1873  out:
1874         sshbuf_free(ca);
1875         sshbuf_free(crit);
1876         sshbuf_free(exts);
1877         sshbuf_free(principals);
1878         free(sig);
1879         return ret;
1880 }
1881
1882 int
1883 sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key)
1884 {
1885         /* Parse additional security-key application string */
1886         if (sshbuf_get_cstring(b, &key->sk_application, NULL) != 0)
1887                 return SSH_ERR_INVALID_FORMAT;
1888         return 0;
1889 }
1890
1891 static int
1892 sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1893     int allow_cert)
1894 {
1895         int type, ret = SSH_ERR_INTERNAL_ERROR;
1896         char *ktype = NULL;
1897         struct sshkey *key = NULL;
1898         struct sshbuf *copy;
1899         const struct sshkey_impl *impl;
1900
1901 #ifdef DEBUG_PK /* XXX */
1902         sshbuf_dump(b, stderr);
1903 #endif
1904         if (keyp != NULL)
1905                 *keyp = NULL;
1906         if ((copy = sshbuf_fromb(b)) == NULL) {
1907                 ret = SSH_ERR_ALLOC_FAIL;
1908                 goto out;
1909         }
1910         if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
1911                 ret = SSH_ERR_INVALID_FORMAT;
1912                 goto out;
1913         }
1914
1915         type = sshkey_type_from_name(ktype);
1916         if (!allow_cert && sshkey_type_is_cert(type)) {
1917                 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1918                 goto out;
1919         }
1920         if ((impl = sshkey_impl_from_type(type)) == NULL) {
1921                 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
1922                 goto out;
1923         }
1924         if ((key = sshkey_new(type)) == NULL) {
1925                 ret = SSH_ERR_ALLOC_FAIL;
1926                 goto out;
1927         }
1928         if (sshkey_type_is_cert(type)) {
1929                 /* Skip nonce that preceeds all certificates */
1930                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1931                         ret = SSH_ERR_INVALID_FORMAT;
1932                         goto out;
1933                 }
1934         }
1935         if ((ret = impl->funcs->deserialize_public(ktype, b, key)) != 0)
1936                 goto out;
1937
1938         /* Parse certificate potion */
1939         if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
1940                 goto out;
1941
1942         if (key != NULL && sshbuf_len(b) != 0) {
1943                 ret = SSH_ERR_INVALID_FORMAT;
1944                 goto out;
1945         }
1946         ret = 0;
1947         if (keyp != NULL) {
1948                 *keyp = key;
1949                 key = NULL;
1950         }
1951  out:
1952         sshbuf_free(copy);
1953         sshkey_free(key);
1954         free(ktype);
1955         return ret;
1956 }
1957
1958 int
1959 sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
1960 {
1961         struct sshbuf *b;
1962         int r;
1963
1964         if ((b = sshbuf_from(blob, blen)) == NULL)
1965                 return SSH_ERR_ALLOC_FAIL;
1966         r = sshkey_from_blob_internal(b, keyp, 1);
1967         sshbuf_free(b);
1968         return r;
1969 }
1970
1971 int
1972 sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
1973 {
1974         return sshkey_from_blob_internal(b, keyp, 1);
1975 }
1976
1977 int
1978 sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
1979 {
1980         struct sshbuf *b;
1981         int r;
1982
1983         if ((r = sshbuf_froms(buf, &b)) != 0)
1984                 return r;
1985         r = sshkey_from_blob_internal(b, keyp, 1);
1986         sshbuf_free(b);
1987         return r;
1988 }
1989
1990 int
1991 sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
1992 {
1993         int r;
1994         struct sshbuf *b = NULL;
1995         char *sigtype = NULL;
1996
1997         if (sigtypep != NULL)
1998                 *sigtypep = NULL;
1999         if ((b = sshbuf_from(sig, siglen)) == NULL)
2000                 return SSH_ERR_ALLOC_FAIL;
2001         if ((r = sshbuf_get_cstring(b, &sigtype, NULL)) != 0)
2002                 goto out;
2003         /* success */
2004         if (sigtypep != NULL) {
2005                 *sigtypep = sigtype;
2006                 sigtype = NULL;
2007         }
2008         r = 0;
2009  out:
2010         free(sigtype);
2011         sshbuf_free(b);
2012         return r;
2013 }
2014
2015 /*
2016  *
2017  * Checks whether a certificate's signature type is allowed.
2018  * Returns 0 (success) if the certificate signature type appears in the
2019  * "allowed" pattern-list, or the key is not a certificate to begin with.
2020  * Otherwise returns a ssherr.h code.
2021  */
2022 int
2023 sshkey_check_cert_sigtype(const struct sshkey *key, const char *allowed)
2024 {
2025         if (key == NULL || allowed == NULL)
2026                 return SSH_ERR_INVALID_ARGUMENT;
2027         if (!sshkey_type_is_cert(key->type))
2028                 return 0;
2029         if (key->cert == NULL || key->cert->signature_type == NULL)
2030                 return SSH_ERR_INVALID_ARGUMENT;
2031         if (match_pattern_list(key->cert->signature_type, allowed, 0) != 1)
2032                 return SSH_ERR_SIGN_ALG_UNSUPPORTED;
2033         return 0;
2034 }
2035
2036 /*
2037  * Returns the expected signature algorithm for a given public key algorithm.
2038  */
2039 const char *
2040 sshkey_sigalg_by_name(const char *name)
2041 {
2042         const struct sshkey_impl *impl;
2043         int i;
2044
2045         for (i = 0; keyimpls[i] != NULL; i++) {
2046                 impl = keyimpls[i];
2047                 if (strcmp(impl->name, name) != 0)
2048                         continue;
2049                 if (impl->sigalg != NULL)
2050                         return impl->sigalg;
2051                 if (!impl->cert)
2052                         return impl->name;
2053                 return sshkey_ssh_name_from_type_nid(
2054                     sshkey_type_plain(impl->type), impl->nid);
2055         }
2056         return NULL;
2057 }
2058
2059 /*
2060  * Verifies that the signature algorithm appearing inside the signature blob
2061  * matches that which was requested.
2062  */
2063 int
2064 sshkey_check_sigtype(const u_char *sig, size_t siglen,
2065     const char *requested_alg)
2066 {
2067         const char *expected_alg;
2068         char *sigtype = NULL;
2069         int r;
2070
2071         if (requested_alg == NULL)
2072                 return 0;
2073         if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL)
2074                 return SSH_ERR_INVALID_ARGUMENT;
2075         if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
2076                 return r;
2077         r = strcmp(expected_alg, sigtype) == 0;
2078         free(sigtype);
2079         return r ? 0 : SSH_ERR_SIGN_ALG_UNSUPPORTED;
2080 }
2081
2082 int
2083 sshkey_sign(struct sshkey *key,
2084     u_char **sigp, size_t *lenp,
2085     const u_char *data, size_t datalen,
2086     const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
2087 {
2088         int was_shielded = sshkey_is_shielded(key);
2089         int r2, r = SSH_ERR_INTERNAL_ERROR;
2090         const struct sshkey_impl *impl;
2091
2092         if (sigp != NULL)
2093                 *sigp = NULL;
2094         if (lenp != NULL)
2095                 *lenp = 0;
2096         if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2097                 return SSH_ERR_INVALID_ARGUMENT;
2098         if ((impl = sshkey_impl_from_key(key)) == NULL)
2099                 return SSH_ERR_KEY_TYPE_UNKNOWN;
2100         if ((r = sshkey_unshield_private(key)) != 0)
2101                 return r;
2102         if (sshkey_is_sk(key)) {
2103                 r = sshsk_sign(sk_provider, key, sigp, lenp, data,
2104                     datalen, compat, sk_pin);
2105         } else {
2106                 if (impl->funcs->sign == NULL)
2107                         r = SSH_ERR_SIGN_ALG_UNSUPPORTED;
2108                 else {
2109                         r = impl->funcs->sign(key, sigp, lenp, data, datalen,
2110                             alg, sk_provider, sk_pin, compat);
2111                  }
2112         }
2113         if (was_shielded && (r2 = sshkey_shield_private(key)) != 0)
2114                 return r2;
2115         return r;
2116 }
2117
2118 /*
2119  * ssh_key_verify returns 0 for a correct signature  and < 0 on error.
2120  * If "alg" specified, then the signature must use that algorithm.
2121  */
2122 int
2123 sshkey_verify(const struct sshkey *key,
2124     const u_char *sig, size_t siglen,
2125     const u_char *data, size_t dlen, const char *alg, u_int compat,
2126     struct sshkey_sig_details **detailsp)
2127 {
2128         const struct sshkey_impl *impl;
2129
2130         if (detailsp != NULL)
2131                 *detailsp = NULL;
2132         if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2133                 return SSH_ERR_INVALID_ARGUMENT;
2134         if ((impl = sshkey_impl_from_key(key)) == NULL)
2135                 return SSH_ERR_KEY_TYPE_UNKNOWN;
2136         return impl->funcs->verify(key, sig, siglen, data, dlen,
2137             alg, compat, detailsp);
2138 }
2139
2140 /* Convert a plain key to their _CERT equivalent */
2141 int
2142 sshkey_to_certified(struct sshkey *k)
2143 {
2144         int newtype;
2145
2146         if ((newtype = sshkey_type_certified(k->type)) == -1)
2147                 return SSH_ERR_INVALID_ARGUMENT;
2148         if ((k->cert = cert_new()) == NULL)
2149                 return SSH_ERR_ALLOC_FAIL;
2150         k->type = newtype;
2151         return 0;
2152 }
2153
2154 /* Convert a certificate to its raw key equivalent */
2155 int
2156 sshkey_drop_cert(struct sshkey *k)
2157 {
2158         if (!sshkey_type_is_cert(k->type))
2159                 return SSH_ERR_KEY_TYPE_UNKNOWN;
2160         cert_free(k->cert);
2161         k->cert = NULL;
2162         k->type = sshkey_type_plain(k->type);
2163         return 0;
2164 }
2165
2166 /* Sign a certified key, (re-)generating the signed certblob. */
2167 int
2168 sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2169     const char *sk_provider, const char *sk_pin,
2170     sshkey_certify_signer *signer, void *signer_ctx)
2171 {
2172         const struct sshkey_impl *impl;
2173         struct sshbuf *principals = NULL;
2174         u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2175         size_t i, ca_len, sig_len;
2176         int ret = SSH_ERR_INTERNAL_ERROR;
2177         struct sshbuf *cert = NULL;
2178         char *sigtype = NULL;
2179
2180         if (k == NULL || k->cert == NULL ||
2181             k->cert->certblob == NULL || ca == NULL)
2182                 return SSH_ERR_INVALID_ARGUMENT;
2183         if (!sshkey_is_cert(k))
2184                 return SSH_ERR_KEY_TYPE_UNKNOWN;
2185         if (!sshkey_type_is_valid_ca(ca->type))
2186                 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2187         if ((impl = sshkey_impl_from_key(k)) == NULL)
2188                 return SSH_ERR_INTERNAL_ERROR;
2189
2190         /*
2191          * If no alg specified as argument but a signature_type was set,
2192          * then prefer that. If both were specified, then they must match.
2193          */
2194         if (alg == NULL)
2195                 alg = k->cert->signature_type;
2196         else if (k->cert->signature_type != NULL &&
2197             strcmp(alg, k->cert->signature_type) != 0)
2198                 return SSH_ERR_INVALID_ARGUMENT;
2199
2200         /*
2201          * If no signing algorithm or signature_type was specified and we're
2202          * using a RSA key, then default to a good signature algorithm.
2203          */
2204         if (alg == NULL && ca->type == KEY_RSA)
2205                 alg = "rsa-sha2-512";
2206
2207         if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2208                 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2209
2210         cert = k->cert->certblob; /* for readability */
2211         sshbuf_reset(cert);
2212         if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)
2213                 goto out;
2214
2215         /* -v01 certs put nonce first */
2216         arc4random_buf(&nonce, sizeof(nonce));
2217         if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2218                 goto out;
2219
2220         /* Public key next */
2221         if ((ret = impl->funcs->serialize_public(k, cert,
2222             SSHKEY_SERIALIZE_DEFAULT)) != 0)
2223                 goto out;
2224
2225         /* Then remaining cert fields */
2226         if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 ||
2227             (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
2228             (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
2229                 goto out;
2230
2231         if ((principals = sshbuf_new()) == NULL) {
2232                 ret = SSH_ERR_ALLOC_FAIL;
2233                 goto out;
2234         }
2235         for (i = 0; i < k->cert->nprincipals; i++) {
2236                 if ((ret = sshbuf_put_cstring(principals,
2237                     k->cert->principals[i])) != 0)
2238                         goto out;
2239         }
2240         if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
2241             (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
2242             (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
2243             (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 ||
2244             (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 ||
2245             (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2246             (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2247                 goto out;
2248
2249         /* Sign the whole mess */
2250         if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2251             sshbuf_len(cert), alg, sk_provider, sk_pin, 0, signer_ctx)) != 0)
2252                 goto out;
2253         /* Check and update signature_type against what was actually used */
2254         if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
2255                 goto out;
2256         if (alg != NULL && strcmp(alg, sigtype) != 0) {
2257                 ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
2258                 goto out;
2259         }
2260         if (k->cert->signature_type == NULL) {
2261                 k->cert->signature_type = sigtype;
2262                 sigtype = NULL;
2263         }
2264         /* Append signature and we are done */
2265         if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
2266                 goto out;
2267         ret = 0;
2268  out:
2269         if (ret != 0)
2270                 sshbuf_reset(cert);
2271         free(sig_blob);
2272         free(ca_blob);
2273         free(sigtype);
2274         sshbuf_free(principals);
2275         return ret;
2276 }
2277
2278 static int
2279 default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp,
2280     const u_char *data, size_t datalen,
2281     const char *alg, const char *sk_provider, const char *sk_pin,
2282     u_int compat, void *ctx)
2283 {
2284         if (ctx != NULL)
2285                 return SSH_ERR_INVALID_ARGUMENT;
2286         return sshkey_sign(key, sigp, lenp, data, datalen, alg,
2287             sk_provider, sk_pin, compat);
2288 }
2289
2290 int
2291 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg,
2292     const char *sk_provider, const char *sk_pin)
2293 {
2294         return sshkey_certify_custom(k, ca, alg, sk_provider, sk_pin,
2295             default_key_sign, NULL);
2296 }
2297
2298 int
2299 sshkey_cert_check_authority(const struct sshkey *k,
2300     int want_host, int require_principal, int wildcard_pattern,
2301     uint64_t verify_time, const char *name, const char **reason)
2302 {
2303         u_int i, principal_matches;
2304
2305         if (reason == NULL)
2306                 return SSH_ERR_INVALID_ARGUMENT;
2307         if (!sshkey_is_cert(k)) {
2308                 *reason = "Key is not a certificate";
2309                 return SSH_ERR_KEY_CERT_INVALID;
2310         }
2311         if (want_host) {
2312                 if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2313                         *reason = "Certificate invalid: not a host certificate";
2314                         return SSH_ERR_KEY_CERT_INVALID;
2315                 }
2316         } else {
2317                 if (k->cert->type != SSH2_CERT_TYPE_USER) {
2318                         *reason = "Certificate invalid: not a user certificate";
2319                         return SSH_ERR_KEY_CERT_INVALID;
2320                 }
2321         }
2322         if (verify_time < k->cert->valid_after) {
2323                 *reason = "Certificate invalid: not yet valid";
2324                 return SSH_ERR_KEY_CERT_INVALID;
2325         }
2326         if (verify_time >= k->cert->valid_before) {
2327                 *reason = "Certificate invalid: expired";
2328                 return SSH_ERR_KEY_CERT_INVALID;
2329         }
2330         if (k->cert->nprincipals == 0) {
2331                 if (require_principal) {
2332                         *reason = "Certificate lacks principal list";
2333                         return SSH_ERR_KEY_CERT_INVALID;
2334                 }
2335         } else if (name != NULL) {
2336                 principal_matches = 0;
2337                 for (i = 0; i < k->cert->nprincipals; i++) {
2338                         if (wildcard_pattern) {
2339                                 if (match_pattern(k->cert->principals[i],
2340                                     name)) {
2341                                         principal_matches = 1;
2342                                         break;
2343                                 }
2344                         } else if (strcmp(name, k->cert->principals[i]) == 0) {
2345                                 principal_matches = 1;
2346                                 break;
2347                         }
2348                 }
2349                 if (!principal_matches) {
2350                         *reason = "Certificate invalid: name is not a listed "
2351                             "principal";
2352                         return SSH_ERR_KEY_CERT_INVALID;
2353                 }
2354         }
2355         return 0;
2356 }
2357
2358 int
2359 sshkey_cert_check_authority_now(const struct sshkey *k,
2360     int want_host, int require_principal, int wildcard_pattern,
2361     const char *name, const char **reason)
2362 {
2363         time_t now;
2364
2365         if ((now = time(NULL)) < 0) {
2366                 /* yikes - system clock before epoch! */
2367                 *reason = "Certificate invalid: not yet valid";
2368                 return SSH_ERR_KEY_CERT_INVALID;
2369         }
2370         return sshkey_cert_check_authority(k, want_host, require_principal,
2371             wildcard_pattern, (uint64_t)now, name, reason);
2372 }
2373
2374 int
2375 sshkey_cert_check_host(const struct sshkey *key, const char *host,
2376     int wildcard_principals, const char *ca_sign_algorithms,
2377     const char **reason)
2378 {
2379         int r;
2380
2381         if ((r = sshkey_cert_check_authority_now(key, 1, 0, wildcard_principals,
2382             host, reason)) != 0)
2383                 return r;
2384         if (sshbuf_len(key->cert->critical) != 0) {
2385                 *reason = "Certificate contains unsupported critical options";
2386                 return SSH_ERR_KEY_CERT_INVALID;
2387         }
2388         if (ca_sign_algorithms != NULL &&
2389             (r = sshkey_check_cert_sigtype(key, ca_sign_algorithms)) != 0) {
2390                 *reason = "Certificate signed with disallowed algorithm";
2391                 return SSH_ERR_KEY_CERT_INVALID;
2392         }
2393         return 0;
2394 }
2395
2396 size_t
2397 sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
2398 {
2399         char from[32], to[32], ret[128];
2400
2401         *from = *to = '\0';
2402         if (cert->valid_after == 0 &&
2403             cert->valid_before == 0xffffffffffffffffULL)
2404                 return strlcpy(s, "forever", l);
2405
2406         if (cert->valid_after != 0)
2407                 format_absolute_time(cert->valid_after, from, sizeof(from));
2408         if (cert->valid_before != 0xffffffffffffffffULL)
2409                 format_absolute_time(cert->valid_before, to, sizeof(to));
2410
2411         if (cert->valid_after == 0)
2412                 snprintf(ret, sizeof(ret), "before %s", to);
2413         else if (cert->valid_before == 0xffffffffffffffffULL)
2414                 snprintf(ret, sizeof(ret), "after %s", from);
2415         else
2416                 snprintf(ret, sizeof(ret), "from %s to %s", from, to);
2417
2418         return strlcpy(s, ret, l);
2419 }
2420
2421 /* Common serialization for FIDO private keys */
2422 int
2423 sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b)
2424 {
2425         int r;
2426
2427         if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
2428             (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
2429             (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
2430             (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
2431                 return r;
2432
2433         return 0;
2434 }
2435
2436 int
2437 sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
2438     enum sshkey_serialize_rep opts)
2439 {
2440         int r = SSH_ERR_INTERNAL_ERROR;
2441         int was_shielded = sshkey_is_shielded(key);
2442         struct sshbuf *b = NULL;
2443         const struct sshkey_impl *impl;
2444
2445         if ((impl = sshkey_impl_from_key(key)) == NULL)
2446                 return SSH_ERR_INTERNAL_ERROR;
2447         if ((r = sshkey_unshield_private(key)) != 0)
2448                 return r;
2449         if ((b = sshbuf_new()) == NULL)
2450                 return SSH_ERR_ALLOC_FAIL;
2451         if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2452                 goto out;
2453         if (sshkey_is_cert(key)) {
2454                 if (key->cert == NULL ||
2455                     sshbuf_len(key->cert->certblob) == 0) {
2456                         r = SSH_ERR_INVALID_ARGUMENT;
2457                         goto out;
2458                 }
2459                 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0)
2460                         goto out;
2461         }
2462         if ((r = impl->funcs->serialize_private(key, b, opts)) != 0)
2463                 goto out;
2464
2465         /*
2466          * success (but we still need to append the output to buf after
2467          * possibly re-shielding the private key)
2468          */
2469         r = 0;
2470  out:
2471         if (was_shielded)
2472                 r = sshkey_shield_private(key);
2473         if (r == 0)
2474                 r = sshbuf_putb(buf, b);
2475         sshbuf_free(b);
2476
2477         return r;
2478 }
2479
2480 int
2481 sshkey_private_serialize(struct sshkey *key, struct sshbuf *b)
2482 {
2483         return sshkey_private_serialize_opt(key, b,
2484             SSHKEY_SERIALIZE_DEFAULT);
2485 }
2486
2487 /* Shared deserialization of FIDO private key components */
2488 int
2489 sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k)
2490 {
2491         int r;
2492
2493         if ((k->sk_key_handle = sshbuf_new()) == NULL ||
2494             (k->sk_reserved = sshbuf_new()) == NULL)
2495                 return SSH_ERR_ALLOC_FAIL;
2496         if ((r = sshbuf_get_cstring(buf, &k->sk_application, NULL)) != 0 ||
2497             (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
2498             (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
2499             (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
2500                 return r;
2501
2502         return 0;
2503 }
2504
2505 int
2506 sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2507 {
2508         const struct sshkey_impl *impl;
2509         char *tname = NULL;
2510         char *expect_sk_application = NULL;
2511         u_char *expect_ed25519_pk = NULL;
2512         struct sshkey *k = NULL;
2513         int type, r = SSH_ERR_INTERNAL_ERROR;
2514
2515         if (kp != NULL)
2516                 *kp = NULL;
2517         if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
2518                 goto out;
2519         type = sshkey_type_from_name(tname);
2520         if (sshkey_type_is_cert(type)) {
2521                 /*
2522                  * Certificate key private keys begin with the certificate
2523                  * itself. Make sure this matches the type of the enclosing
2524                  * private key.
2525                  */
2526                 if ((r = sshkey_froms(buf, &k)) != 0)
2527                         goto out;
2528                 if (k->type != type) {
2529                         r = SSH_ERR_KEY_CERT_MISMATCH;
2530                         goto out;
2531                 }
2532                 /* For ECDSA keys, the group must match too */
2533                 if (k->type == KEY_ECDSA &&
2534                     k->ecdsa_nid != sshkey_ecdsa_nid_from_name(tname)) {
2535                         r = SSH_ERR_KEY_CERT_MISMATCH;
2536                         goto out;
2537                 }
2538                 /*
2539                  * Several fields are redundant between certificate and
2540                  * private key body, we require these to match.
2541                  */
2542                 expect_sk_application = k->sk_application;
2543                 expect_ed25519_pk = k->ed25519_pk;
2544                 k->sk_application = NULL;
2545                 k->ed25519_pk = NULL;
2546                 /* XXX xmss too or refactor */
2547         } else {
2548                 if ((k = sshkey_new(type)) == NULL) {
2549                         r = SSH_ERR_ALLOC_FAIL;
2550                         goto out;
2551                 }
2552         }
2553         if ((impl = sshkey_impl_from_type(type)) == NULL) {
2554                 r = SSH_ERR_INTERNAL_ERROR;
2555                 goto out;
2556         }
2557         if ((r = impl->funcs->deserialize_private(tname, buf, k)) != 0)
2558                 goto out;
2559
2560         /* XXX xmss too or refactor */
2561         if ((expect_sk_application != NULL && (k->sk_application == NULL ||
2562             strcmp(expect_sk_application, k->sk_application) != 0)) ||
2563             (expect_ed25519_pk != NULL && (k->ed25519_pk == NULL ||
2564             memcmp(expect_ed25519_pk, k->ed25519_pk, ED25519_PK_SZ) != 0))) {
2565                 r = SSH_ERR_KEY_CERT_MISMATCH;
2566                 goto out;
2567         }
2568         /* success */
2569         r = 0;
2570         if (kp != NULL) {
2571                 *kp = k;
2572                 k = NULL;
2573         }
2574  out:
2575         free(tname);
2576         sshkey_free(k);
2577         free(expect_sk_application);
2578         free(expect_ed25519_pk);
2579         return r;
2580 }
2581
2582 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2583 int
2584 sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2585 {
2586         EC_POINT *nq = NULL;
2587         BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL;
2588         int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2589
2590         /*
2591          * NB. This assumes OpenSSL has already verified that the public
2592          * point lies on the curve. This is done by EC_POINT_oct2point()
2593          * implicitly calling EC_POINT_is_on_curve(). If this code is ever
2594          * reachable with public points not unmarshalled using
2595          * EC_POINT_oct2point then the caller will need to explicitly check.
2596          */
2597
2598         /*
2599          * We shouldn't ever hit this case because bignum_get_ecpoint()
2600          * refuses to load GF2m points.
2601          */
2602         if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2603             NID_X9_62_prime_field)
2604                 goto out;
2605
2606         /* Q != infinity */
2607         if (EC_POINT_is_at_infinity(group, public))
2608                 goto out;
2609
2610         if ((x = BN_new()) == NULL ||
2611             (y = BN_new()) == NULL ||
2612             (order = BN_new()) == NULL ||
2613             (tmp = BN_new()) == NULL) {
2614                 ret = SSH_ERR_ALLOC_FAIL;
2615                 goto out;
2616         }
2617
2618         /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2619         if (EC_GROUP_get_order(group, order, NULL) != 1 ||
2620             EC_POINT_get_affine_coordinates_GFp(group, public,
2621             x, y, NULL) != 1) {
2622                 ret = SSH_ERR_LIBCRYPTO_ERROR;
2623                 goto out;
2624         }
2625         if (BN_num_bits(x) <= BN_num_bits(order) / 2 ||
2626             BN_num_bits(y) <= BN_num_bits(order) / 2)
2627                 goto out;
2628
2629         /* nQ == infinity (n == order of subgroup) */
2630         if ((nq = EC_POINT_new(group)) == NULL) {
2631                 ret = SSH_ERR_ALLOC_FAIL;
2632                 goto out;
2633         }
2634         if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) {
2635                 ret = SSH_ERR_LIBCRYPTO_ERROR;
2636                 goto out;
2637         }
2638         if (EC_POINT_is_at_infinity(group, nq) != 1)
2639                 goto out;
2640
2641         /* x < order - 1, y < order - 1 */
2642         if (!BN_sub(tmp, order, BN_value_one())) {
2643                 ret = SSH_ERR_LIBCRYPTO_ERROR;
2644                 goto out;
2645         }
2646         if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)
2647                 goto out;
2648         ret = 0;
2649  out:
2650         BN_clear_free(x);
2651         BN_clear_free(y);
2652         BN_clear_free(order);
2653         BN_clear_free(tmp);
2654         EC_POINT_free(nq);
2655         return ret;
2656 }
2657
2658 int
2659 sshkey_ec_validate_private(const EC_KEY *key)
2660 {
2661         BIGNUM *order = NULL, *tmp = NULL;
2662         int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2663
2664         if ((order = BN_new()) == NULL || (tmp = BN_new()) == NULL) {
2665                 ret = SSH_ERR_ALLOC_FAIL;
2666                 goto out;
2667         }
2668
2669         /* log2(private) > log2(order)/2 */
2670         if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) != 1) {
2671                 ret = SSH_ERR_LIBCRYPTO_ERROR;
2672                 goto out;
2673         }
2674         if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2675             BN_num_bits(order) / 2)
2676                 goto out;
2677
2678         /* private < order - 1 */
2679         if (!BN_sub(tmp, order, BN_value_one())) {
2680                 ret = SSH_ERR_LIBCRYPTO_ERROR;
2681                 goto out;
2682         }
2683         if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)
2684                 goto out;
2685         ret = 0;
2686  out:
2687         BN_clear_free(order);
2688         BN_clear_free(tmp);
2689         return ret;
2690 }
2691
2692 void
2693 sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
2694 {
2695         BIGNUM *x = NULL, *y = NULL;
2696
2697         if (point == NULL) {
2698                 fputs("point=(NULL)\n", stderr);
2699                 return;
2700         }
2701         if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) {
2702                 fprintf(stderr, "%s: BN_new failed\n", __func__);
2703                 goto out;
2704         }
2705         if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2706             NID_X9_62_prime_field) {
2707                 fprintf(stderr, "%s: group is not a prime field\n", __func__);
2708                 goto out;
2709         }
2710         if (EC_POINT_get_affine_coordinates_GFp(group, point,
2711             x, y, NULL) != 1) {
2712                 fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
2713                     __func__);
2714                 goto out;
2715         }
2716         fputs("x=", stderr);
2717         BN_print_fp(stderr, x);
2718         fputs("\ny=", stderr);
2719         BN_print_fp(stderr, y);
2720         fputs("\n", stderr);
2721  out:
2722         BN_clear_free(x);
2723         BN_clear_free(y);
2724 }
2725
2726 void
2727 sshkey_dump_ec_key(const EC_KEY *key)
2728 {
2729         const BIGNUM *exponent;
2730
2731         sshkey_dump_ec_point(EC_KEY_get0_group(key),
2732             EC_KEY_get0_public_key(key));
2733         fputs("exponent=", stderr);
2734         if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
2735                 fputs("(NULL)", stderr);
2736         else
2737                 BN_print_fp(stderr, EC_KEY_get0_private_key(key));
2738         fputs("\n", stderr);
2739 }
2740 #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2741
2742 static int
2743 sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob,
2744     const char *passphrase, const char *comment, const char *ciphername,
2745     int rounds)
2746 {
2747         u_char *cp, *key = NULL, *pubkeyblob = NULL;
2748         u_char salt[SALT_LEN];
2749         size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
2750         u_int check;
2751         int r = SSH_ERR_INTERNAL_ERROR;
2752         struct sshcipher_ctx *ciphercontext = NULL;
2753         const struct sshcipher *cipher;
2754         const char *kdfname = KDFNAME;
2755         struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;
2756
2757         if (rounds <= 0)
2758                 rounds = DEFAULT_ROUNDS;
2759         if (passphrase == NULL || !strlen(passphrase)) {
2760                 ciphername = "none";
2761                 kdfname = "none";
2762         } else if (ciphername == NULL)
2763                 ciphername = DEFAULT_CIPHERNAME;
2764         if ((cipher = cipher_by_name(ciphername)) == NULL) {
2765                 r = SSH_ERR_INVALID_ARGUMENT;
2766                 goto out;
2767         }
2768
2769         if ((kdf = sshbuf_new()) == NULL ||
2770             (encoded = sshbuf_new()) == NULL ||
2771             (encrypted = sshbuf_new()) == NULL) {
2772                 r = SSH_ERR_ALLOC_FAIL;
2773                 goto out;
2774         }
2775         blocksize = cipher_blocksize(cipher);
2776         keylen = cipher_keylen(cipher);
2777         ivlen = cipher_ivlen(cipher);
2778         authlen = cipher_authlen(cipher);
2779         if ((key = calloc(1, keylen + ivlen)) == NULL) {
2780                 r = SSH_ERR_ALLOC_FAIL;
2781                 goto out;
2782         }
2783         if (strcmp(kdfname, "bcrypt") == 0) {
2784                 arc4random_buf(salt, SALT_LEN);
2785                 if (bcrypt_pbkdf(passphrase, strlen(passphrase),
2786                     salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {
2787                         r = SSH_ERR_INVALID_ARGUMENT;
2788                         goto out;
2789                 }
2790                 if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||
2791                     (r = sshbuf_put_u32(kdf, rounds)) != 0)
2792                         goto out;
2793         } else if (strcmp(kdfname, "none") != 0) {
2794                 /* Unsupported KDF type */
2795                 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
2796                 goto out;
2797         }
2798         if ((r = cipher_init(&ciphercontext, cipher, key, keylen,
2799             key + keylen, ivlen, 1)) != 0)
2800                 goto out;
2801
2802         if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||
2803             (r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||
2804             (r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||
2805             (r = sshbuf_put_stringb(encoded, kdf)) != 0 ||
2806             (r = sshbuf_put_u32(encoded, 1)) != 0 ||    /* number of keys */
2807             (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||
2808             (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)
2809                 goto out;
2810
2811         /* set up the buffer that will be encrypted */
2812
2813         /* Random check bytes */
2814         check = arc4random();
2815         if ((r = sshbuf_put_u32(encrypted, check)) != 0 ||
2816             (r = sshbuf_put_u32(encrypted, check)) != 0)
2817                 goto out;
2818
2819         /* append private key and comment*/
2820         if ((r = sshkey_private_serialize_opt(prv, encrypted,
2821             SSHKEY_SERIALIZE_FULL)) != 0 ||
2822             (r = sshbuf_put_cstring(encrypted, comment)) != 0)
2823                 goto out;
2824
2825         /* padding */
2826         i = 0;
2827         while (sshbuf_len(encrypted) % blocksize) {
2828                 if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)
2829                         goto out;
2830         }
2831
2832         /* length in destination buffer */
2833         if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)
2834                 goto out;
2835
2836         /* encrypt */
2837         if ((r = sshbuf_reserve(encoded,
2838             sshbuf_len(encrypted) + authlen, &cp)) != 0)
2839                 goto out;
2840         if ((r = cipher_crypt(ciphercontext, 0, cp,
2841             sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
2842                 goto out;
2843
2844         sshbuf_reset(blob);
2845
2846         /* assemble uuencoded key */
2847         if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0 ||
2848             (r = sshbuf_dtob64(encoded, blob, 1)) != 0 ||
2849             (r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
2850                 goto out;
2851
2852         /* success */
2853         r = 0;
2854
2855  out:
2856         sshbuf_free(kdf);
2857         sshbuf_free(encoded);
2858         sshbuf_free(encrypted);
2859         cipher_free(ciphercontext);
2860         explicit_bzero(salt, sizeof(salt));
2861         if (key != NULL)
2862                 freezero(key, keylen + ivlen);
2863         if (pubkeyblob != NULL)
2864                 freezero(pubkeyblob, pubkeylen);
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 #ifdef PEM_R_PROBLEMS_GETTING_PASSWORD
3346                 case PEM_R_PROBLEMS_GETTING_PASSWORD:
3347 #endif
3348 #ifdef PEM_R_BAD_DECRYPT
3349                 case PEM_R_BAD_DECRYPT:
3350 #endif
3351                         return SSH_ERR_KEY_WRONG_PASSPHRASE;
3352                 default:
3353                         return SSH_ERR_INVALID_FORMAT;
3354                 }
3355         case ERR_LIB_EVP:
3356                 switch (pem_reason) {
3357 #ifdef EVP_R_BAD_DECRYPT
3358                 case EVP_R_BAD_DECRYPT:
3359                         return SSH_ERR_KEY_WRONG_PASSPHRASE;
3360 #endif
3361 #ifdef EVP_R_BN_DECODE_ERROR
3362                 case EVP_R_BN_DECODE_ERROR:
3363 #endif
3364                 case EVP_R_DECODE_ERROR:
3365 #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3366                 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3367 #endif
3368                         return SSH_ERR_INVALID_FORMAT;
3369                 default:
3370                         return SSH_ERR_LIBCRYPTO_ERROR;
3371                 }
3372         case ERR_LIB_ASN1:
3373                 return SSH_ERR_INVALID_FORMAT;
3374         }
3375         return SSH_ERR_LIBCRYPTO_ERROR;
3376 }
3377
3378 static void
3379 clear_libcrypto_errors(void)
3380 {
3381         while (ERR_get_error() != 0)
3382                 ;
3383 }
3384
3385 /*
3386  * Translate OpenSSL error codes to determine whether
3387  * passphrase is required/incorrect.
3388  */
3389 static int
3390 convert_libcrypto_error(void)
3391 {
3392         /*
3393          * Some password errors are reported at the beginning
3394          * of the error queue.
3395          */
3396         if (translate_libcrypto_error(ERR_peek_error()) ==
3397             SSH_ERR_KEY_WRONG_PASSPHRASE)
3398                 return SSH_ERR_KEY_WRONG_PASSPHRASE;
3399         return translate_libcrypto_error(ERR_peek_last_error());
3400 }
3401
3402 static int
3403 pem_passphrase_cb(char *buf, int size, int rwflag, void *u)
3404 {
3405         char *p = (char *)u;
3406         size_t len;
3407
3408         if (p == NULL || (len = strlen(p)) == 0)
3409                 return -1;
3410         if (size < 0 || len > (size_t)size)
3411                 return -1;
3412         memcpy(buf, p, len);
3413         return (int)len;
3414 }
3415
3416 static int
3417 sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3418     const char *passphrase, struct sshkey **keyp)
3419 {
3420         EVP_PKEY *pk = NULL;
3421         struct sshkey *prv = NULL;
3422         BIO *bio = NULL;
3423         int r;
3424
3425         if (keyp != NULL)
3426                 *keyp = NULL;
3427
3428         if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
3429                 return SSH_ERR_ALLOC_FAIL;
3430         if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
3431             (int)sshbuf_len(blob)) {
3432                 r = SSH_ERR_ALLOC_FAIL;
3433                 goto out;
3434         }
3435
3436         clear_libcrypto_errors();
3437         if ((pk = PEM_read_bio_PrivateKey(bio, NULL, pem_passphrase_cb,
3438             (char *)passphrase)) == NULL) {
3439                 /*
3440                  * libcrypto may return various ASN.1 errors when attempting
3441                  * to parse a key with an incorrect passphrase.
3442                  * Treat all format errors as "incorrect passphrase" if a
3443                  * passphrase was supplied.
3444                  */
3445                 if (passphrase != NULL && *passphrase != '\0')
3446                         r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3447                 else
3448                         r = convert_libcrypto_error();
3449                 goto out;
3450         }
3451         if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA &&
3452             (type == KEY_UNSPEC || type == KEY_RSA)) {
3453                 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3454                         r = SSH_ERR_ALLOC_FAIL;
3455                         goto out;
3456                 }
3457                 prv->rsa = EVP_PKEY_get1_RSA(pk);
3458                 prv->type = KEY_RSA;
3459 #ifdef DEBUG_PK
3460                 RSA_print_fp(stderr, prv->rsa, 8);
3461 #endif
3462                 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
3463                         r = SSH_ERR_LIBCRYPTO_ERROR;
3464                         goto out;
3465                 }
3466                 if ((r = sshkey_check_rsa_length(prv, 0)) != 0)
3467                         goto out;
3468         } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
3469             (type == KEY_UNSPEC || type == KEY_DSA)) {
3470                 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3471                         r = SSH_ERR_ALLOC_FAIL;
3472                         goto out;
3473                 }
3474                 prv->dsa = EVP_PKEY_get1_DSA(pk);
3475                 prv->type = KEY_DSA;
3476 #ifdef DEBUG_PK
3477                 DSA_print_fp(stderr, prv->dsa, 8);
3478 #endif
3479 #ifdef OPENSSL_HAS_ECC
3480         } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC &&
3481             (type == KEY_UNSPEC || type == KEY_ECDSA)) {
3482                 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3483                         r = SSH_ERR_ALLOC_FAIL;
3484                         goto out;
3485                 }
3486                 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
3487                 prv->type = KEY_ECDSA;
3488                 prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);
3489                 if (prv->ecdsa_nid == -1 ||
3490                     sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
3491                     sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
3492                     EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
3493                     sshkey_ec_validate_private(prv->ecdsa) != 0) {
3494                         r = SSH_ERR_INVALID_FORMAT;
3495                         goto out;
3496                 }
3497 # ifdef DEBUG_PK
3498                 if (prv != NULL && prv->ecdsa != NULL)
3499                         sshkey_dump_ec_key(prv->ecdsa);
3500 # endif
3501 #endif /* OPENSSL_HAS_ECC */
3502         } else {
3503                 r = SSH_ERR_INVALID_FORMAT;
3504                 goto out;
3505         }
3506         r = 0;
3507         if (keyp != NULL) {
3508                 *keyp = prv;
3509                 prv = NULL;
3510         }
3511  out:
3512         BIO_free(bio);
3513         EVP_PKEY_free(pk);
3514         sshkey_free(prv);
3515         return r;
3516 }
3517 #endif /* WITH_OPENSSL */
3518
3519 int
3520 sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3521     const char *passphrase, struct sshkey **keyp, char **commentp)
3522 {
3523         int r = SSH_ERR_INTERNAL_ERROR;
3524
3525         if (keyp != NULL)
3526                 *keyp = NULL;
3527         if (commentp != NULL)
3528                 *commentp = NULL;
3529
3530         switch (type) {
3531         case KEY_ED25519:
3532         case KEY_XMSS:
3533                 /* No fallback for new-format-only keys */
3534                 return sshkey_parse_private2(blob, type, passphrase,
3535                     keyp, commentp);
3536         default:
3537                 r = sshkey_parse_private2(blob, type, passphrase, keyp,
3538                     commentp);
3539                 /* Only fallback to PEM parser if a format error occurred. */
3540                 if (r != SSH_ERR_INVALID_FORMAT)
3541                         return r;
3542 #ifdef WITH_OPENSSL
3543                 return sshkey_parse_private_pem_fileblob(blob, type,
3544                     passphrase, keyp);
3545 #else
3546                 return SSH_ERR_INVALID_FORMAT;
3547 #endif /* WITH_OPENSSL */
3548         }
3549 }
3550
3551 int
3552 sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
3553     struct sshkey **keyp, char **commentp)
3554 {
3555         if (keyp != NULL)
3556                 *keyp = NULL;
3557         if (commentp != NULL)
3558                 *commentp = NULL;
3559
3560         return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
3561             passphrase, keyp, commentp);
3562 }
3563
3564 void
3565 sshkey_sig_details_free(struct sshkey_sig_details *details)
3566 {
3567         freezero(details, sizeof(*details));
3568 }
3569
3570 int
3571 sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type,
3572     struct sshkey **pubkeyp)
3573 {
3574         int r = SSH_ERR_INTERNAL_ERROR;
3575
3576         if (pubkeyp != NULL)
3577                 *pubkeyp = NULL;
3578         /* only new-format private keys bundle a public key inside */
3579         if ((r = sshkey_parse_private2_pubkey(blob, type, pubkeyp)) != 0)
3580                 return r;
3581         return 0;
3582 }
3583
3584 #ifdef WITH_XMSS
3585 /*
3586  * serialize the key with the current state and forward the state
3587  * maxsign times.
3588  */
3589 int
3590 sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
3591     u_int32_t maxsign, int printerror)
3592 {
3593         int r, rupdate;
3594
3595         if (maxsign == 0 ||
3596             sshkey_type_plain(k->type) != KEY_XMSS)
3597                 return sshkey_private_serialize_opt(k, b,
3598                     SSHKEY_SERIALIZE_DEFAULT);
3599         if ((r = sshkey_xmss_get_state(k, printerror)) != 0 ||
3600             (r = sshkey_private_serialize_opt(k, b,
3601             SSHKEY_SERIALIZE_STATE)) != 0 ||
3602             (r = sshkey_xmss_forward_state(k, maxsign)) != 0)
3603                 goto out;
3604         r = 0;
3605 out:
3606         if ((rupdate = sshkey_xmss_update_state(k, printerror)) != 0) {
3607                 if (r == 0)
3608                         r = rupdate;
3609         }
3610         return r;
3611 }
3612
3613 u_int32_t
3614 sshkey_signatures_left(const struct sshkey *k)
3615 {
3616         if (sshkey_type_plain(k->type) == KEY_XMSS)
3617                 return sshkey_xmss_signatures_left(k);
3618         return 0;
3619 }
3620
3621 int
3622 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
3623 {
3624         if (sshkey_type_plain(k->type) != KEY_XMSS)
3625                 return SSH_ERR_INVALID_ARGUMENT;
3626         return sshkey_xmss_enable_maxsign(k, maxsign);
3627 }
3628
3629 int
3630 sshkey_set_filename(struct sshkey *k, const char *filename)
3631 {
3632         if (k == NULL)
3633                 return SSH_ERR_INVALID_ARGUMENT;
3634         if (sshkey_type_plain(k->type) != KEY_XMSS)
3635                 return 0;
3636         if (filename == NULL)
3637                 return SSH_ERR_INVALID_ARGUMENT;
3638         if ((k->xmss_filename = strdup(filename)) == NULL)
3639                 return SSH_ERR_ALLOC_FAIL;
3640         return 0;
3641 }
3642 #else
3643 int
3644 sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
3645     u_int32_t maxsign, int printerror)
3646 {
3647         return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);
3648 }
3649
3650 u_int32_t
3651 sshkey_signatures_left(const struct sshkey *k)
3652 {
3653         return 0;
3654 }
3655
3656 int
3657 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
3658 {
3659         return SSH_ERR_INVALID_ARGUMENT;
3660 }
3661
3662 int
3663 sshkey_set_filename(struct sshkey *k, const char *filename)
3664 {
3665         if (k == NULL)
3666                 return SSH_ERR_INVALID_ARGUMENT;
3667         return 0;
3668 }
3669 #endif /* WITH_XMSS */