Coverage Report

Created: 2025-07-11 06:18

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