Coverage Report

Created: 2023-11-27 06:40

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