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