Bug Summary

File:src/usr.bin/ssh/ssh/../sshkey.c
Warning:line 2194, column 7
Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'

Annotated Source Code

Press '?' to see keyboard shortcuts

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