xref: /dragonfly/crypto/openssh/sshkey.c (revision ba1276acd1c8c22d225b1bcf370a14c878644f44)
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 *
sshkey_impl_from_type(int type)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 *
sshkey_impl_from_type_nid(int type,int nid)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 *
sshkey_impl_from_key(const struct sshkey * k)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 *
sshkey_type(const struct sshkey * k)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 *
sshkey_ssh_name_from_type_nid(int type,int nid)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
sshkey_type_is_cert(int type)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 *
sshkey_ssh_name(const struct sshkey * k)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 *
sshkey_ssh_name_plain(const struct sshkey * k)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
sshkey_type_from_name(const char * name)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
key_type_is_ecdsa_variant(int type)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
sshkey_ecdsa_nid_from_name(const char * name)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
sshkey_match_keyname_to_sigalgs(const char * keyname,const char * sigalgs)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 *
sshkey_alg_list(int certs_only,int plain_only,int include_sigonly,char sep)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
sshkey_names_valid2(const char * names,int allow_wildcard,int plain_only)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
sshkey_size(const struct sshkey * k)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
sshkey_type_is_valid_ca(int type)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
sshkey_is_cert(const struct sshkey * k)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
sshkey_is_sk(const struct sshkey * k)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
sshkey_type_plain(int type)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
sshkey_type_certified(int type)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
sshkey_curve_name_to_nid(const char * name)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
sshkey_curve_nid_to_bits(int nid)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
sshkey_ecdsa_bits_to_nid(int bits)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 *
sshkey_curve_nid_to_name(int nid)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
sshkey_ec_nid_to_hash_alg(int nid)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
cert_free(struct sshkey_cert * cert)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 *
cert_new(void)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 *
sshkey_new(int type)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
sshkey_sk_cleanup(struct sshkey * k)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
sshkey_free_contents(struct sshkey * k)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
sshkey_free(struct sshkey * k)667 sshkey_free(struct sshkey *k)
668 {
669           sshkey_free_contents(k);
670           freezero(k, sizeof(*k));
671 }
672 
673 static int
cert_compare(struct sshkey_cert * a,struct sshkey_cert * b)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
sshkey_sk_fields_equal(const struct sshkey * a,const struct sshkey * b)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
sshkey_equal_public(const struct sshkey * a,const struct sshkey * b)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
sshkey_equal(const struct sshkey * a,const struct sshkey * b)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
sshkey_serialize_sk(const struct sshkey * key,struct sshbuf * b)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
to_blob_buf(const struct sshkey * key,struct sshbuf * b,int force_plain,enum sshkey_serialize_rep opts)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
sshkey_putb(const struct sshkey * key,struct sshbuf * b)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
sshkey_puts_opts(const struct sshkey * key,struct sshbuf * b,enum sshkey_serialize_rep opts)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
sshkey_puts(const struct sshkey * key,struct sshbuf * b)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
sshkey_putb_plain(const struct sshkey * key,struct sshbuf * b)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
to_blob(const struct sshkey * key,u_char ** blobp,size_t * lenp,int force_plain,enum sshkey_serialize_rep opts)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
sshkey_to_blob(const struct sshkey * key,u_char ** blobp,size_t * lenp)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
sshkey_plain_to_blob(const struct sshkey * key,u_char ** blobp,size_t * lenp)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
sshkey_fingerprint_raw(const struct sshkey * k,int dgst_alg,u_char ** retp,size_t * lenp)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 *
fingerprint_b64(const char * alg,u_char * dgst_raw,size_t dgst_raw_len)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 *
fingerprint_hex(const char * alg,u_char * dgst_raw,size_t dgst_raw_len)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 *
fingerprint_bubblebabble(u_char * dgst_raw,size_t dgst_raw_len)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 *
fingerprint_randomart(const char * alg,u_char * dgst_raw,size_t dgst_raw_len,const struct sshkey * k)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 *
sshkey_fingerprint(const struct sshkey * k,int dgst_alg,enum sshkey_fp_rep dgst_rep)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
peek_type_nid(const char * s,size_t l,int * nid)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
sshkey_read(struct sshkey * ret,char ** cpp)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
sshkey_to_base64(const struct sshkey * key,char ** b64p)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
sshkey_format_text(const struct sshkey * key,struct sshbuf * b)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
sshkey_write(const struct sshkey * key,FILE * f)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 *
sshkey_cert_type(const struct sshkey * k)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
sshkey_check_rsa_length(const struct sshkey * k,int min_size)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
sshkey_ecdsa_key_to_nid(EC_KEY * k)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
sshkey_generate(int type,u_int bits,struct sshkey ** keyp)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
sshkey_cert_copy(const struct sshkey * from_key,struct sshkey * to_key)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
sshkey_copy_public_sk(const struct sshkey * from,struct sshkey * to)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
sshkey_from_private(const struct sshkey * k,struct sshkey ** pkp)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
sshkey_is_shielded(struct sshkey * k)1530 sshkey_is_shielded(struct sshkey *k)
1531 {
1532           return k != NULL && k->shielded_private != NULL;
1533 }
1534 
1535 int
sshkey_shield_private(struct sshkey * k)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
private2_check_padding(struct sshbuf * decrypted)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
sshkey_unshield_private(struct sshkey * k)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
cert_parse(struct sshbuf * b,struct sshkey * key,struct sshbuf * certbuf)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
sshkey_deserialize_sk(struct sshbuf * b,struct sshkey * key)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
sshkey_from_blob_internal(struct sshbuf * b,struct sshkey ** keyp,int allow_cert)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
sshkey_from_blob(const u_char * blob,size_t blen,struct sshkey ** keyp)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
sshkey_fromb(struct sshbuf * b,struct sshkey ** keyp)1977 sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
1978 {
1979           return sshkey_from_blob_internal(b, keyp, 1);
1980 }
1981 
1982 int
sshkey_froms(struct sshbuf * buf,struct sshkey ** keyp)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
sshkey_get_sigtype(const u_char * sig,size_t siglen,char ** sigtypep)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
sshkey_check_cert_sigtype(const struct sshkey * key,const char * allowed)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 *
sshkey_sigalg_by_name(const char * name)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
sshkey_check_sigtype(const u_char * sig,size_t siglen,const char * requested_alg)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
sshkey_sign(struct sshkey * key,u_char ** sigp,size_t * lenp,const u_char * data,size_t datalen,const char * alg,const char * sk_provider,const char * sk_pin,u_int compat)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
sshkey_verify(const struct sshkey * key,const u_char * sig,size_t siglen,const u_char * data,size_t dlen,const char * alg,u_int compat,struct sshkey_sig_details ** detailsp)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
sshkey_to_certified(struct sshkey * k)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
sshkey_drop_cert(struct sshkey * k)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
sshkey_certify_custom(struct sshkey * k,struct sshkey * ca,const char * alg,const char * sk_provider,const char * sk_pin,sshkey_certify_signer * signer,void * signer_ctx)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
default_key_sign(struct sshkey * key,u_char ** sigp,size_t * lenp,const u_char * data,size_t datalen,const char * alg,const char * sk_provider,const char * sk_pin,u_int compat,void * ctx)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
sshkey_certify(struct sshkey * k,struct sshkey * ca,const char * alg,const char * sk_provider,const char * sk_pin)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
sshkey_cert_check_authority(const struct sshkey * k,int want_host,int require_principal,int wildcard_pattern,uint64_t verify_time,const char * name,const char ** reason)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
sshkey_cert_check_authority_now(const struct sshkey * k,int want_host,int require_principal,int wildcard_pattern,const char * name,const char ** reason)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
sshkey_cert_check_host(const struct sshkey * key,const char * host,int wildcard_principals,const char * ca_sign_algorithms,const char ** reason)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
sshkey_format_cert_validity(const struct sshkey_cert * cert,char * s,size_t l)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
sshkey_serialize_private_sk(const struct sshkey * key,struct sshbuf * b)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
sshkey_private_serialize_opt(struct sshkey * key,struct sshbuf * buf,enum sshkey_serialize_rep opts)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
sshkey_private_serialize(struct sshkey * key,struct sshbuf * b)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
sshkey_private_deserialize_sk(struct sshbuf * buf,struct sshkey * k)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
sshkey_private_deserialize(struct sshbuf * buf,struct sshkey ** kp)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
sshkey_ec_validate_public(const EC_GROUP * group,const EC_POINT * public)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
sshkey_ec_validate_private(const EC_KEY * key)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
sshkey_dump_ec_point(const EC_GROUP * group,const EC_POINT * point)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
sshkey_dump_ec_key(const EC_KEY * key)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
sshkey_private_to_blob2(struct sshkey * prv,struct sshbuf * blob,const char * passphrase,const char * comment,const char * ciphername,int rounds)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
private2_uudecode(struct sshbuf * blob,struct sshbuf ** decodedp)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
private2_decrypt(struct sshbuf * decoded,const char * passphrase,struct sshbuf ** decryptedp,struct sshkey ** pubkeyp)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
sshkey_parse_private2(struct sshbuf * blob,int type,const char * passphrase,struct sshkey ** keyp,char ** commentp)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
sshkey_parse_private2_pubkey(struct sshbuf * blob,int type,struct sshkey ** keyp)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
sshkey_private_to_blob_pem_pkcs8(struct sshkey * key,struct sshbuf * buf,int format,const char * _passphrase,const char * comment)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
sshkey_private_to_fileblob(struct sshkey * key,struct sshbuf * blob,const char * passphrase,const char * comment,int format,const char * openssh_format_cipher,int openssh_format_rounds)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
translate_libcrypto_error(unsigned long pem_err)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
clear_libcrypto_errors(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
convert_libcrypto_error(void)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
pem_passphrase_cb(char * buf,int size,int rwflag,void * u)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
sshkey_parse_private_pem_fileblob(struct sshbuf * blob,int type,const char * passphrase,struct sshkey ** keyp)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
sshkey_parse_private_fileblob_type(struct sshbuf * blob,int type,const char * passphrase,struct sshkey ** keyp,char ** commentp)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
sshkey_parse_private_fileblob(struct sshbuf * buffer,const char * passphrase,struct sshkey ** keyp,char ** commentp)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
sshkey_sig_details_free(struct sshkey_sig_details * details)3610 sshkey_sig_details_free(struct sshkey_sig_details *details)
3611 {
3612           freezero(details, sizeof(*details));
3613 }
3614 
3615 int
sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf * blob,int type,struct sshkey ** pubkeyp)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
sshkey_private_serialize_maxsign(struct sshkey * k,struct sshbuf * b,u_int32_t maxsign,int printerror)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
sshkey_signatures_left(const struct sshkey * k)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
sshkey_enable_maxsign(struct sshkey * k,u_int32_t maxsign)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
sshkey_set_filename(struct sshkey * k,const char * filename)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
sshkey_private_serialize_maxsign(struct sshkey * k,struct sshbuf * b,u_int32_t maxsign,int printerror)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
sshkey_signatures_left(const struct sshkey * k)3696 sshkey_signatures_left(const struct sshkey *k)
3697 {
3698           return 0;
3699 }
3700 
3701 int
sshkey_enable_maxsign(struct sshkey * k,u_int32_t maxsign)3702 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
3703 {
3704           return SSH_ERR_INVALID_ARGUMENT;
3705 }
3706 
3707 int
sshkey_set_filename(struct sshkey * k,const char * filename)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 */
3715