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