1 /**
2 * FreeRDP: A Remote Desktop Protocol Implementation
3 * Certificate 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 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <winpr/wtypes.h>
32 #include <winpr/crt.h>
33 #include <winpr/file.h>
34 #include <winpr/crypto.h>
35
36 #include <openssl/pem.h>
37 #include <openssl/rsa.h>
38
39 #include "certificate.h"
40 #include "../crypto/opensslcompat.h"
41
42 #define TAG "com.freerdp.core"
43
44 /**
45 *
46 * X.509 Certificate Structure
47 *
48 * Certificate ::= SEQUENCE
49 * {
50 * tbsCertificate TBSCertificate,
51 * signatureAlgorithm AlgorithmIdentifier,
52 * signatureValue BIT_STRING
53 * }
54 *
55 * TBSCertificate ::= SEQUENCE
56 * {
57 * version [0] EXPLICIT Version DEFAULT v1,
58 * serialNumber CertificateSerialNumber,
59 * signature AlgorithmIdentifier,
60 * issuer Name,
61 * validity Validity,
62 * subject Name,
63 * subjectPublicKeyInfo SubjectPublicKeyInfo,
64 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
65 * subjectUniqueId [2] IMPLICIT UniqueIdentifier OPTIONAL,
66 * extensions [3] EXPLICIT Extensions OPTIONAL
67 * }
68 *
69 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
70 *
71 * CertificateSerialNumber ::= INTEGER
72 *
73 * AlgorithmIdentifier ::= SEQUENCE
74 * {
75 * algorithm OBJECT_IDENTIFIER,
76 * parameters ANY DEFINED BY algorithm OPTIONAL
77 * }
78 *
79 * Name ::= CHOICE { RDNSequence }
80 *
81 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
82 *
83 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
84 *
85 * AttributeTypeAndValue ::= SEQUENCE
86 * {
87 * type AttributeType,
88 * value AttributeValue
89 * }
90 *
91 * AttributeType ::= OBJECT_IDENTIFIER
92 *
93 * AttributeValue ::= ANY DEFINED BY AttributeType
94 *
95 * Validity ::= SEQUENCE
96 * {
97 * notBefore Time,
98 * notAfter Time
99 * }
100 *
101 * Time ::= CHOICE
102 * {
103 * utcTime UTCTime,
104 * generalTime GeneralizedTime
105 * }
106 *
107 * UniqueIdentifier ::= BIT_STRING
108 *
109 * SubjectPublicKeyInfo ::= SEQUENCE
110 * {
111 * algorithm AlgorithmIdentifier,
112 * subjectPublicKey BIT_STRING
113 * }
114 *
115 * RSAPublicKey ::= SEQUENCE
116 * {
117 * modulus INTEGER
118 * publicExponent INTEGER
119 * }
120 *
121 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
122 *
123 * Extension ::= SEQUENCE
124 * {
125 * extnID OBJECT_IDENTIFIER
126 * critical BOOLEAN DEFAULT FALSE,
127 * extnValue OCTET_STRING
128 * }
129 *
130 */
131
132 static const char* certificate_read_errors[] = { "Certificate tag",
133 "TBSCertificate",
134 "Explicit Contextual Tag [0]",
135 "version",
136 "CertificateSerialNumber",
137 "AlgorithmIdentifier",
138 "Issuer Name",
139 "Validity",
140 "Subject Name",
141 "SubjectPublicKeyInfo Tag",
142 "subjectPublicKeyInfo::AlgorithmIdentifier",
143 "subjectPublicKeyInfo::subjectPublicKey",
144 "RSAPublicKey Tag",
145 "modulusLength",
146 "zero padding",
147 "modulusLength",
148 "modulus",
149 "publicExponent length",
150 "publicExponent" };
151
152 /**
153 * Read X.509 Certificate
154 * @param certificate certificate module
155 * @param cert X.509 certificate
156 */
157
certificate_read_x509_certificate(rdpCertBlob * cert,rdpCertInfo * info)158 static BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
159 {
160 wStream* s;
161 size_t length;
162 BYTE padding;
163 UINT32 version;
164 size_t modulus_length;
165 size_t exponent_length;
166 int error = 0;
167
168 if (!cert || !info)
169 return FALSE;
170
171 memset(info, 0, sizeof(rdpCertInfo));
172 s = Stream_New(cert->data, cert->length);
173
174 if (!s)
175 return FALSE;
176
177 info->Modulus = 0;
178
179 if (!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */
180 goto error1;
181
182 error++;
183
184 if (!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */
185 goto error1;
186
187 error++;
188
189 if (!ber_read_contextual_tag(s, 0, &length, TRUE)) /* Explicit Contextual Tag [0] */
190 goto error1;
191
192 error++;
193
194 if (!ber_read_integer(s, &version)) /* version (INTEGER) */
195 goto error1;
196
197 error++;
198 version++;
199
200 /* serialNumber */
201 if (!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */
202 goto error1;
203
204 error++;
205
206 /* signature */
207 if (!ber_read_sequence_tag(s, &length) ||
208 !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
209 goto error1;
210
211 error++;
212
213 /* issuer */
214 if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
215 goto error1;
216
217 error++;
218
219 /* validity */
220 if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Validity (SEQUENCE) */
221 goto error1;
222
223 error++;
224
225 /* subject */
226 if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
227 goto error1;
228
229 error++;
230
231 /* subjectPublicKeyInfo */
232 if (!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */
233 goto error1;
234
235 error++;
236
237 /* subjectPublicKeyInfo::AlgorithmIdentifier */
238 if (!ber_read_sequence_tag(s, &length) ||
239 !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
240 goto error1;
241
242 error++;
243
244 /* subjectPublicKeyInfo::subjectPublicKey */
245 if (!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */
246 goto error1;
247
248 error++;
249
250 /* RSAPublicKey (SEQUENCE) */
251 if (!ber_read_sequence_tag(s, &length)) /* SEQUENCE */
252 goto error1;
253
254 error++;
255
256 if (!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */
257 goto error1;
258
259 error++;
260
261 /* skip zero padding, if any */
262 do
263 {
264 if (Stream_GetRemainingLength(s) < 1)
265 goto error1;
266
267 Stream_Peek_UINT8(s, padding);
268
269 if (padding == 0)
270 {
271 if (!Stream_SafeSeek(s, 1))
272 goto error1;
273
274 modulus_length--;
275 }
276 } while (padding == 0);
277
278 error++;
279
280 if (modulus_length > UINT32_MAX)
281 goto error1;
282
283 if ((Stream_GetRemainingLength(s)) < modulus_length)
284 goto error1;
285
286 info->ModulusLength = (UINT32)modulus_length;
287 info->Modulus = (BYTE*)malloc(info->ModulusLength);
288
289 if (!info->Modulus)
290 goto error1;
291
292 Stream_Read(s, info->Modulus, info->ModulusLength);
293 error++;
294
295 if (!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */
296 goto error2;
297
298 error++;
299
300 if (((Stream_GetRemainingLength(s)) < exponent_length) || (exponent_length > 4))
301 goto error2;
302
303 Stream_Read(s, &info->exponent[4 - exponent_length], exponent_length);
304 crypto_reverse(info->Modulus, info->ModulusLength);
305 crypto_reverse(info->exponent, 4);
306 Stream_Free(s, FALSE);
307 return TRUE;
308 error2:
309 free(info->Modulus);
310 info->Modulus = 0;
311 error1:
312 WLog_ERR(TAG, "error reading when reading certificate: part=%s error=%d",
313 certificate_read_errors[error], error);
314 Stream_Free(s, FALSE);
315 return FALSE;
316 }
317
318 /**
319 * Instantiate new X.509 Certificate Chain.
320 * @param count certificate chain count
321 * @return new X.509 certificate chain
322 */
323
certificate_new_x509_certificate_chain(UINT32 count)324 static rdpX509CertChain* certificate_new_x509_certificate_chain(UINT32 count)
325 {
326 rdpX509CertChain* x509_cert_chain;
327 x509_cert_chain = (rdpX509CertChain*)malloc(sizeof(rdpX509CertChain));
328
329 if (!x509_cert_chain)
330 return NULL;
331
332 x509_cert_chain->count = count;
333 x509_cert_chain->array = (rdpCertBlob*)calloc(count, sizeof(rdpCertBlob));
334
335 if (!x509_cert_chain->array)
336 {
337 free(x509_cert_chain);
338 return NULL;
339 }
340
341 return x509_cert_chain;
342 }
343
344 /**
345 * Free X.509 Certificate Chain.
346 * @param x509_cert_chain X.509 certificate chain to be freed
347 */
348
certificate_free_x509_certificate_chain(rdpX509CertChain * x509_cert_chain)349 static void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain)
350 {
351 int i;
352
353 if (!x509_cert_chain)
354 return;
355
356 for (i = 0; i < (int)x509_cert_chain->count; i++)
357 {
358 free(x509_cert_chain->array[i].data);
359 }
360
361 free(x509_cert_chain->array);
362 free(x509_cert_chain);
363 }
364
certificate_process_server_public_key(rdpCertificate * certificate,wStream * s,UINT32 length)365 static BOOL certificate_process_server_public_key(rdpCertificate* certificate, wStream* s,
366 UINT32 length)
367 {
368 BYTE magic[4];
369 UINT32 keylen;
370 UINT32 bitlen;
371 UINT32 datalen;
372
373 if (Stream_GetRemainingLength(s) < 20)
374 return FALSE;
375
376 Stream_Read(s, magic, 4);
377
378 if (memcmp(magic, "RSA1", 4) != 0)
379 {
380 WLog_ERR(TAG, "magic error");
381 return FALSE;
382 }
383
384 Stream_Read_UINT32(s, keylen);
385 Stream_Read_UINT32(s, bitlen);
386 Stream_Read_UINT32(s, datalen);
387 Stream_Read(s, certificate->cert_info.exponent, 4);
388
389 if ((keylen <= 8) || (Stream_GetRemainingLength(s) < keylen))
390 return FALSE;
391
392 certificate->cert_info.ModulusLength = keylen - 8;
393 certificate->cert_info.Modulus = malloc(certificate->cert_info.ModulusLength);
394
395 if (!certificate->cert_info.Modulus)
396 return FALSE;
397
398 Stream_Read(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength);
399 Stream_Seek(s, 8); /* 8 bytes of zero padding */
400 return TRUE;
401 }
402
certificate_process_server_public_signature(rdpCertificate * certificate,const BYTE * sigdata,size_t sigdatalen,wStream * s,UINT32 siglen)403 static BOOL certificate_process_server_public_signature(rdpCertificate* certificate,
404 const BYTE* sigdata, size_t sigdatalen,
405 wStream* s, UINT32 siglen)
406 {
407 #if defined(CERT_VALIDATE_PADDING) || defined(CERT_VALIDATE_RSA)
408 size_t i, sum;
409 #endif
410 #if defined(CERT_VALIDATE_RSA)
411 BYTE sig[TSSK_KEY_LENGTH];
412 #endif
413 BYTE encsig[TSSK_KEY_LENGTH + 8];
414 #if defined(CERT_VALIDATE_MD5) && defined(CERT_VALIDATE_RSA)
415 BYTE md5hash[WINPR_MD5_DIGEST_LENGTH];
416 #endif
417 #if !defined(CERT_VALIDATE_MD5) || !defined(CERT_VALIDATE_RSA)
418 (void)sigdata;
419 (void)sigdatalen;
420 #endif
421 (void)certificate;
422 /* Do not bother with validation of server proprietary certificate. The use of MD5 here is not
423 * allowed under FIPS. Since the validation is not protecting against anything since the
424 * private/public keys are well known and documented in MS-RDPBCGR section 5.3.3.1, we are not
425 * gaining any security by using MD5 for signature comparison. Rather then use MD5
426 * here we just dont do the validation to avoid its use. Historically, freerdp has been ignoring
427 * a failed validation anyways. */
428 #if defined(CERT_VALIDATE_MD5)
429
430 if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash, sizeof(md5hash)))
431 return FALSE;
432
433 #endif
434 Stream_Read(s, encsig, siglen);
435
436 if (siglen < 8)
437 return FALSE;
438
439 /* Last 8 bytes shall be all zero. */
440 #if defined(CERT_VALIDATE_PADDING)
441
442 for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++)
443 sum += encsig[i];
444
445 if (sum != 0)
446 {
447 WLog_ERR(TAG, "invalid signature");
448 return FALSE;
449 }
450
451 #endif
452 #if defined(CERT_VALIDATE_RSA)
453
454 if (crypto_rsa_public_decrypt(encsig, siglen - 8, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent,
455 sig) <= 0)
456 {
457 WLog_ERR(TAG, "invalid RSA decrypt");
458 return FALSE;
459 }
460
461 /* Verify signature. */
462 /* Do not bother with validation of server proprietary certificate as described above. */
463 #if defined(CERT_VALIDATE_MD5)
464
465 if (memcmp(md5hash, sig, sizeof(md5hash)) != 0)
466 {
467 WLog_ERR(TAG, "invalid signature");
468 return FALSE;
469 }
470
471 #endif
472 /*
473 * Verify rest of decrypted data:
474 * The 17th byte is 0x00.
475 * The 18th through 62nd bytes are each 0xFF.
476 * The 63rd byte is 0x01.
477 */
478
479 for (sum = 0, i = 17; i < 62; i++)
480 sum += sig[i];
481
482 if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
483 {
484 WLog_ERR(TAG, "invalid signature");
485 return FALSE;
486 }
487
488 #endif
489 return TRUE;
490 }
491
492 /**
493 * Read a Server Proprietary Certificate.\n
494 * @param certificate certificate module
495 * @param s stream
496 */
497
certificate_read_server_proprietary_certificate(rdpCertificate * certificate,wStream * s)498 static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate, wStream* s)
499 {
500 UINT32 dwSigAlgId;
501 UINT32 dwKeyAlgId;
502 UINT16 wPublicKeyBlobType;
503 UINT16 wPublicKeyBlobLen;
504 UINT16 wSignatureBlobType;
505 UINT16 wSignatureBlobLen;
506 BYTE* sigdata;
507 size_t sigdatalen;
508
509 if (Stream_GetRemainingLength(s) < 12)
510 return FALSE;
511
512 /* -4, because we need to include dwVersion */
513 sigdata = Stream_Pointer(s) - 4;
514 Stream_Read_UINT32(s, dwSigAlgId);
515 Stream_Read_UINT32(s, dwKeyAlgId);
516
517 if (!((dwSigAlgId == SIGNATURE_ALG_RSA) && (dwKeyAlgId == KEY_EXCHANGE_ALG_RSA)))
518 {
519 WLog_ERR(TAG,
520 "unsupported signature or key algorithm, dwSigAlgId=%" PRIu32
521 " dwKeyAlgId=%" PRIu32 "",
522 dwSigAlgId, dwKeyAlgId);
523 return FALSE;
524 }
525
526 Stream_Read_UINT16(s, wPublicKeyBlobType);
527
528 if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
529 {
530 WLog_ERR(TAG, "unsupported public key blob type %" PRIu16 "", wPublicKeyBlobType);
531 return FALSE;
532 }
533
534 Stream_Read_UINT16(s, wPublicKeyBlobLen);
535
536 if (Stream_GetRemainingLength(s) < wPublicKeyBlobLen)
537 {
538 WLog_ERR(TAG, "not enough bytes for public key(len=%" PRIu16 ")", wPublicKeyBlobLen);
539 return FALSE;
540 }
541
542 if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen))
543 {
544 WLog_ERR(TAG, "error in server public key");
545 return FALSE;
546 }
547
548 if (Stream_GetRemainingLength(s) < 4)
549 return FALSE;
550
551 sigdatalen = Stream_Pointer(s) - sigdata;
552 Stream_Read_UINT16(s, wSignatureBlobType);
553
554 if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
555 {
556 WLog_ERR(TAG, "unsupported blob signature %" PRIu16 "", wSignatureBlobType);
557 return FALSE;
558 }
559
560 Stream_Read_UINT16(s, wSignatureBlobLen);
561
562 if (Stream_GetRemainingLength(s) < wSignatureBlobLen)
563 {
564 WLog_ERR(TAG, "not enough bytes for signature(len=%" PRIu16 ")", wSignatureBlobLen);
565 return FALSE;
566 }
567
568 if (wSignatureBlobLen != 72)
569 {
570 WLog_ERR(TAG, "invalid signature length (got %" PRIu16 ", expected 72)", wSignatureBlobLen);
571 return FALSE;
572 }
573
574 if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s,
575 wSignatureBlobLen))
576 {
577 WLog_ERR(TAG, "unable to parse server public signature");
578 return FALSE;
579 }
580
581 return TRUE;
582 }
583
584 /**
585 * Read an X.509 Certificate Chain.\n
586 * @param certificate certificate module
587 * @param s stream
588 */
589
certificate_read_server_x509_certificate_chain(rdpCertificate * certificate,wStream * s)590 static BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s)
591 {
592 UINT32 i;
593 BOOL ret;
594 UINT32 certLength;
595 UINT32 numCertBlobs;
596 DEBUG_CERTIFICATE("Server X.509 Certificate Chain");
597
598 if (Stream_GetRemainingLength(s) < 4)
599 return FALSE;
600
601 Stream_Read_UINT32(s, numCertBlobs); /* numCertBlobs */
602 certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs);
603
604 if (!certificate->x509_cert_chain)
605 return FALSE;
606
607 for (i = 0; i < numCertBlobs; i++)
608 {
609 if (Stream_GetRemainingLength(s) < 4)
610 return FALSE;
611
612 Stream_Read_UINT32(s, certLength);
613
614 if (Stream_GetRemainingLength(s) < certLength)
615 return FALSE;
616
617 DEBUG_CERTIFICATE("X.509 Certificate #%d, length:%" PRIu32 "", i + 1, certLength);
618 certificate->x509_cert_chain->array[i].data = (BYTE*)malloc(certLength);
619
620 if (!certificate->x509_cert_chain->array[i].data)
621 return FALSE;
622
623 Stream_Read(s, certificate->x509_cert_chain->array[i].data, certLength);
624 certificate->x509_cert_chain->array[i].length = certLength;
625
626 if ((numCertBlobs - i) == 2)
627 {
628 rdpCertInfo cert_info = { 0 };
629 DEBUG_CERTIFICATE("License Server Certificate");
630 ret = certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i],
631 &cert_info);
632 DEBUG_LICENSE("modulus length:%" PRIu32 "", cert_info.ModulusLength);
633 free(cert_info.Modulus);
634
635 if (!ret)
636 {
637 WLog_ERR(TAG, "failed to read License Server, content follows:");
638 winpr_HexDump(TAG, WLOG_ERROR, certificate->x509_cert_chain->array[i].data,
639 certificate->x509_cert_chain->array[i].length);
640 return FALSE;
641 }
642 }
643 else if (numCertBlobs - i == 1)
644 {
645 DEBUG_CERTIFICATE("Terminal Server Certificate");
646
647 if (!certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i],
648 &certificate->cert_info))
649 return FALSE;
650
651 DEBUG_CERTIFICATE("modulus length:%" PRIu32 "", certificate->cert_info.ModulusLength);
652 }
653 }
654
655 return TRUE;
656 }
657
658 /**
659 * Read a Server Certificate.\n
660 * @param certificate certificate module
661 * @param server_cert server certificate
662 * @param length certificate length
663 */
664
certificate_read_server_certificate(rdpCertificate * certificate,BYTE * server_cert,size_t length)665 BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert,
666 size_t length)
667 {
668 BOOL ret;
669 wStream* s;
670 UINT32 dwVersion;
671
672 if (length < 4) /* NULL certificate is not an error see #1795 */
673 return TRUE;
674
675 s = Stream_New(server_cert, length);
676
677 if (!s)
678 {
679 WLog_ERR(TAG, "Stream_New failed!");
680 return FALSE;
681 }
682
683 Stream_Read_UINT32(s, dwVersion); /* dwVersion (4 bytes) */
684
685 switch (dwVersion & CERT_CHAIN_VERSION_MASK)
686 {
687 case CERT_CHAIN_VERSION_1:
688 ret = certificate_read_server_proprietary_certificate(certificate, s);
689 break;
690
691 case CERT_CHAIN_VERSION_2:
692 ret = certificate_read_server_x509_certificate_chain(certificate, s);
693 break;
694
695 default:
696 WLog_ERR(TAG, "invalid certificate chain version:%" PRIu32 "",
697 dwVersion & CERT_CHAIN_VERSION_MASK);
698 ret = FALSE;
699 break;
700 }
701
702 Stream_Free(s, FALSE);
703 return ret;
704 }
705
key_new_from_content(const char * keycontent,const char * keyfile)706 rdpRsaKey* key_new_from_content(const char* keycontent, const char* keyfile)
707 {
708 BIO* bio = NULL;
709 RSA* rsa = NULL;
710 rdpRsaKey* key = NULL;
711 const BIGNUM* rsa_e = NULL;
712 const BIGNUM* rsa_n = NULL;
713 const BIGNUM* rsa_d = NULL;
714 key = (rdpRsaKey*)calloc(1, sizeof(rdpRsaKey));
715
716 if (!key)
717 return NULL;
718
719 bio = BIO_new_mem_buf((void*)keycontent, strlen(keycontent));
720
721 if (!bio)
722 goto out_free;
723
724 rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
725 BIO_free_all(bio);
726
727 if (!rsa)
728 {
729 WLog_ERR(TAG, "unable to load RSA key from %s: %s.", keyfile, strerror(errno));
730 goto out_free;
731 }
732
733 switch (RSA_check_key(rsa))
734 {
735 case 0:
736 WLog_ERR(TAG, "invalid RSA key in %s", keyfile);
737 goto out_free_rsa;
738
739 case 1:
740 /* Valid key. */
741 break;
742
743 default:
744 WLog_ERR(TAG, "unexpected error when checking RSA key from %s: %s.", keyfile,
745 strerror(errno));
746 goto out_free_rsa;
747 }
748
749 RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
750
751 if (BN_num_bytes(rsa_e) > 4)
752 {
753 WLog_ERR(TAG, "RSA public exponent too large in %s", keyfile);
754 goto out_free_rsa;
755 }
756
757 key->ModulusLength = BN_num_bytes(rsa_n);
758 key->Modulus = (BYTE*)malloc(key->ModulusLength);
759
760 if (!key->Modulus)
761 goto out_free_rsa;
762
763 BN_bn2bin(rsa_n, key->Modulus);
764 crypto_reverse(key->Modulus, key->ModulusLength);
765 key->PrivateExponentLength = BN_num_bytes(rsa_d);
766 key->PrivateExponent = (BYTE*)malloc(key->PrivateExponentLength);
767
768 if (!key->PrivateExponent)
769 goto out_free_modulus;
770
771 BN_bn2bin(rsa_d, key->PrivateExponent);
772 crypto_reverse(key->PrivateExponent, key->PrivateExponentLength);
773 memset(key->exponent, 0, sizeof(key->exponent));
774 BN_bn2bin(rsa_e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa_e));
775 crypto_reverse(key->exponent, sizeof(key->exponent));
776 RSA_free(rsa);
777 return key;
778 out_free_modulus:
779 free(key->Modulus);
780 out_free_rsa:
781 RSA_free(rsa);
782 out_free:
783 free(key);
784 return NULL;
785 }
786
key_new(const char * keyfile)787 rdpRsaKey* key_new(const char* keyfile)
788 {
789 FILE* fp = NULL;
790 INT64 length;
791 char* buffer = NULL;
792 rdpRsaKey* key = NULL;
793 fp = winpr_fopen(keyfile, "rb");
794
795 if (!fp)
796 {
797 WLog_ERR(TAG, "unable to open RSA key file %s: %s.", keyfile, strerror(errno));
798 goto out_free;
799 }
800
801 if (_fseeki64(fp, 0, SEEK_END) < 0)
802 goto out_free;
803
804 if ((length = _ftelli64(fp)) < 0)
805 goto out_free;
806
807 if (_fseeki64(fp, 0, SEEK_SET) < 0)
808 goto out_free;
809
810 buffer = (char*)malloc(length + 1);
811
812 if (!buffer)
813 goto out_free;
814
815 if (fread((void*)buffer, length, 1, fp) != 1)
816 goto out_free;
817
818 fclose(fp);
819 buffer[length] = '\0';
820 key = key_new_from_content(buffer, keyfile);
821 free(buffer);
822 return key;
823 out_free:
824
825 if (fp)
826 fclose(fp);
827
828 free(buffer);
829 return NULL;
830 }
831
key_clone(const rdpRsaKey * key)832 rdpRsaKey* key_clone(const rdpRsaKey* key)
833 {
834 rdpRsaKey* _key = (rdpRsaKey*)calloc(1, sizeof(rdpRsaKey));
835
836 if (!_key)
837 return NULL;
838
839 CopyMemory(_key, key, sizeof(rdpRsaKey));
840
841 if (key->Modulus)
842 {
843 _key->Modulus = (BYTE*)malloc(key->ModulusLength);
844
845 if (!_key->Modulus)
846 goto out_fail;
847
848 CopyMemory(_key->Modulus, key->Modulus, key->ModulusLength);
849 }
850
851 if (key->PrivateExponent)
852 {
853 _key->PrivateExponent = (BYTE*)malloc(key->PrivateExponentLength);
854
855 if (!_key->PrivateExponent)
856 goto out_fail;
857
858 CopyMemory(_key->PrivateExponent, key->PrivateExponent, key->PrivateExponentLength);
859 }
860
861 return _key;
862 out_fail:
863 free(_key->Modulus);
864 free(_key->PrivateExponent);
865 free(_key);
866 return NULL;
867 }
868
key_free(rdpRsaKey * key)869 void key_free(rdpRsaKey* key)
870 {
871 if (!key)
872 return;
873
874 free(key->Modulus);
875 free(key->PrivateExponent);
876 free(key);
877 }
878
certificate_clone(rdpCertificate * certificate)879 rdpCertificate* certificate_clone(rdpCertificate* certificate)
880 {
881 UINT32 index;
882 rdpCertificate* _certificate = (rdpCertificate*)calloc(1, sizeof(rdpCertificate));
883
884 if (!_certificate)
885 return NULL;
886
887 CopyMemory(_certificate, certificate, sizeof(rdpCertificate));
888
889 if (certificate->cert_info.ModulusLength)
890 {
891 _certificate->cert_info.Modulus = (BYTE*)malloc(certificate->cert_info.ModulusLength);
892
893 if (!_certificate->cert_info.Modulus)
894 goto out_fail;
895
896 CopyMemory(_certificate->cert_info.Modulus, certificate->cert_info.Modulus,
897 certificate->cert_info.ModulusLength);
898 _certificate->cert_info.ModulusLength = certificate->cert_info.ModulusLength;
899 }
900
901 if (certificate->x509_cert_chain)
902 {
903 _certificate->x509_cert_chain = (rdpX509CertChain*)malloc(sizeof(rdpX509CertChain));
904
905 if (!_certificate->x509_cert_chain)
906 goto out_fail;
907
908 CopyMemory(_certificate->x509_cert_chain, certificate->x509_cert_chain,
909 sizeof(rdpX509CertChain));
910
911 if (certificate->x509_cert_chain->count)
912 {
913 _certificate->x509_cert_chain->array =
914 (rdpCertBlob*)calloc(certificate->x509_cert_chain->count, sizeof(rdpCertBlob));
915
916 if (!_certificate->x509_cert_chain->array)
917 goto out_fail;
918
919 for (index = 0; index < certificate->x509_cert_chain->count; index++)
920 {
921 _certificate->x509_cert_chain->array[index].length =
922 certificate->x509_cert_chain->array[index].length;
923
924 if (certificate->x509_cert_chain->array[index].length)
925 {
926 _certificate->x509_cert_chain->array[index].data =
927 (BYTE*)malloc(certificate->x509_cert_chain->array[index].length);
928
929 if (!_certificate->x509_cert_chain->array[index].data)
930 {
931 for (; index > 0; --index)
932 {
933 if (certificate->x509_cert_chain->array[index - 1].length)
934 free(_certificate->x509_cert_chain->array[index - 1].data);
935 }
936
937 goto out_fail;
938 }
939
940 CopyMemory(_certificate->x509_cert_chain->array[index].data,
941 certificate->x509_cert_chain->array[index].data,
942 _certificate->x509_cert_chain->array[index].length);
943 }
944 }
945 }
946 }
947
948 return _certificate;
949 out_fail:
950
951 if (_certificate->x509_cert_chain)
952 {
953 free(_certificate->x509_cert_chain->array);
954 free(_certificate->x509_cert_chain);
955 }
956
957 free(_certificate->cert_info.Modulus);
958 free(_certificate);
959 return NULL;
960 }
961
962 /**
963 * Instantiate new certificate module.\n
964 * @param rdp RDP module
965 * @return new certificate module
966 */
967
certificate_new(void)968 rdpCertificate* certificate_new(void)
969 {
970 return (rdpCertificate*)calloc(1, sizeof(rdpCertificate));
971 }
972
973 /**
974 * Free certificate module.
975 * @param certificate certificate module to be freed
976 */
977
certificate_free(rdpCertificate * certificate)978 void certificate_free(rdpCertificate* certificate)
979 {
980 if (!certificate)
981 return;
982
983 certificate_free_x509_certificate_chain(certificate->x509_cert_chain);
984 free(certificate->cert_info.Modulus);
985 free(certificate);
986 }
987