2 * FreeRDP: A Remote Desktop Protocol Client
5 * Copyright 2011 Jiten Pathy
6 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
25 #include <openssl/pem.h>
26 #include <openssl/rsa.h>
28 #include <freerdp/utils/file.h>
30 static const char certificate_store_dir[] = "certs";
31 static const char certificate_known_hosts_file[] = "known_hosts";
33 #include "certificate.h"
37 * X.509 Certificate Structure
39 * Certificate ::= SEQUENCE
41 * tbsCertificate TBSCertificate,
42 * signatureAlgorithm AlgorithmIdentifier,
43 * signatureValue BIT_STRING
46 * TBSCertificate ::= SEQUENCE
48 * version [0] EXPLICIT Version DEFAULT v1,
49 * serialNumber CertificateSerialNumber,
50 * signature AlgorithmIdentifier,
54 * subjectPublicKeyInfo SubjectPublicKeyInfo,
55 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
56 * subjectUniqueId [2] IMPLICIT UniqueIdentifier OPTIONAL,
57 * extensions [3] EXPLICIT Extensions OPTIONAL
60 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
62 * CertificateSerialNumber ::= INTEGER
64 * AlgorithmIdentifier ::= SEQUENCE
66 * algorithm OBJECT_IDENTIFIER,
67 * parameters ANY DEFINED BY algorithm OPTIONAL
70 * Name ::= CHOICE { RDNSequence }
72 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
74 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
76 * AttributeTypeAndValue ::= SEQUENCE
79 * value AttributeValue
82 * AttributeType ::= OBJECT_IDENTIFIER
84 * AttributeValue ::= ANY DEFINED BY AttributeType
86 * Validity ::= SEQUENCE
95 * generalTime GeneralizedTime
98 * UniqueIdentifier ::= BIT_STRING
100 * SubjectPublicKeyInfo ::= SEQUENCE
102 * algorithm AlgorithmIdentifier,
103 * subjectPublicKey BIT_STRING
106 * RSAPublicKey ::= SEQUENCE
109 * publicExponent INTEGER
112 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
114 * Extension ::= SEQUENCE
116 * extnID OBJECT_IDENTIFIER
117 * critical BOOLEAN DEFAULT FALSE,
118 * extnValue OCTET_STRING
124 * Read X.509 Certificate
125 * @param certificate certificate module
126 * @param cert X.509 certificate
129 void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
139 stream_attach(s, cert->data, cert->length);
141 ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */
143 ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */
145 /* Explicit Contextual Tag [0] */
146 ber_read_contextual_tag(s, 0, &length, true);
147 ber_read_integer(s, &version); /* version (INTEGER) */
151 ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */
154 ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
155 stream_seek(s, length);
158 ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
159 stream_seek(s, length);
162 ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */
163 stream_seek(s, length);
166 ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
167 stream_seek(s, length);
169 /* subjectPublicKeyInfo */
170 ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */
172 /* subjectPublicKeyInfo::AlgorithmIdentifier */
173 ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
174 stream_seek(s, length);
176 /* subjectPublicKeyInfo::subjectPublicKey */
177 ber_read_bit_string(s, &length, &padding); /* BIT_STRING */
179 /* RSAPublicKey (SEQUENCE) */
180 ber_read_sequence_tag(s, &length); /* SEQUENCE */
182 ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */
184 /* skip zero padding, if any */
187 stream_peek_uint8(s, padding);
195 while (padding == 0);
197 freerdp_blob_alloc(&info->modulus, modulus_length);
198 stream_read(s, info->modulus.data, modulus_length);
200 ber_read_integer_length(s, &exponent_length); /* publicExponent (INTEGER) */
201 stream_read(s, &info->exponent[4 - exponent_length], exponent_length);
202 crypto_reverse(info->modulus.data, modulus_length);
203 crypto_reverse(info->exponent, 4);
210 * Instantiate new X.509 Certificate Chain.
211 * @param count certificate chain count
212 * @return new X.509 certificate chain
215 rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count)
217 rdpX509CertChain* x509_cert_chain;
219 x509_cert_chain = (rdpX509CertChain*) xmalloc(sizeof(rdpX509CertChain));
221 x509_cert_chain->count = count;
222 x509_cert_chain->array = (rdpCertBlob*) xzalloc(sizeof(rdpCertBlob) * count);
224 return x509_cert_chain;
228 * Free X.509 Certificate Chain.
229 * @param x509_cert_chain X.509 certificate chain to be freed
232 void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain)
236 if (x509_cert_chain != NULL)
238 for (i = 0; i < (int) x509_cert_chain->count; i++)
240 if (x509_cert_chain->array[i].data != NULL)
241 xfree(x509_cert_chain->array[i].data);
244 xfree(x509_cert_chain->array);
245 xfree(x509_cert_chain);
249 static boolean certificate_process_server_public_key(rdpCertificate* certificate, STREAM* s, uint32 length)
257 stream_read(s, magic, 4);
258 if (memcmp(magic, "RSA1", 4) != 0)
260 printf("gcc_process_server_public_key: magic error\n");
264 stream_read_uint32(s, keylen);
265 stream_read_uint32(s, bitlen);
266 stream_read_uint32(s, datalen);
267 stream_read(s, certificate->cert_info.exponent, 4);
269 freerdp_blob_alloc(&(certificate->cert_info.modulus), modlen);
270 stream_read(s, certificate->cert_info.modulus.data, modlen);
271 /* 8 bytes of zero padding */
277 static boolean certificate_process_server_public_signature(rdpCertificate* certificate, uint8* sigdata, int sigdatalen, STREAM* s, uint32 siglen)
279 uint8 md5hash[CRYPTO_MD5_DIGEST_LENGTH];
280 uint8 encsig[TSSK_KEY_LENGTH + 8];
281 uint8 sig[TSSK_KEY_LENGTH];
285 md5ctx = crypto_md5_init();
286 crypto_md5_update(md5ctx, sigdata, sigdatalen);
287 crypto_md5_final(md5ctx, md5hash);
289 stream_read(s, encsig, siglen);
291 /* Last 8 bytes shall be all zero. */
293 for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++)
298 printf("certificate_process_server_public_signature: invalid signature\n");
304 crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
306 /* Verify signature. */
307 if (memcmp(md5hash, sig, sizeof(md5hash)) != 0)
309 printf("certificate_process_server_public_signature: invalid signature\n");
314 * Verify rest of decrypted data:
315 * The 17th byte is 0x00.
316 * The 18th through 62nd bytes are each 0xFF.
317 * The 63rd byte is 0x01.
320 for (sum = 0, i = 17; i < 62; i++)
323 if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
325 printf("certificate_process_server_public_signature: invalid signature\n");
333 * Read a Server Proprietary Certificate.\n
334 * @param certificate certificate module
338 boolean certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s)
342 uint32 wPublicKeyBlobType;
343 uint32 wPublicKeyBlobLen;
344 uint32 wSignatureBlobType;
345 uint32 wSignatureBlobLen;
349 /* -4, because we need to include dwVersion */
350 sigdata = stream_get_tail(s) - 4;
351 stream_read_uint32(s, dwSigAlgId);
352 stream_read_uint32(s, dwKeyAlgId);
353 if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA))
355 printf("certificate_read_server_proprietary_certificate: parse error 1\n");
358 stream_read_uint16(s, wPublicKeyBlobType);
359 if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
361 printf("certificate_read_server_proprietary_certificate: parse error 2\n");
364 stream_read_uint16(s, wPublicKeyBlobLen);
365 if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen))
367 printf("certificate_read_server_proprietary_certificate: parse error 3\n");
370 sigdatalen = stream_get_tail(s) - sigdata;
371 stream_read_uint16(s, wSignatureBlobType);
372 if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
374 printf("certificate_read_server_proprietary_certificate: parse error 4\n");
377 stream_read_uint16(s, wSignatureBlobLen);
378 if (wSignatureBlobLen != 72)
380 printf("certificate_process_server_public_signature: invalid signature length (got %d, expected %d)\n", wSignatureBlobLen, 64);
383 if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s, wSignatureBlobLen))
385 printf("certificate_read_server_proprietary_certificate: parse error 5\n");
393 * Read an X.509 Certificate Chain.\n
394 * @param certificate certificate module
398 boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s)
404 DEBUG_CERTIFICATE("Server X.509 Certificate Chain");
406 stream_read_uint32(s, numCertBlobs); /* numCertBlobs */
408 certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs);
410 for (i = 0; i < (int) numCertBlobs; i++)
412 stream_read_uint32(s, certLength);
414 DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength);
416 certificate->x509_cert_chain->array[i].data = (uint8*) xmalloc(certLength);
417 stream_read(s, certificate->x509_cert_chain->array[i].data, certLength);
418 certificate->x509_cert_chain->array[i].length = certLength;
420 if (numCertBlobs - i == 2)
422 rdpCertInfo cert_info;
423 DEBUG_CERTIFICATE("License Server Certificate");
424 certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &cert_info);
425 DEBUG_LICENSE("modulus length:%d", cert_info.modulus.length);
426 freerdp_blob_free(&cert_info.modulus);
428 else if (numCertBlobs - i == 1)
430 DEBUG_CERTIFICATE("Terminal Server Certificate");
431 certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &certificate->cert_info);
432 DEBUG_CERTIFICATE("modulus length:%d", certificate->cert_info.modulus.length);
440 * Read a Server Certificate.\n
441 * @param certificate certificate module
442 * @param server_cert server certificate
443 * @param length certificate length
446 boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length)
452 stream_attach(s, server_cert, length);
456 printf("null server certificate\n");
460 stream_read_uint32(s, dwVersion); /* dwVersion (4 bytes) */
462 switch (dwVersion & CERT_CHAIN_VERSION_MASK)
464 case CERT_CHAIN_VERSION_1:
465 certificate_read_server_proprietary_certificate(certificate, s);
468 case CERT_CHAIN_VERSION_2:
469 certificate_read_server_x509_certificate_chain(certificate, s);
473 printf("invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK);
481 rdpKey* key_new(const char* keyfile)
487 key = (rdpKey*) xzalloc(sizeof(rdpKey));
492 fp = fopen(keyfile, "r");
496 printf("unable to load RSA key from %s: %s.", keyfile, strerror(errno));
500 rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
504 ERR_print_errors_fp(stdout);
511 switch (RSA_check_key(rsa))
515 printf("invalid RSA key in %s", keyfile);
523 ERR_print_errors_fp(stdout);
528 if (BN_num_bytes(rsa->e) > 4)
531 printf("RSA public exponent too large in %s", keyfile);
535 freerdp_blob_alloc(&key->modulus, BN_num_bytes(rsa->n));
536 BN_bn2bin(rsa->n, key->modulus.data);
537 crypto_reverse(key->modulus.data, key->modulus.length);
538 freerdp_blob_alloc(&key->private_exponent, BN_num_bytes(rsa->d));
539 BN_bn2bin(rsa->d, key->private_exponent.data);
540 crypto_reverse(key->private_exponent.data, key->private_exponent.length);
541 memset(key->exponent, 0, sizeof(key->exponent));
542 BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
543 crypto_reverse(key->exponent, sizeof(key->exponent));
550 void key_free(rdpKey* key)
554 freerdp_blob_free(&key->modulus);
555 freerdp_blob_free(&key->private_exponent);
560 void certificate_store_init(rdpCertificateStore* certificate_store)
563 rdpSettings* settings;
565 settings = certificate_store->settings;
567 config_path = freerdp_get_config_path(settings);
568 certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_dir);
570 if (freerdp_check_file_exists(certificate_store->path) == false)
572 freerdp_mkdir(certificate_store->path);
573 printf("creating directory %s\n", certificate_store->path);
576 certificate_store->file = freerdp_construct_path(config_path, (char*) certificate_known_hosts_file);
578 if (freerdp_check_file_exists(certificate_store->file) == false)
580 certificate_store->fp = fopen((char*) certificate_store->file, "w+");
582 if (certificate_store->fp == NULL)
584 printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
588 fflush(certificate_store->fp);
592 certificate_store->fp = fopen((char*) certificate_store->file, "r+");
596 int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
605 fp = certificate_store->fp;
610 fseek(fp, 0, SEEK_END);
612 fseek(fp, 0, SEEK_SET);
617 data = (char*) xmalloc(size + 2);
619 if (fread(data, size, 1, fp) != 1)
626 data[size + 1] = '\0';
627 pline = strtok(data, "\n");
629 while (pline != NULL)
631 length = strlen(pline);
635 length = strcspn(pline, " \t");
636 pline[length] = '\0';
638 if (strcmp(pline, certificate_data->hostname) == 0)
640 pline = &pline[length + 1];
642 if (strcmp(pline, certificate_data->fingerprint) == 0)
650 pline = strtok(NULL, "\n");
657 void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
661 /* reopen in append mode */
662 fp = fopen(certificate_store->file, "a");
667 fprintf(certificate_store->fp,"%s %s\n", certificate_data->hostname, certificate_data->fingerprint);
671 rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint)
673 rdpCertificateData* certdata;
675 certdata = (rdpCertificateData*) xzalloc(sizeof(rdpCertificateData));
677 if (certdata != NULL)
679 certdata->hostname = xstrdup(hostname);
680 certdata->fingerprint = xstrdup(fingerprint);
686 void certificate_data_free(rdpCertificateData* certificate_data)
688 if (certificate_data != NULL)
690 xfree(certificate_data->hostname);
691 xfree(certificate_data->fingerprint);
692 xfree(certificate_data);
696 rdpCertificateStore* certificate_store_new(rdpSettings* settings)
698 rdpCertificateStore* certificate_store;
700 certificate_store = (rdpCertificateStore*) xzalloc(sizeof(rdpCertificateStore));
702 if (certificate_store != NULL)
704 certificate_store->settings = settings;
705 certificate_store_init(certificate_store);
708 return certificate_store;
711 void certificate_store_free(rdpCertificateStore* certstore)
713 if (certstore != NULL)
715 if (certstore->fp != NULL)
716 fclose(certstore->fp);
718 xfree(certstore->path);
719 xfree(certstore->file);
725 * Instantiate new certificate module.\n
726 * @param rdp RDP module
727 * @return new certificate module
730 rdpCertificate* certificate_new()
732 rdpCertificate* certificate;
734 certificate = (rdpCertificate*) xzalloc(sizeof(rdpCertificate));
736 if (certificate != NULL)
738 certificate->x509_cert_chain = NULL;
745 * Free certificate module.
746 * @param certificate certificate module to be freed
749 void certificate_free(rdpCertificate* certificate)
751 if (certificate != NULL)
753 certificate_free_x509_certificate_chain(certificate->x509_cert_chain);
755 if (certificate->cert_info.modulus.data != NULL)
756 freerdp_blob_free(&(certificate->cert_info.modulus));