Fix changelog email address
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-core / certificate.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Certificate Handling
4  *
5  * Copyright 2011 Jiten Pathy
6  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7  *
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
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  */
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include <openssl/pem.h>
26 #include <openssl/rsa.h>
27
28 #include <freerdp/utils/file.h>
29
30 static const char certificate_store_dir[] = "certs";
31 static const char certificate_known_hosts_file[] = "known_hosts";
32
33 #include "certificate.h"
34
35 /**
36  *
37  * X.509 Certificate Structure
38  *
39  * Certificate ::= SEQUENCE
40  * {
41  *      tbsCertificate                  TBSCertificate,
42  *      signatureAlgorithm              AlgorithmIdentifier,
43  *      signatureValue                  BIT_STRING
44  * }
45  *
46  * TBSCertificate ::= SEQUENCE
47  * {
48  *      version                 [0]     EXPLICIT Version DEFAULT v1,
49  *      serialNumber                    CertificateSerialNumber,
50  *      signature                       AlgorithmIdentifier,
51  *      issuer                          Name,
52  *      validity                        Validity,
53  *      subject                         Name,
54  *      subjectPublicKeyInfo            SubjectPublicKeyInfo,
55  *      issuerUniqueID          [1]     IMPLICIT UniqueIdentifier OPTIONAL,
56  *      subjectUniqueId         [2]     IMPLICIT UniqueIdentifier OPTIONAL,
57  *      extensions              [3]     EXPLICIT Extensions OPTIONAL
58  * }
59  *
60  * Version ::= INTEGER { v1(0), v2(1), v3(2) }
61  *
62  * CertificateSerialNumber ::= INTEGER
63  *
64  * AlgorithmIdentifier ::= SEQUENCE
65  * {
66  *      algorithm                       OBJECT_IDENTIFIER,
67  *      parameters                      ANY DEFINED BY algorithm OPTIONAL
68  * }
69  *
70  * Name ::= CHOICE { RDNSequence }
71  *
72  * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
73  *
74  * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
75  *
76  * AttributeTypeAndValue ::= SEQUENCE
77  * {
78  *      type                            AttributeType,
79  *      value                           AttributeValue
80  * }
81  *
82  * AttributeType ::= OBJECT_IDENTIFIER
83  *
84  * AttributeValue ::= ANY DEFINED BY AttributeType
85  *
86  * Validity ::= SEQUENCE
87  * {
88  *      notBefore                       Time,
89  *      notAfter                        Time
90  * }
91  *
92  * Time ::= CHOICE
93  * {
94  *      utcTime                         UTCTime,
95  *      generalTime                     GeneralizedTime
96  * }
97  *
98  * UniqueIdentifier ::= BIT_STRING
99  *
100  * SubjectPublicKeyInfo ::= SEQUENCE
101  * {
102  *      algorithm                       AlgorithmIdentifier,
103  *      subjectPublicKey                BIT_STRING
104  * }
105  *
106  * RSAPublicKey ::= SEQUENCE
107  * {
108  *      modulus                         INTEGER
109  *      publicExponent                  INTEGER
110  * }
111  *
112  * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
113  *
114  * Extension ::= SEQUENCE
115  * {
116  *      extnID                          OBJECT_IDENTIFIER
117  *      critical                        BOOLEAN DEFAULT FALSE,
118  *      extnValue                       OCTET_STRING
119  * }
120  *
121  */
122
123 /**
124  * Read X.509 Certificate
125  * @param certificate certificate module
126  * @param cert X.509 certificate
127  */
128
129 void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
130 {
131         STREAM* s;
132         int length;
133         uint8 padding;
134         uint32 version;
135         int modulus_length;
136         int exponent_length;
137
138         s = stream_new(0);
139         stream_attach(s, cert->data, cert->length);
140
141         ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */
142
143         ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */
144
145         /* Explicit Contextual Tag [0] */
146         ber_read_contextual_tag(s, 0, &length, true);
147         ber_read_integer(s, &version); /* version (INTEGER) */
148         version++;
149
150         /* serialNumber */
151         ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */
152
153         /* signature */
154         ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
155         stream_seek(s, length);
156
157         /* issuer */
158         ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
159         stream_seek(s, length);
160
161         /* validity */
162         ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */
163         stream_seek(s, length);
164
165         /* subject */
166         ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
167         stream_seek(s, length);
168
169         /* subjectPublicKeyInfo */
170         ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */
171
172         /* subjectPublicKeyInfo::AlgorithmIdentifier */
173         ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
174         stream_seek(s, length);
175
176         /* subjectPublicKeyInfo::subjectPublicKey */
177         ber_read_bit_string(s, &length, &padding); /* BIT_STRING */
178
179         /* RSAPublicKey (SEQUENCE) */
180         ber_read_sequence_tag(s, &length); /* SEQUENCE */
181
182         ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */
183
184         /* skip zero padding, if any */
185         do
186         {
187                 stream_peek_uint8(s, padding);
188
189                 if (padding == 0)
190                 {
191                         stream_seek(s, 1);
192                         modulus_length--;
193                 }
194         }
195         while (padding == 0);
196
197         freerdp_blob_alloc(&info->modulus, modulus_length);
198         stream_read(s, info->modulus.data, modulus_length);
199
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);
204
205         stream_detach(s);
206         stream_free(s);
207 }
208
209 /**
210  * Instantiate new X.509 Certificate Chain.
211  * @param count certificate chain count
212  * @return new X.509 certificate chain
213  */
214
215 rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count)
216 {
217         rdpX509CertChain* x509_cert_chain;
218
219         x509_cert_chain = (rdpX509CertChain*) xmalloc(sizeof(rdpX509CertChain));
220
221         x509_cert_chain->count = count;
222         x509_cert_chain->array = (rdpCertBlob*) xzalloc(sizeof(rdpCertBlob) * count);
223
224         return x509_cert_chain;
225 }
226
227 /**
228  * Free X.509 Certificate Chain.
229  * @param x509_cert_chain X.509 certificate chain to be freed
230  */
231
232 void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain)
233 {
234         int i;
235
236         if (x509_cert_chain != NULL)
237         {
238                 for (i = 0; i < (int) x509_cert_chain->count; i++)
239                 {
240                         if (x509_cert_chain->array[i].data != NULL)
241                                 xfree(x509_cert_chain->array[i].data);
242                 }
243
244                 xfree(x509_cert_chain->array);
245                 xfree(x509_cert_chain);
246         }
247 }
248
249 static boolean certificate_process_server_public_key(rdpCertificate* certificate, STREAM* s, uint32 length)
250 {
251         uint8 magic[4];
252         uint32 keylen;
253         uint32 bitlen;
254         uint32 datalen;
255         uint32 modlen;
256
257         stream_read(s, magic, 4);
258         if (memcmp(magic, "RSA1", 4) != 0)
259         {
260                 printf("gcc_process_server_public_key: magic error\n");
261                 return false;
262         }
263
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);
268         modlen = keylen - 8;
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 */
272         stream_seek(s, 8);
273
274         return true;
275 }
276
277 static boolean certificate_process_server_public_signature(rdpCertificate* certificate, uint8* sigdata, int sigdatalen, STREAM* s, uint32 siglen)
278 {
279         uint8 md5hash[CRYPTO_MD5_DIGEST_LENGTH];
280         uint8 encsig[TSSK_KEY_LENGTH + 8];
281         uint8 sig[TSSK_KEY_LENGTH];
282         CryptoMd5 md5ctx;
283         int i, sum;
284
285         md5ctx = crypto_md5_init();
286         crypto_md5_update(md5ctx, sigdata, sigdatalen);
287         crypto_md5_final(md5ctx, md5hash);
288
289         stream_read(s, encsig, siglen);
290
291         /* Last 8 bytes shall be all zero. */
292
293         for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++)
294                 sum += encsig[i];
295
296         if (sum != 0)
297         {
298                 printf("certificate_process_server_public_signature: invalid signature\n");
299                 //return false;
300         }
301
302         siglen -= 8;
303
304         crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
305
306         /* Verify signature. */
307         if (memcmp(md5hash, sig, sizeof(md5hash)) != 0)
308         {
309                 printf("certificate_process_server_public_signature: invalid signature\n");
310                 //return false;
311         }
312
313         /*
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.
318          */
319
320         for (sum = 0, i = 17; i < 62; i++)
321                 sum += sig[i];
322
323         if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
324         {
325                 printf("certificate_process_server_public_signature: invalid signature\n");
326                 //return false;
327         }
328
329         return true;
330 }
331
332 /**
333  * Read a Server Proprietary Certificate.\n
334  * @param certificate certificate module
335  * @param s stream
336  */
337
338 boolean certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s)
339 {
340         uint32 dwSigAlgId;
341         uint32 dwKeyAlgId;
342         uint32 wPublicKeyBlobType;
343         uint32 wPublicKeyBlobLen;
344         uint32 wSignatureBlobType;
345         uint32 wSignatureBlobLen;
346         uint8* sigdata;
347         int sigdatalen;
348
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))
354         {
355                 printf("certificate_read_server_proprietary_certificate: parse error 1\n");
356                 return false;
357         }
358         stream_read_uint16(s, wPublicKeyBlobType);
359         if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
360         {
361                 printf("certificate_read_server_proprietary_certificate: parse error 2\n");
362                 return false;
363         }
364         stream_read_uint16(s, wPublicKeyBlobLen);
365         if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen))
366         {
367                 printf("certificate_read_server_proprietary_certificate: parse error 3\n");
368                 return false;
369         }
370         sigdatalen = stream_get_tail(s) - sigdata;
371         stream_read_uint16(s, wSignatureBlobType);
372         if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
373         {
374                 printf("certificate_read_server_proprietary_certificate: parse error 4\n");
375                 return false;
376         }
377         stream_read_uint16(s, wSignatureBlobLen);
378         if (wSignatureBlobLen != 72)
379         {
380                 printf("certificate_process_server_public_signature: invalid signature length (got %d, expected %d)\n", wSignatureBlobLen, 64);
381                 return false;
382         }
383         if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s, wSignatureBlobLen))
384         {
385                 printf("certificate_read_server_proprietary_certificate: parse error 5\n");
386                 return false;
387         }
388
389         return true;
390 }
391
392 /**
393  * Read an X.509 Certificate Chain.\n
394  * @param certificate certificate module
395  * @param s stream
396  */
397
398 boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s)
399 {
400         int i;
401         uint32 certLength;
402         uint32 numCertBlobs;
403
404         DEBUG_CERTIFICATE("Server X.509 Certificate Chain");
405
406         stream_read_uint32(s, numCertBlobs); /* numCertBlobs */
407
408         certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs);
409
410         for (i = 0; i < (int) numCertBlobs; i++)
411         {
412                 stream_read_uint32(s, certLength);
413
414                 DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength);
415
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;
419
420                 if (numCertBlobs - i == 2)
421                 {
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);
427                 }
428                 else if (numCertBlobs - i == 1)
429                 {
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);
433                 }
434         }
435
436         return true;
437 }
438
439 /**
440  * Read a Server Certificate.\n
441  * @param certificate certificate module
442  * @param server_cert server certificate
443  * @param length certificate length
444  */
445
446 boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length)
447 {
448         STREAM* s;
449         uint32 dwVersion;
450
451         s = stream_new(0);
452         stream_attach(s, server_cert, length);
453
454         if (length < 1)
455         {
456                 printf("null server certificate\n");
457                 return false;
458         }
459
460         stream_read_uint32(s, dwVersion); /* dwVersion (4 bytes) */
461
462         switch (dwVersion & CERT_CHAIN_VERSION_MASK)
463         {
464                 case CERT_CHAIN_VERSION_1:
465                         certificate_read_server_proprietary_certificate(certificate, s);
466                         break;
467
468                 case CERT_CHAIN_VERSION_2:
469                         certificate_read_server_x509_certificate_chain(certificate, s);
470                         break;
471
472                 default:
473                         printf("invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK);
474                         break;
475         }
476
477         xfree(s);
478         return true;
479 }
480
481 rdpKey* key_new(const char* keyfile)
482 {
483         rdpKey* key;
484         RSA *rsa;
485         FILE *fp;
486
487         key = (rdpKey*) xzalloc(sizeof(rdpKey));
488
489         if (key == NULL)
490                 return NULL;
491
492         fp = fopen(keyfile, "r");
493
494         if (fp == NULL)
495         {
496                 printf("unable to load RSA key from %s: %s.", keyfile, strerror(errno));
497                 return NULL;
498         }
499
500         rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
501
502         if (rsa == NULL)
503         {
504                 ERR_print_errors_fp(stdout);
505                 fclose(fp);
506                 return NULL;
507         }
508
509         fclose(fp);
510
511         switch (RSA_check_key(rsa))
512         {
513                 case 0:
514                         RSA_free(rsa);
515                         printf("invalid RSA key in %s", keyfile);
516                         return NULL;
517
518                 case 1:
519                         /* Valid key. */
520                         break;
521
522                 default:
523                         ERR_print_errors_fp(stdout);
524                         RSA_free(rsa);
525                         return NULL;
526         }
527
528         if (BN_num_bytes(rsa->e) > 4)
529         {
530                 RSA_free(rsa);
531                 printf("RSA public exponent too large in %s", keyfile);
532                 return NULL;
533         }
534
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));
544
545         RSA_free(rsa);
546
547         return key;
548 }
549
550 void key_free(rdpKey* key)
551 {
552         if (key != NULL)
553         {
554                 freerdp_blob_free(&key->modulus);
555                 freerdp_blob_free(&key->private_exponent);
556                 xfree(key);
557         }
558 }
559
560 void certificate_store_init(rdpCertificateStore* certificate_store)
561 {
562         char* config_path;
563         rdpSettings* settings;
564
565         settings = certificate_store->settings;
566
567         config_path = freerdp_get_config_path(settings);
568         certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_dir);
569
570         if (freerdp_check_file_exists(certificate_store->path) == false)
571         {
572                 freerdp_mkdir(certificate_store->path);
573                 printf("creating directory %s\n", certificate_store->path);
574         }
575
576         certificate_store->file = freerdp_construct_path(config_path, (char*) certificate_known_hosts_file);
577
578         if (freerdp_check_file_exists(certificate_store->file) == false)
579         {
580                 certificate_store->fp = fopen((char*) certificate_store->file, "w+");
581
582                 if (certificate_store->fp == NULL)
583                 {
584                         printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
585                         return;
586                 }
587
588                 fflush(certificate_store->fp);
589         }
590         else
591         {
592                 certificate_store->fp = fopen((char*) certificate_store->file, "r+");
593         }
594 }
595
596 int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
597 {
598         FILE* fp;
599         int length;
600         char* data;
601         char* pline;
602         int match = 1;
603         long int size;
604
605         fp = certificate_store->fp;
606
607         if (!fp)
608                 return match;
609
610         fseek(fp, 0, SEEK_END);
611         size = ftell(fp);
612         fseek(fp, 0, SEEK_SET);
613
614         if (size < 1)
615                 return match;
616
617         data = (char*) xmalloc(size + 2);
618
619         if (fread(data, size, 1, fp) != 1)
620         {
621                 xfree(data);
622                 return match;
623         }
624
625         data[size] = '\n';
626         data[size + 1] = '\0';
627         pline = strtok(data, "\n");
628
629         while (pline != NULL)
630         {
631                 length = strlen(pline);
632
633                 if (length > 0)
634                 {
635                         length = strcspn(pline, " \t");
636                         pline[length] = '\0';
637
638                         if (strcmp(pline, certificate_data->hostname) == 0)
639                         {
640                                 pline = &pline[length + 1];
641
642                                 if (strcmp(pline, certificate_data->fingerprint) == 0)
643                                         match = 0;
644                                 else
645                                         match = -1;
646                                 break;
647                         }
648                 }
649
650                 pline = strtok(NULL, "\n");
651         }
652         xfree(data);
653
654         return match;
655 }
656
657 void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
658 {
659         FILE* fp;
660
661         /* reopen in append mode */
662         fp = fopen(certificate_store->file, "a");
663
664         if (!fp)
665                 return;
666
667         fprintf(certificate_store->fp,"%s %s\n", certificate_data->hostname, certificate_data->fingerprint);
668         fclose(fp);
669 }
670
671 rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint)
672 {
673         rdpCertificateData* certdata;
674
675         certdata = (rdpCertificateData*) xzalloc(sizeof(rdpCertificateData));
676
677         if (certdata != NULL)
678         {
679                 certdata->hostname = xstrdup(hostname);
680                 certdata->fingerprint = xstrdup(fingerprint);
681         }
682
683         return certdata;
684 }
685
686 void certificate_data_free(rdpCertificateData* certificate_data)
687 {
688         if (certificate_data != NULL)
689         {
690                 xfree(certificate_data->hostname);
691                 xfree(certificate_data->fingerprint);
692                 xfree(certificate_data);
693         }
694 }
695
696 rdpCertificateStore* certificate_store_new(rdpSettings* settings)
697 {
698         rdpCertificateStore* certificate_store;
699
700         certificate_store = (rdpCertificateStore*) xzalloc(sizeof(rdpCertificateStore));
701
702         if (certificate_store != NULL)
703         {
704                 certificate_store->settings = settings;
705                 certificate_store_init(certificate_store);
706         }
707
708         return certificate_store;
709 }
710
711 void certificate_store_free(rdpCertificateStore* certstore)
712 {
713         if (certstore != NULL)
714         {
715                 if (certstore->fp != NULL)
716                         fclose(certstore->fp);
717
718                 xfree(certstore->path);
719                 xfree(certstore->file);
720                 xfree(certstore);
721         }
722 }
723
724 /**
725  * Instantiate new certificate module.\n
726  * @param rdp RDP module
727  * @return new certificate module
728  */
729
730 rdpCertificate* certificate_new()
731 {
732         rdpCertificate* certificate;
733
734         certificate = (rdpCertificate*) xzalloc(sizeof(rdpCertificate));
735
736         if (certificate != NULL)
737         {
738                 certificate->x509_cert_chain = NULL;
739         }
740
741         return certificate;
742 }
743
744 /**
745  * Free certificate module.
746  * @param certificate certificate module to be freed
747  */
748
749 void certificate_free(rdpCertificate* certificate)
750 {
751         if (certificate != NULL)
752         {
753                 certificate_free_x509_certificate_chain(certificate->x509_cert_chain);
754
755                 if (certificate->cert_info.modulus.data != NULL)
756                         freerdp_blob_free(&(certificate->cert_info.modulus));
757
758                 xfree(certificate);
759         }
760 }