FreeRDP
privatekey.c
1 
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 {
95  if (!freerdp_key_is_rsa(key))
96  {
97  WLog_WARN(TAG, "Key is no RSA key");
98  return NULL;
99  }
100 
101  RSA* rsa = NULL;
102  BIO* bio = BIO_new(
103 #if defined(LIBRESSL_VERSION_NUMBER)
104  BIO_s_mem()
105 #else
106  BIO_s_secmem()
107 #endif
108  );
109  if (!bio)
110  return NULL;
111  const int rc = PEM_write_bio_PrivateKey(bio, key->evp, NULL, NULL, 0, NULL, NULL);
112  if (rc != 1)
113  goto fail;
114  rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
115 fail:
116  BIO_free_all(bio);
117  return rsa;
118 }
119 #endif
120 
121 static EVP_PKEY* evp_pkey_utils_from_pem(const char* data, size_t len, BOOL fromFile)
122 {
123  EVP_PKEY* evp = NULL;
124  BIO* bio = NULL;
125  if (fromFile)
126  bio = BIO_new_file(data, "rb");
127  else
128  {
129  if (len > INT_MAX)
130  return NULL;
131  bio = BIO_new_mem_buf(data, (int)len);
132  }
133 
134  if (!bio)
135  {
136  WLog_ERR(TAG, "BIO_new failed for private key");
137  return NULL;
138  }
139 
140  evp = PEM_read_bio_PrivateKey(bio, NULL, NULL, 0);
141  BIO_free_all(bio);
142  if (!evp)
143  WLog_ERR(TAG, "PEM_read_bio_PrivateKey returned NULL [input length %" PRIuz "]", len);
144 
145  return evp;
146 }
147 
148 static BOOL key_read_private(rdpPrivateKey* key)
149 {
150  BOOL rc = FALSE;
151 
152  WINPR_ASSERT(key);
153  WINPR_ASSERT(key->evp);
154 
155  /* The key is not an RSA key, that means we just return success. */
156  if (!freerdp_key_is_rsa(key))
157  return TRUE;
158 
159 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
160  RSA* rsa = evp_pkey_to_rsa(key);
161  if (!rsa)
162  {
163  char ebuffer[256] = { 0 };
164  WLog_ERR(TAG, "unable to load RSA key: %s.",
165  winpr_strerror(errno, ebuffer, sizeof(ebuffer)));
166  goto fail;
167  }
168 
169  switch (RSA_check_key(rsa))
170  {
171  case 0:
172  WLog_ERR(TAG, "invalid RSA key");
173  goto fail;
174 
175  case 1:
176  /* Valid key. */
177  break;
178 
179  default:
180  {
181  char ebuffer[256] = { 0 };
182  WLog_ERR(TAG, "unexpected error when checking RSA key: %s.",
183  winpr_strerror(errno, ebuffer, sizeof(ebuffer)));
184  goto fail;
185  }
186  }
187 
188  const BIGNUM* rsa_e = NULL;
189  const BIGNUM* rsa_n = NULL;
190  const BIGNUM* rsa_d = NULL;
191 
192  RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
193 #else
194  BIGNUM* rsa_e = NULL;
195  BIGNUM* rsa_n = NULL;
196  BIGNUM* rsa_d = NULL;
197 
198  if (!EVP_PKEY_get_bn_param(key->evp, OSSL_PKEY_PARAM_RSA_N, &rsa_n))
199  goto fail;
200  if (!EVP_PKEY_get_bn_param(key->evp, OSSL_PKEY_PARAM_RSA_E, &rsa_e))
201  goto fail;
202  if (!EVP_PKEY_get_bn_param(key->evp, OSSL_PKEY_PARAM_RSA_D, &rsa_d))
203  goto fail;
204 #endif
205  if (BN_num_bytes(rsa_e) > 4)
206  {
207  WLog_ERR(TAG, "RSA public exponent too large");
208  goto fail;
209  }
210 
211  if (!read_bignum(&key->PrivateExponent, &key->PrivateExponentLength, rsa_d, TRUE))
212  goto fail;
213 
214  if (!cert_info_create(&key->cert, rsa_n, rsa_e))
215  goto fail;
216  rc = TRUE;
217 fail:
218 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
219  RSA_free(rsa);
220 #else
221  BN_free(rsa_d);
222  BN_free(rsa_e);
223  BN_free(rsa_n);
224 #endif
225  return rc;
226 }
227 
228 rdpPrivateKey* freerdp_key_new_from_pem(const char* pem)
229 {
230  rdpPrivateKey* key = freerdp_key_new();
231  if (!key || !pem)
232  goto fail;
233  key->evp = evp_pkey_utils_from_pem(pem, strlen(pem), FALSE);
234  if (!key->evp)
235  goto fail;
236  if (!key_read_private(key))
237  goto fail;
238  return key;
239 fail:
240  freerdp_key_free(key);
241  return NULL;
242 }
243 
244 rdpPrivateKey* freerdp_key_new_from_file(const char* keyfile)
245 {
246 
247  rdpPrivateKey* key = freerdp_key_new();
248  if (!key || !keyfile)
249  goto fail;
250 
251  key->evp = evp_pkey_utils_from_pem(keyfile, strlen(keyfile), TRUE);
252  if (!key->evp)
253  goto fail;
254  if (!key_read_private(key))
255  goto fail;
256  return key;
257 fail:
258  freerdp_key_free(key);
259  return NULL;
260 }
261 
262 rdpPrivateKey* freerdp_key_new(void)
263 {
264  return calloc(1, sizeof(rdpPrivateKey));
265 }
266 
267 rdpPrivateKey* freerdp_key_clone(const rdpPrivateKey* key)
268 {
269  if (!key)
270  return NULL;
271 
272  rdpPrivateKey* _key = (rdpPrivateKey*)calloc(1, sizeof(rdpPrivateKey));
273 
274  if (!_key)
275  return NULL;
276 
277  if (key->evp)
278  {
279  _key->evp = key->evp;
280  if (!_key->evp)
281  goto out_fail;
282  EVP_PKEY_up_ref(_key->evp);
283  }
284 
285  if (key->PrivateExponent)
286  {
287  _key->PrivateExponent = (BYTE*)malloc(key->PrivateExponentLength);
288 
289  if (!_key->PrivateExponent)
290  goto out_fail;
291 
292  CopyMemory(_key->PrivateExponent, key->PrivateExponent, key->PrivateExponentLength);
293  _key->PrivateExponentLength = key->PrivateExponentLength;
294  }
295 
296  if (!cert_info_clone(&_key->cert, &key->cert))
297  goto out_fail;
298 
299  return _key;
300 out_fail:
301  WINPR_PRAGMA_DIAG_PUSH
302  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
303  freerdp_key_free(_key);
304  WINPR_PRAGMA_DIAG_POP
305  return NULL;
306 }
307 
308 void freerdp_key_free(rdpPrivateKey* key)
309 {
310  if (!key)
311  return;
312 
313  EVP_PKEY_free(key->evp);
314  if (key->PrivateExponent)
315  memset(key->PrivateExponent, 0, key->PrivateExponentLength);
316  free(key->PrivateExponent);
317  cert_info_free(&key->cert);
318  free(key);
319 }
320 
321 const rdpCertInfo* freerdp_key_get_info(const rdpPrivateKey* key)
322 {
323  WINPR_ASSERT(key);
324  if (!freerdp_key_is_rsa(key))
325  return NULL;
326  return &key->cert;
327 }
328 
329 const BYTE* freerdp_key_get_exponent(const rdpPrivateKey* key, size_t* plength)
330 {
331  WINPR_ASSERT(key);
332  if (!freerdp_key_is_rsa(key))
333  {
334  if (plength)
335  *plength = 0;
336  return NULL;
337  }
338 
339  if (plength)
340  *plength = key->PrivateExponentLength;
341  return key->PrivateExponent;
342 }
343 
344 EVP_PKEY* freerdp_key_get_evp_pkey(const rdpPrivateKey* key)
345 {
346  WINPR_ASSERT(key);
347 
348  EVP_PKEY* evp = key->evp;
349  WINPR_ASSERT(evp);
350  EVP_PKEY_up_ref(evp);
351  return evp;
352 }
353 
354 BOOL freerdp_key_is_rsa(const rdpPrivateKey* key)
355 {
356  WINPR_ASSERT(key);
357  if (key == priv_key_tssk)
358  return TRUE;
359 
360  WINPR_ASSERT(key->evp);
361  return (EVP_PKEY_id(key->evp) == EVP_PKEY_RSA);
362 }
363 
364 size_t freerdp_key_get_bits(const rdpPrivateKey* key)
365 {
366  int rc = -1;
367 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
368  RSA* rsa = evp_pkey_to_rsa(key);
369  if (rsa)
370  {
371  rc = RSA_bits(rsa);
372  RSA_free(rsa);
373  }
374 #else
375  rc = EVP_PKEY_get_bits(key->evp);
376 #endif
377 
378  return rc;
379 }
380 
381 BOOL freerdp_key_generate(rdpPrivateKey* key, size_t key_length)
382 {
383  BOOL rc = FALSE;
384 
385 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
386  RSA* rsa = NULL;
387 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
388  rsa = RSA_generate_key(key_length, RSA_F4, NULL, NULL);
389 #else
390  {
391  BIGNUM* bn = BN_secure_new();
392 
393  if (!bn)
394  return FALSE;
395 
396  rsa = RSA_new();
397 
398  if (!rsa)
399  {
400  BN_clear_free(bn);
401  return FALSE;
402  }
403 
404  BN_set_word(bn, RSA_F4);
405  const int res = RSA_generate_key_ex(rsa, key_length, bn, NULL);
406  BN_clear_free(bn);
407 
408  if (res != 1)
409  return FALSE;
410  }
411 #endif
412 
413  EVP_PKEY_free(key->evp);
414  key->evp = EVP_PKEY_new();
415 
416  if (!EVP_PKEY_assign_RSA(key->evp, rsa))
417  {
418  EVP_PKEY_free(key->evp);
419  key->evp = NULL;
420  RSA_free(rsa);
421  return FALSE;
422  }
423 
424  rc = TRUE;
425 #else
426  EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
427  if (!pctx)
428  return FALSE;
429 
430  if (EVP_PKEY_keygen_init(pctx) != 1)
431  goto fail;
432 
433  if (key_length > INT_MAX)
434  goto fail;
435 
436  if (EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, (int)key_length) != 1)
437  goto fail;
438 
439  EVP_PKEY_free(key->evp);
440  key->evp = NULL;
441 
442  if (EVP_PKEY_generate(pctx, &key->evp) != 1)
443  goto fail;
444 
445  rc = TRUE;
446 fail:
447  EVP_PKEY_CTX_free(pctx);
448 #endif
449  return rc;
450 }
451 
452 BYTE* freerdp_key_get_param(const rdpPrivateKey* key, enum FREERDP_KEY_PARAM param, size_t* plength)
453 {
454  BYTE* buf = NULL;
455 
456  WINPR_ASSERT(key);
457  WINPR_ASSERT(plength);
458 
459  *plength = 0;
460 
461  BIGNUM* bn = NULL;
462 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
463 
464  const char* pk = NULL;
465  switch (param)
466  {
467  case FREERDP_KEY_PARAM_RSA_D:
468  pk = OSSL_PKEY_PARAM_RSA_D;
469  break;
470  case FREERDP_KEY_PARAM_RSA_E:
471  pk = OSSL_PKEY_PARAM_RSA_E;
472  break;
473  case FREERDP_KEY_PARAM_RSA_N:
474  pk = OSSL_PKEY_PARAM_RSA_N;
475  break;
476  default:
477  return NULL;
478  }
479 
480  if (!EVP_PKEY_get_bn_param(key->evp, pk, &bn))
481  return NULL;
482 #else
483  {
484  const RSA* rsa = EVP_PKEY_get0_RSA(key->evp);
485  if (!rsa)
486  return NULL;
487 
488  const BIGNUM* cbn = NULL;
489  switch (param)
490  {
491  case FREERDP_KEY_PARAM_RSA_D:
492 #if OPENSSL_VERSION_NUMBER >= 0x10101007L
493  cbn = RSA_get0_d(rsa);
494 #endif
495  break;
496  case FREERDP_KEY_PARAM_RSA_E:
497 #if OPENSSL_VERSION_NUMBER >= 0x10101007L
498  cbn = RSA_get0_e(rsa);
499 #endif
500  break;
501  case FREERDP_KEY_PARAM_RSA_N:
502 #if OPENSSL_VERSION_NUMBER >= 0x10101007L
503  cbn = RSA_get0_n(rsa);
504 #endif
505  break;
506  default:
507  return NULL;
508  }
509  if (!cbn)
510  return NULL;
511  bn = BN_dup(cbn);
512  if (!bn)
513  return NULL;
514  }
515 #endif
516 
517  const int length = BN_num_bytes(bn);
518  if (length < 0)
519  goto fail;
520 
521  const size_t alloc_size = (size_t)length + 1ull;
522  buf = calloc(alloc_size, sizeof(BYTE));
523  if (!buf)
524  goto fail;
525 
526  const int bnlen = BN_bn2bin(bn, buf);
527  if (bnlen != length)
528  {
529  free(buf);
530  buf = NULL;
531  }
532  else
533  *plength = length;
534 
535 fail:
536  BN_free(bn);
537  return buf;
538 }
539 
540 WINPR_DIGEST_CTX* freerdp_key_digest_sign(rdpPrivateKey* key, WINPR_MD_TYPE digest)
541 {
542  WINPR_DIGEST_CTX* md_ctx = winpr_Digest_New();
543  if (!md_ctx)
544  return NULL;
545 
546  if (!winpr_DigestSign_Init(md_ctx, digest, key->evp))
547  {
548  winpr_Digest_Free(md_ctx);
549  return NULL;
550  }
551  return md_ctx;
552 }