Coverage Report

Created: 2026-02-24 06:38

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