Coverage Report

Created: 2024-06-17 06:25

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