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