Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/libfreerdp/crypto/privatekey.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Private key Handling
4
 *
5
 * Copyright 2011 Jiten Pathy
6
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7
 * Copyright 2015 Thincast Technologies GmbH
8
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
9
 * Copyright 2023 Armin Novak <anovak@thincast.com>
10
 * Copyright 2023 Thincast Technologies GmbH
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 *     http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24
25
#include <freerdp/config.h>
26
27
#include <errno.h>
28
#include <stdio.h>
29
#include <string.h>
30
31
#include <winpr/assert.h>
32
#include <winpr/wtypes.h>
33
#include <winpr/crt.h>
34
#include <winpr/file.h>
35
#include <winpr/crypto.h>
36
37
#include <openssl/pem.h>
38
#include <openssl/rsa.h>
39
#include <openssl/bn.h>
40
41
#include "privatekey.h"
42
#include "cert_common.h"
43
44
#include <freerdp/crypto/privatekey.h>
45
46
#include <openssl/evp.h>
47
48
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
49
#include <openssl/core_names.h>
50
#endif
51
52
#include "x509_utils.h"
53
#include "crypto.h"
54
#include "opensslcompat.h"
55
56
#define TAG FREERDP_TAG("crypto")
57
58
struct rdp_private_key
59
{
60
  EVP_PKEY* evp;
61
62
  rdpCertInfo cert;
63
  BYTE* PrivateExponent;
64
  DWORD PrivateExponentLength;
65
};
66
67
/*
68
 * Terminal Services Signing Keys.
69
 * Yes, Terminal Services Private Key is publicly available.
70
 */
71
72
static BYTE tssk_modulus[] = { 0x3d, 0x3a, 0x5e, 0xbd, 0x72, 0x43, 0x3e, 0xc9, 0x4d, 0xbb, 0xc1,
73
                             0x1e, 0x4a, 0xba, 0x5f, 0xcb, 0x3e, 0x88, 0x20, 0x87, 0xef, 0xf5,
74
                             0xc1, 0xe2, 0xd7, 0xb7, 0x6b, 0x9a, 0xf2, 0x52, 0x45, 0x95, 0xce,
75
                             0x63, 0x65, 0x6b, 0x58, 0x3a, 0xfe, 0xef, 0x7c, 0xe7, 0xbf, 0xfe,
76
                             0x3d, 0xf6, 0x5c, 0x7d, 0x6c, 0x5e, 0x06, 0x09, 0x1a, 0xf5, 0x61,
77
                             0xbb, 0x20, 0x93, 0x09, 0x5f, 0x05, 0x6d, 0xea, 0x87 };
78
79
static BYTE tssk_privateExponent[] = {
80
  0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55, 0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8,
81
  0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94, 0xcf, 0x92, 0xcc, 0x33, 0x99, 0xe8, 0x08, 0x60,
82
  0x17, 0x9a, 0x12, 0x9f, 0x24, 0xdd, 0xb1, 0x24, 0x99, 0xc7, 0x3a, 0xb8, 0x0a, 0x7b, 0x0d, 0xdd,
83
  0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3, 0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f
84
};
85
86
static const rdpPrivateKey tssk = { .PrivateExponent = tssk_privateExponent,
87
                                  .PrivateExponentLength = sizeof(tssk_privateExponent),
88
                                  .cert = { .Modulus = tssk_modulus,
89
                                            .ModulusLength = sizeof(tssk_modulus) } };
90
const rdpPrivateKey* priv_key_tssk = &tssk;
91
92
#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
93
static RSA* evp_pkey_to_rsa(const rdpPrivateKey* key)
94
0
{
95
0
  if (!freerdp_key_is_rsa(key))
96
0
  {
97
0
    WLog_WARN(TAG, "Key is no RSA key");
98
0
    return NULL;
99
0
  }
100
101
0
  RSA* rsa = NULL;
102
0
  BIO* bio = BIO_new(
103
#if defined(LIBRESSL_VERSION_NUMBER)
104
      BIO_s_mem()
105
#else
106
0
      BIO_s_secmem()
107
0
#endif
108
0
  );
109
0
  if (!bio)
110
0
    return NULL;
111
0
  const int rc = PEM_write_bio_PrivateKey(bio, key->evp, NULL, NULL, 0, NULL, NULL);
112
0
  if (rc != 1)
113
0
    goto fail;
114
0
  rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
115
0
fail:
116
0
  BIO_free_all(bio);
117
0
  return rsa;
118
0
}
119
#endif
120
121
static EVP_PKEY* evp_pkey_utils_from_pem(const char* data, size_t len, BOOL fromFile)
122
0
{
123
0
  EVP_PKEY* evp = NULL;
124
0
  BIO* bio = NULL;
125
0
  if (fromFile)
126
0
    bio = BIO_new_file(data, "rb");
127
0
  else
128
0
    bio = BIO_new_mem_buf(data, len);
129
130
0
  if (!bio)
131
0
  {
132
0
    WLog_ERR(TAG, "BIO_new failed for private key");
133
0
    return NULL;
134
0
  }
135
136
0
  evp = PEM_read_bio_PrivateKey(bio, NULL, NULL, 0);
137
0
  BIO_free_all(bio);
138
0
  if (!evp)
139
0
    WLog_ERR(TAG, "PEM_read_bio_PrivateKey returned NULL [input length %" PRIuz "]", len);
140
141
0
  return evp;
142
0
}
143
144
static BOOL key_read_private(rdpPrivateKey* key)
145
0
{
146
0
  BOOL rc = FALSE;
147
148
0
  WINPR_ASSERT(key);
149
0
  WINPR_ASSERT(key->evp);
150
151
  /* The key is not an RSA key, that means we just return success. */
152
0
  if (!freerdp_key_is_rsa(key))
153
0
    return TRUE;
154
155
0
#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
156
0
  RSA* rsa = evp_pkey_to_rsa(key);
157
0
  if (!rsa)
158
0
  {
159
0
    char ebuffer[256] = { 0 };
160
0
    WLog_ERR(TAG, "unable to load RSA key: %s.",
161
0
             winpr_strerror(errno, ebuffer, sizeof(ebuffer)));
162
0
    goto fail;
163
0
  }
164
165
0
  switch (RSA_check_key(rsa))
166
0
  {
167
0
    case 0:
168
0
      WLog_ERR(TAG, "invalid RSA key");
169
0
      goto fail;
170
171
0
    case 1:
172
      /* Valid key. */
173
0
      break;
174
175
0
    default:
176
0
    {
177
0
      char ebuffer[256] = { 0 };
178
0
      WLog_ERR(TAG, "unexpected error when checking RSA key: %s.",
179
0
               winpr_strerror(errno, ebuffer, sizeof(ebuffer)));
180
0
      goto fail;
181
0
    }
182
0
  }
183
184
0
  const BIGNUM* rsa_e = NULL;
185
0
  const BIGNUM* rsa_n = NULL;
186
0
  const BIGNUM* rsa_d = NULL;
187
188
0
  RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
189
#else
190
  BIGNUM* rsa_e = NULL;
191
  BIGNUM* rsa_n = NULL;
192
  BIGNUM* rsa_d = NULL;
193
194
  if (!EVP_PKEY_get_bn_param(key->evp, OSSL_PKEY_PARAM_RSA_N, &rsa_n))
195
    goto fail;
196
  if (!EVP_PKEY_get_bn_param(key->evp, OSSL_PKEY_PARAM_RSA_E, &rsa_e))
197
    goto fail;
198
  if (!EVP_PKEY_get_bn_param(key->evp, OSSL_PKEY_PARAM_RSA_D, &rsa_d))
199
    goto fail;
200
#endif
201
0
  if (BN_num_bytes(rsa_e) > 4)
202
0
  {
203
0
    WLog_ERR(TAG, "RSA public exponent too large");
204
0
    goto fail;
205
0
  }
206
207
0
  if (!read_bignum(&key->PrivateExponent, &key->PrivateExponentLength, rsa_d, TRUE))
208
0
    goto fail;
209
210
0
  if (!cert_info_create(&key->cert, rsa_n, rsa_e))
211
0
    goto fail;
212
0
  rc = TRUE;
213
0
fail:
214
0
#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
215
0
  RSA_free(rsa);
216
#else
217
  BN_free(rsa_d);
218
  BN_free(rsa_e);
219
  BN_free(rsa_n);
220
#endif
221
0
  return rc;
222
0
}
223
224
rdpPrivateKey* freerdp_key_new_from_pem(const char* pem)
225
0
{
226
0
  rdpPrivateKey* key = freerdp_key_new();
227
0
  if (!key || !pem)
228
0
    goto fail;
229
0
  key->evp = evp_pkey_utils_from_pem(pem, strlen(pem), FALSE);
230
0
  if (!key->evp)
231
0
    goto fail;
232
0
  if (!key_read_private(key))
233
0
    goto fail;
234
0
  return key;
235
0
fail:
236
0
  freerdp_key_free(key);
237
0
  return NULL;
238
0
}
239
240
rdpPrivateKey* freerdp_key_new_from_file(const char* keyfile)
241
0
{
242
243
0
  rdpPrivateKey* key = freerdp_key_new();
244
0
  if (!key || !keyfile)
245
0
    goto fail;
246
247
0
  key->evp = evp_pkey_utils_from_pem(keyfile, strlen(keyfile), TRUE);
248
0
  if (!key->evp)
249
0
    goto fail;
250
0
  if (!key_read_private(key))
251
0
    goto fail;
252
0
  return key;
253
0
fail:
254
0
  freerdp_key_free(key);
255
0
  return NULL;
256
0
}
257
258
rdpPrivateKey* freerdp_key_new(void)
259
14.9k
{
260
14.9k
  return calloc(1, sizeof(rdpPrivateKey));
261
14.9k
}
262
263
rdpPrivateKey* freerdp_key_clone(const rdpPrivateKey* key)
264
0
{
265
0
  if (!key)
266
0
    return NULL;
267
268
0
  rdpPrivateKey* _key = (rdpPrivateKey*)calloc(1, sizeof(rdpPrivateKey));
269
270
0
  if (!_key)
271
0
    return NULL;
272
273
0
  if (key->evp)
274
0
  {
275
0
    _key->evp = key->evp;
276
0
    if (!_key->evp)
277
0
      goto out_fail;
278
0
    EVP_PKEY_up_ref(_key->evp);
279
0
  }
280
281
0
  if (key->PrivateExponent)
282
0
  {
283
0
    _key->PrivateExponent = (BYTE*)malloc(key->PrivateExponentLength);
284
285
0
    if (!_key->PrivateExponent)
286
0
      goto out_fail;
287
288
0
    CopyMemory(_key->PrivateExponent, key->PrivateExponent, key->PrivateExponentLength);
289
0
    _key->PrivateExponentLength = key->PrivateExponentLength;
290
0
  }
291
292
0
  if (!cert_info_clone(&_key->cert, &key->cert))
293
0
    goto out_fail;
294
295
0
  return _key;
296
0
out_fail:
297
0
  WINPR_PRAGMA_DIAG_PUSH
298
0
  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
299
0
  freerdp_key_free(_key);
300
0
  WINPR_PRAGMA_DIAG_POP
301
0
  return NULL;
302
0
}
303
304
void freerdp_key_free(rdpPrivateKey* key)
305
119k
{
306
119k
  if (!key)
307
104k
    return;
308
309
14.9k
  EVP_PKEY_free(key->evp);
310
14.9k
  if (key->PrivateExponent)
311
0
    memset(key->PrivateExponent, 0, key->PrivateExponentLength);
312
14.9k
  free(key->PrivateExponent);
313
14.9k
  cert_info_free(&key->cert);
314
14.9k
  free(key);
315
14.9k
}
316
317
const rdpCertInfo* freerdp_key_get_info(const rdpPrivateKey* key)
318
0
{
319
0
  WINPR_ASSERT(key);
320
0
  if (!freerdp_key_is_rsa(key))
321
0
    return NULL;
322
0
  return &key->cert;
323
0
}
324
325
const BYTE* freerdp_key_get_exponent(const rdpPrivateKey* key, size_t* plength)
326
0
{
327
0
  WINPR_ASSERT(key);
328
0
  if (!freerdp_key_is_rsa(key))
329
0
  {
330
0
    if (plength)
331
0
      *plength = 0;
332
0
    return NULL;
333
0
  }
334
335
0
  if (plength)
336
0
    *plength = key->PrivateExponentLength;
337
0
  return key->PrivateExponent;
338
0
}
339
340
EVP_PKEY* freerdp_key_get_evp_pkey(const rdpPrivateKey* key)
341
0
{
342
0
  WINPR_ASSERT(key);
343
344
0
  EVP_PKEY* evp = key->evp;
345
0
  WINPR_ASSERT(evp);
346
0
  EVP_PKEY_up_ref(evp);
347
0
  return evp;
348
0
}
349
350
BOOL freerdp_key_is_rsa(const rdpPrivateKey* key)
351
0
{
352
0
  WINPR_ASSERT(key);
353
0
  if (key == priv_key_tssk)
354
0
    return TRUE;
355
356
0
  WINPR_ASSERT(key->evp);
357
0
  return (EVP_PKEY_id(key->evp) == EVP_PKEY_RSA);
358
0
}
359
360
size_t freerdp_key_get_bits(const rdpPrivateKey* key)
361
0
{
362
0
  int rc = -1;
363
0
#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
364
0
  RSA* rsa = evp_pkey_to_rsa(key);
365
0
  if (rsa)
366
0
  {
367
0
    rc = RSA_bits(rsa);
368
0
    RSA_free(rsa);
369
0
  }
370
#else
371
  rc = EVP_PKEY_get_bits(key->evp);
372
#endif
373
374
0
  return rc;
375
0
}
376
377
BOOL freerdp_key_generate(rdpPrivateKey* key, size_t key_length)
378
0
{
379
0
  BOOL rc = FALSE;
380
381
0
#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
382
0
  RSA* rsa = NULL;
383
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
384
  rsa = RSA_generate_key(key_length, RSA_F4, NULL, NULL);
385
#else
386
0
  {
387
0
    BIGNUM* bn = BN_secure_new();
388
389
0
    if (!bn)
390
0
      return FALSE;
391
392
0
    rsa = RSA_new();
393
394
0
    if (!rsa)
395
0
    {
396
0
      BN_clear_free(bn);
397
0
      return FALSE;
398
0
    }
399
400
0
    BN_set_word(bn, RSA_F4);
401
0
    const int res = RSA_generate_key_ex(rsa, key_length, bn, NULL);
402
0
    BN_clear_free(bn);
403
404
0
    if (res != 1)
405
0
      return FALSE;
406
0
  }
407
0
#endif
408
409
0
  EVP_PKEY_free(key->evp);
410
0
  key->evp = EVP_PKEY_new();
411
412
0
  if (!EVP_PKEY_assign_RSA(key->evp, rsa))
413
0
  {
414
0
    EVP_PKEY_free(key->evp);
415
0
    key->evp = NULL;
416
0
    RSA_free(rsa);
417
0
    return FALSE;
418
0
  }
419
420
0
  rc = TRUE;
421
#else
422
  EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
423
  if (!pctx)
424
    return FALSE;
425
426
  if (EVP_PKEY_keygen_init(pctx) != 1)
427
    goto fail;
428
429
  if (EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_length) != 1)
430
    goto fail;
431
432
  EVP_PKEY_free(key->evp);
433
  key->evp = NULL;
434
435
  if (EVP_PKEY_generate(pctx, &key->evp) != 1)
436
    goto fail;
437
438
  rc = TRUE;
439
fail:
440
  EVP_PKEY_CTX_free(pctx);
441
#endif
442
0
  return rc;
443
0
}
444
445
BYTE* freerdp_key_get_param(const rdpPrivateKey* key, enum FREERDP_KEY_PARAM param, size_t* plength)
446
0
{
447
0
  BYTE* buf = NULL;
448
449
0
  WINPR_ASSERT(key);
450
0
  WINPR_ASSERT(plength);
451
452
0
  *plength = 0;
453
454
0
  BIGNUM* bn = NULL;
455
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
456
457
  const char* pk = NULL;
458
  switch (param)
459
  {
460
    case FREERDP_KEY_PARAM_RSA_D:
461
      pk = OSSL_PKEY_PARAM_RSA_D;
462
      break;
463
    case FREERDP_KEY_PARAM_RSA_E:
464
      pk = OSSL_PKEY_PARAM_RSA_E;
465
      break;
466
    case FREERDP_KEY_PARAM_RSA_N:
467
      pk = OSSL_PKEY_PARAM_RSA_N;
468
      break;
469
    default:
470
      return NULL;
471
  }
472
473
  if (!EVP_PKEY_get_bn_param(key->evp, pk, &bn))
474
    return NULL;
475
#else
476
0
  {
477
0
    const RSA* rsa = EVP_PKEY_get0_RSA(key->evp);
478
0
    if (!rsa)
479
0
      return NULL;
480
481
0
    const BIGNUM* cbn = NULL;
482
0
    switch (param)
483
0
    {
484
0
      case FREERDP_KEY_PARAM_RSA_D:
485
0
#if OPENSSL_VERSION_NUMBER >= 0x10101007L
486
0
        cbn = RSA_get0_d(rsa);
487
0
#endif
488
0
        break;
489
0
      case FREERDP_KEY_PARAM_RSA_E:
490
0
#if OPENSSL_VERSION_NUMBER >= 0x10101007L
491
0
        cbn = RSA_get0_e(rsa);
492
0
#endif
493
0
        break;
494
0
      case FREERDP_KEY_PARAM_RSA_N:
495
0
#if OPENSSL_VERSION_NUMBER >= 0x10101007L
496
0
        cbn = RSA_get0_n(rsa);
497
0
#endif
498
0
        break;
499
0
      default:
500
0
        return NULL;
501
0
    }
502
0
    if (!cbn)
503
0
      return NULL;
504
0
    bn = BN_dup(cbn);
505
0
    if (!bn)
506
0
      return NULL;
507
0
  }
508
0
#endif
509
510
0
  const int length = BN_num_bytes(bn);
511
0
  if (length < 0)
512
0
    goto fail;
513
514
0
  const size_t alloc_size = (size_t)length + 1ull;
515
0
  buf = calloc(alloc_size, sizeof(BYTE));
516
0
  if (!buf)
517
0
    goto fail;
518
519
0
  const int bnlen = BN_bn2bin(bn, buf);
520
0
  if (bnlen != length)
521
0
  {
522
0
    free(buf);
523
0
    buf = NULL;
524
0
  }
525
0
  else
526
0
    *plength = length;
527
528
0
fail:
529
0
  BN_free(bn);
530
0
  return buf;
531
0
}
532
533
WINPR_DIGEST_CTX* freerdp_key_digest_sign(rdpPrivateKey* key, WINPR_MD_TYPE digest)
534
0
{
535
0
  WINPR_DIGEST_CTX* md_ctx = winpr_Digest_New();
536
0
  if (!md_ctx)
537
0
    return NULL;
538
539
0
  if (!winpr_DigestSign_Init(md_ctx, digest, key->evp))
540
0
  {
541
0
    winpr_Digest_Free(md_ctx);
542
0
    return NULL;
543
0
  }
544
0
  return md_ctx;
545
0
}