Coverage Report

Created: 2025-11-23 06:13

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