Refactor log system
[platform/core/security/cert-svc.git] / vcore / src / vcore / WrtSignatureValidator.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        WrtSignatureValidator.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version     1.0
20  * @brief       Implementatin of tizen signature validation protocol.
21  */
22 #include <vcore/WrtSignatureValidator.h>
23
24 #include <vcore/CertificateVerifier.h>
25 #include <vcore/Certificate.h>
26 #include <vcore/OCSPCertMgrUtil.h>
27 #include <vcore/ReferenceValidator.h>
28 #include <vcore/ValidatorFactories.h>
29 #include <vcore/XmlsecAdapter.h>
30
31 #include <dpl/log/log.h>
32
33 namespace {
34 const time_t TIMET_DAY = 60 * 60 * 24;
35
36 const std::string TOKEN_ROLE_AUTHOR_URI =
37     "http://www.w3.org/ns/widgets-digsig#role-author";
38 const std::string TOKEN_ROLE_DISTRIBUTOR_URI =
39     "http://www.w3.org/ns/widgets-digsig#role-distributor";
40 const std::string TOKEN_PROFILE_URI =
41     "http://www.w3.org/ns/widgets-digsig#profile";
42
43 } // namespace anonymouse
44
45 static tm _ASN1_GetTimeT(ASN1_TIME* time)
46 {
47     struct tm t;
48     const char* str = (const char*) time->data;
49     size_t i = 0;
50
51     memset(&t, 0, sizeof(t));
52
53     if (time->type == V_ASN1_UTCTIME) /* two digit year */
54     {
55         t.tm_year = (str[i] - '0') * 10 + (str[i+1] - '0');
56         i += 2;
57         if (t.tm_year < 70)
58             t.tm_year += 100;
59     }
60     else if (time->type == V_ASN1_GENERALIZEDTIME) /* four digit year */
61     {
62         t.tm_year =
63             (str[i] - '0') * 1000
64             + (str[i+1] - '0') * 100
65             + (str[i+2] - '0') * 10
66             + (str[i+3] - '0');
67         i += 4;
68         t.tm_year -= 1900;
69     }
70     t.tm_mon = ((str[i] - '0') * 10 + (str[i+1] - '0')) - 1; // -1 since January is 0 not 1.
71     t.tm_mday = (str[i+2] - '0') * 10 + (str[i+3] - '0');
72     t.tm_hour = (str[i+4] - '0') * 10 + (str[i+5] - '0');
73     t.tm_min  = (str[i+6] - '0') * 10 + (str[i+7] - '0');
74     t.tm_sec  = (str[i+8] - '0') * 10 + (str[i+9] - '0');
75
76     /* Note: we did not adjust the time based on time zone information */
77     return t;
78 }
79
80
81 namespace ValidationCore {
82
83 class WrtSignatureValidator::Impl {
84 public:
85     virtual WrtSignatureValidator::Result check(
86         SignatureData &data,
87         const std::string &widgetContentPath) = 0;
88
89     explicit Impl(bool ocspEnable,
90                   bool crlEnable,
91                   bool complianceMode)
92       : m_complianceModeEnabled(complianceMode)
93     {
94 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
95         m_ocspEnable = ocspEnable;
96         m_crlEnable = crlEnable;
97 #else
98         (void) ocspEnable;
99         (void) crlEnable;
100 #endif
101     }
102
103     virtual ~Impl() {}
104
105     bool checkRoleURI(const SignatureData &data) {
106         std::string roleURI = data.getRoleURI();
107
108         if (roleURI.empty()) {
109             LogWarning("URI attribute in Role tag couldn't be empty.");
110             return false;
111         }
112
113         if (roleURI != TOKEN_ROLE_AUTHOR_URI && data.isAuthorSignature()) {
114             LogWarning("URI attribute in Role tag does not "
115               "match with signature filename.");
116             return false;
117         }
118
119         if (roleURI != TOKEN_ROLE_DISTRIBUTOR_URI && !data.isAuthorSignature()) {
120             LogWarning("URI attribute in Role tag does not "
121               "match with signature filename.");
122             return false;
123         }
124         return true;
125     }
126
127     bool checkProfileURI(const SignatureData &data) {
128         if (TOKEN_PROFILE_URI != data.getProfileURI()) {
129             LogWarning("Profile tag contains unsupported value in URI attribute " << data.getProfileURI());
130             return false;
131         }
132         return true;
133     }
134
135     bool checkObjectReferences(const SignatureData &data) {
136         ObjectList objectList = data.getObjectList();
137         ObjectList::const_iterator iter;
138         for (iter = objectList.begin(); iter != objectList.end(); ++iter) {
139             if (!data.containObjectReference(*iter)) {
140                 LogWarning("Signature does not contain reference for object " << *iter);
141                 return false;
142             }
143         }
144         return true;
145     }
146 protected:
147     bool m_complianceModeEnabled;
148 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
149     bool m_ocspEnable;
150     bool m_crlEnable;
151 #endif
152
153 };
154
155 class ImplTizen : public WrtSignatureValidator::Impl {
156 public:
157     WrtSignatureValidator::Result check(SignatureData &data,
158             const std::string &widgetContentPath);
159
160     explicit ImplTizen(bool ocspEnable,
161                        bool crlEnable,
162                        bool complianceMode)
163       : Impl(ocspEnable, crlEnable, complianceMode)
164     {}
165
166     virtual ~ImplTizen() {}
167 };
168
169 WrtSignatureValidator::Result ImplTizen::check(
170         SignatureData &data,
171         const std::string &widgetContentPath)
172 {
173     bool disregard = false;
174
175     if (!checkRoleURI(data)) {
176         return WrtSignatureValidator::SIGNATURE_INVALID;
177     }
178
179     if (!checkProfileURI(data)) {
180         return WrtSignatureValidator::SIGNATURE_INVALID;
181     }
182
183     //  CertificateList sortedCertificateList = data.getCertList();
184
185     CertificateCollection collection;
186     collection.load(data.getCertList());
187
188     // First step - sort certificate
189     if (!collection.sort()) {
190         LogWarning("Certificates do not form valid chain.");
191         return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
192     }
193
194     // Check for error
195     if (collection.empty()) {
196         LogWarning("Certificate list in signature is empty.");
197         return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
198     }
199
200     CertificateList sortedCertificateList = collection.getChain();
201
202     // TODO move it to CertificateCollection
203     // Add root CA and CA certificates (if chain is incomplete)
204     sortedCertificateList =
205         OCSPCertMgrUtil::completeCertificateChain(sortedCertificateList);
206
207     CertificatePtr root = sortedCertificateList.back();
208
209     // Is Root CA certificate trusted?
210     CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
211
212     LogDebug("Is root certificate from TIZEN_DEVELOPER domain : " << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
213     LogDebug("Is root certificate from TIZEN_TEST domain      : " << storeIdSet.contains(CertStoreId::TIZEN_TEST));
214     LogDebug("Is root certificate from TIZEN_VERIFY domain    : " << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
215     LogDebug("Is root certificate from TIZEN_PUBLIC domain    : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
216     LogDebug("Is root certificate from TIZEN_PARTNER domain   : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
217     LogDebug("Is root certificate from TIZEN_PLATFORM domain  : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
218     LogDebug("Visibility level is public   : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
219     LogDebug("Visibility level is partner  : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
220         LogDebug("Visibility level is platform : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
221
222         if (data.isAuthorSignature())
223         {
224                 if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
225                 {
226                         LogWarning("author-signature.xml has got unrecognized Root CA "
227                                         "certificate. Signature will be disregarded.");
228                         disregard = true;
229                 }
230         }
231         else // distributor
232         {
233                 if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
234                 {
235                         LogWarning("distributor has author level siganture! Signature will be disregarded.");
236                         return WrtSignatureValidator::SIGNATURE_IN_DISTRIBUTOR_CASE_AUTHOR_CERT;//SIGNATURE_INVALID;
237                 }
238                 LogDebug("signaturefile name = " << data.getSignatureFileName());
239
240
241                 if (data.getSignatureNumber() == 1)
242                 {
243                         if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
244                         {
245                                 LogDebug("Root CA for signature1.xml is correct.");
246                         }
247                         else
248                         {
249                                 LogWarning("signature1.xml has got unrecognized Root CA "
250                                         "certificate. Signature will be disregarded.");
251                                 disregard = true;
252                         }
253                 }
254         }
255
256     data.setStorageType(storeIdSet);
257     data.setSortedCertificateList(sortedCertificateList);
258
259     // We add only Root CA certificate because WAC ensure that the rest
260     // of certificates are present in signature files ;-)
261     XmlSec::XmlSecContext context;
262     context.signatureFile = data.getSignatureFileName();
263     context.certificatePtr = root;
264
265     // Now we should have full certificate chain.
266     // If the end certificate is not ROOT CA we should disregard signature
267     // but still signature must be valid... Aaaaaa it's so stupid...
268     if (!(root->isSignedBy(root))) {
269         LogWarning("Root CA certificate not found. Chain is incomplete.");
270         //context.allowBrokenChain = true;
271     }
272
273     // WAC 2.0 SP-2066 The wrt must not block widget installation
274     // due to expiration of the author certificate.
275     time_t nowTime = time(NULL);
276 #define CHECK_TIME
277 #ifdef CHECK_TIME
278
279     ASN1_TIME* notAfterTime = data.getEndEntityCertificatePtr()->getNotAfterTime();
280     ASN1_TIME* notBeforeTime = data.getEndEntityCertificatePtr()->getNotBeforeTime();
281
282         if (X509_cmp_time(notBeforeTime, &nowTime) > 0  || X509_cmp_time(notAfterTime, &nowTime) < 0)
283     {
284       struct tm *t;
285       struct tm ta, tb, tc;
286       char msg[1024];
287
288       t = localtime(&nowTime);
289       if (!t)
290           return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;
291
292       memset(&tc, 0, sizeof(tc));
293
294       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
295       LogDebug("## System's currentTime : " << msg);
296       fprintf(stderr, "## System's currentTime : %s\n", msg);
297
298       tb = _ASN1_GetTimeT(notBeforeTime);
299       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
300       LogDebug("## certificate's notBeforeTime : " << msg);
301       fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
302
303       ta = _ASN1_GetTimeT(notAfterTime);
304       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
305       LogDebug("## certificate's notAfterTime : " << msg);
306       fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
307
308           if (storeIdSet.contains(CertStoreId::TIZEN_TEST) || storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
309           {
310          LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
311          fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
312          return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;//SIGNATURE_INVALID;
313       }
314
315       int year = (ta.tm_year - tb.tm_year) / 4;
316
317       if(year == 0)
318       {
319           tc.tm_year = tb.tm_year; 
320           tc.tm_mon = tb.tm_mon + 1;
321           tc.tm_mday = tb.tm_mday;
322
323           if(tc.tm_mon == 12)
324           {
325               tc.tm_year = ta.tm_year;       
326               tc.tm_mon = ta.tm_mon - 1;
327               tc.tm_mday = ta.tm_mday;
328               
329               if(tc.tm_mon < 0)
330               {
331                  tc.tm_year = ta.tm_year;
332                  tc.tm_mon = ta.tm_mon;
333                  tc.tm_mday = ta.tm_mday -1;
334
335                  if(tc.tm_mday == 0)
336                  {
337                     tc.tm_year = tb.tm_year;                
338                     tc.tm_mon = tb.tm_mon;
339                     tc.tm_mday = tb.tm_mday +1;
340                  }
341               }
342           }          
343       }
344       else{
345          tc.tm_year = tb.tm_year + year;
346          tc.tm_mon = (tb.tm_mon + ta.tm_mon )/2;
347          tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;  
348       }
349
350       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
351       LogDebug("## cmp cert with validation time : " << msg);
352       fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
353
354       time_t outCurrent = mktime(&tc);
355       context.validationTime = outCurrent;
356
357       fprintf(stderr, "## cmp outCurrent time : %ld\n", outCurrent);
358
359       //return WrtSignatureValidator::SIGNATURE_INVALID;
360     }   
361
362 #endif
363
364 #if 0
365     time_t notAfter = data.getEndEntityCertificatePtr()->getNotAfter();
366     time_t notBefore = data.getEndEntityCertificatePtr()->getNotBefore();
367
368         struct tm *t;
369
370         if (data.isAuthorSignature())
371         {
372                 // time_t 2038 year bug exist. So, notAtter() cann't check...
373                 /*
374                 if (notAfter < nowTime)
375                 {
376                         context.validationTime = notAfter - TIMET_DAY;
377                         LogWarning("Author certificate is expired. notAfter...");
378                 }
379                 */
380
381                 if (notBefore > nowTime)
382                 {
383                         LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
384
385                         t = localtime(&nowTime);
386                         LogDebug("System's current Year : " << (t->tm_year + 1900));
387                         LogDebug("System's current month : " << (t->tm_mon + 1));
388                         LogDebug("System's current day : " << (t->tm_mday));
389
390                         t = localtime(&notBefore);
391                         LogDebug("Author certificate's notBefore Year : " << (t->tm_year + 1900));
392                         LogDebug("Author certificate's notBefore month : " << (t->tm_mon + 1));
393                         LogDebug("Author certificate's notBefore day : " << (t->tm_mday));
394
395                         context.validationTime = notBefore + TIMET_DAY;
396
397                         t = localtime(&context.validationTime);
398                         LogDebug("Modified current Year : " << (t->tm_year + 1900));
399                         LogDebug("Modified current notBefore month : " << (t->tm_mon + 1));
400                         LogDebug("Modified current notBefore day : " << (t->tm_mday));
401                 }
402         }
403 #endif
404     // WAC 2.0 SP-2066 The wrt must not block widget installation
405         //context.allowBrokenChain = true;
406
407         // end
408         if (!data.isAuthorSignature())
409         {
410                 if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
411                         LogWarning("Installation break - invalid package!");
412                         return WrtSignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
413                 }
414
415                 data.setReference(context.referenceSet);
416
417                 if (!checkObjectReferences(data)) {
418                         LogWarning("Failed to check Object References");
419                         return WrtSignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
420                 }
421
422                 ReferenceValidator fileValidator(widgetContentPath);
423                 if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
424                         LogWarning("Invalid package - file references broken");
425                         return WrtSignatureValidator::SIGNATURE_INVALID_NO_HASH_FILE;//SIGNATURE_INVALID;
426                 }
427         }
428
429 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
430     // It is good time to do OCSP check
431     // ocspCheck will throw an exception on any error.
432     // TODO Probably we should catch this exception and add
433     // some information to SignatureData.
434     if (!m_complianceModeEnabled && !data.isAuthorSignature()) {
435         CertificateCollection coll;
436         coll.load(sortedCertificateList);
437
438         if (!coll.sort()) {
439             LogDebug("Collection does not contain chain!");
440             return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
441         }
442
443         CertificateVerifier verificator(m_ocspEnable, m_crlEnable);
444         VerificationStatus result = verificator.check(coll);
445
446         if (result == VERIFICATION_STATUS_REVOKED) {
447             return WrtSignatureValidator::SIGNATURE_REVOKED;
448         }
449
450         if (result == VERIFICATION_STATUS_UNKNOWN ||
451             result == VERIFICATION_STATUS_ERROR)
452         {
453 #ifdef _OCSP_POLICY_DISREGARD_UNKNOWN_OR_ERROR_CERTS_
454             disregard = true;
455 #endif
456         }
457     }
458 #endif
459
460     if (disregard) {
461         LogWarning("Signature is disregard. RootCA is not a member of Tizen");
462         return WrtSignatureValidator::SIGNATURE_INVALID_DISTRIBUTOR_CERT;//SIGNATURE_DISREGARD;
463     }
464     return WrtSignatureValidator::SIGNATURE_VERIFIED;
465 }
466
467 class ImplWac : public WrtSignatureValidator::Impl
468 {
469 public:
470     WrtSignatureValidator::Result check(SignatureData &data,
471             const std::string &widgetContentPath);
472
473     explicit ImplWac(bool ocspEnable,
474                      bool crlEnable,
475                      bool complianceMode)
476       : Impl(ocspEnable, crlEnable, complianceMode)
477     {}
478
479     virtual ~ImplWac() {}
480 };
481
482 WrtSignatureValidator::Result ImplWac::check(
483     SignatureData &data,
484     const std::string &widgetContentPath)
485 {
486     bool disregard = false;
487
488     if (!checkRoleURI(data)) {
489         return WrtSignatureValidator::SIGNATURE_INVALID;
490     }
491
492     if (!checkProfileURI(data)) {
493         return WrtSignatureValidator::SIGNATURE_INVALID;
494     }
495
496     //  CertificateList sortedCertificateList = data.getCertList();
497
498     CertificateCollection collection;
499     collection.load(data.getCertList());
500
501     // First step - sort certificate
502     if (!collection.sort()) {
503         LogWarning("Certificates do not form valid chain.");
504         return WrtSignatureValidator::SIGNATURE_INVALID;
505     }
506
507     // Check for error
508     if (collection.empty()) {
509         LogWarning("Certificate list in signature is empty.");
510         return WrtSignatureValidator::SIGNATURE_INVALID;
511     }
512
513     CertificateList sortedCertificateList = collection.getChain();
514
515     // TODO move it to CertificateCollection
516     // Add root CA and CA certificates (if chain is incomplete)
517     sortedCertificateList =
518         OCSPCertMgrUtil::completeCertificateChain(sortedCertificateList);
519
520     CertificatePtr root = sortedCertificateList.back();
521
522     // Is Root CA certificate trusted?
523     CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
524
525     LogDebug("Is root certificate from TIZEN_DEVELOPER domain : " << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
526     LogDebug("Is root certificate from TIZEN_TEST domain      : " << storeIdSet.contains(CertStoreId::TIZEN_TEST));
527     LogDebug("Is root certificate from TIZEN_VERIFY domain    : " << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
528     LogDebug("Is root certificate from TIZEN_PUBLIC domain    : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
529     LogDebug("Is root certificate from TIZEN_PARTNER domain   : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
530     LogDebug("Is root certificate from TIZEN_PLATFORM domain  : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
531     LogDebug("Visibility level is public   : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
532     LogDebug("Visibility level is partner  : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
533         LogDebug("Visibility level is platform : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
534
535         if (data.isAuthorSignature())
536         {
537                 if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
538                 {
539                         LogWarning("author-signature.xml has got unrecognized Root CA "
540                                         "certificate. Signature will be disregarded.");
541                         disregard = true;
542                 }
543         }
544         else
545         {
546                 if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
547                 {
548                         LogWarning("distributor has author level siganture! Signature will be disregarded.");
549                         return WrtSignatureValidator::SIGNATURE_INVALID;
550                 }
551                 LogDebug("signaturefile name = " << data.getSignatureFileName());
552
553                 if (data.getSignatureNumber() == 1)
554                 {
555                         if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
556                         {
557                                 LogDebug("Root CA for signature1.xml is correct.");
558                         }
559                         else
560                         {
561                                 LogWarning("signature1.xml has got unrecognized Root CA "
562                                         "certificate. Signature will be disregarded.");
563                                 disregard = true;
564                         }
565                 }
566         }
567
568     data.setStorageType(storeIdSet);
569     data.setSortedCertificateList(sortedCertificateList);
570
571     // We add only Root CA certificate because WAC ensure that the rest
572     // of certificates are present in signature files ;-)
573     XmlSec::XmlSecContext context;
574     context.signatureFile = data.getSignatureFileName();
575     context.certificatePtr = root;
576
577     // Now we should have full certificate chain.
578     // If the end certificate is not ROOT CA we should disregard signature
579     // but still signature must be valid... Aaaaaa it's so stupid...
580     if (!(root->isSignedBy(root))) {
581         LogWarning("Root CA certificate not found. Chain is incomplete.");
582 //        context.allowBrokenChain = true;
583     }
584
585     time_t nowTime = time(NULL);
586     // WAC 2.0 SP-2066 The wrt must not block widget installation
587         // due to expiration of the author certificate.
588 #define CHECK_TIME
589 #ifdef CHECK_TIME
590
591     ASN1_TIME* notAfterTime = data.getEndEntityCertificatePtr()->getNotAfterTime();
592     ASN1_TIME* notBeforeTime = data.getEndEntityCertificatePtr()->getNotBeforeTime();
593
594                 if (X509_cmp_time(notBeforeTime, &nowTime) > 0  || X509_cmp_time(notAfterTime, &nowTime) < 0)
595     {
596       struct tm *t;
597       struct tm ta, tb, tc;
598       char msg[1024];
599
600       t = localtime(&nowTime);
601       if (!t)
602           return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;
603
604       memset(&tc, 0, sizeof(tc));
605
606       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
607       LogDebug("## System's currentTime : " << msg);
608       fprintf(stderr, "## System's currentTime : %s\n", msg);
609
610       tb = _ASN1_GetTimeT(notBeforeTime);
611       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
612       LogDebug("## certificate's notBeforeTime : " << msg);
613       fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
614
615       ta = _ASN1_GetTimeT(notAfterTime);
616       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
617       LogDebug("## certificate's notAfterTime : " << msg);
618       fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
619
620       if (storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
621       {
622          LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
623          fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
624          return WrtSignatureValidator::SIGNATURE_INVALID;
625       }
626
627       int year = (ta.tm_year - tb.tm_year) / 4;
628
629       if(year == 0)
630       {
631           tc.tm_year = tb.tm_year; 
632           tc.tm_mon = tb.tm_mon + 1;
633           tc.tm_mday = tb.tm_mday;
634
635           if(tc.tm_mon == 12)
636           {
637               tc.tm_year = ta.tm_year;       
638               tc.tm_mon = ta.tm_mon - 1;
639               tc.tm_mday = ta.tm_mday;
640               
641               if(tc.tm_mon < 0)
642               {
643                  tc.tm_year = ta.tm_year;
644                  tc.tm_mon = ta.tm_mon;
645                  tc.tm_mday = ta.tm_mday -1;
646
647                  if(tc.tm_mday == 0)
648                  {
649                     tc.tm_year = tb.tm_year;                
650                     tc.tm_mon = tb.tm_mon;
651                     tc.tm_mday = tb.tm_mday +1;
652                  }
653               }
654           }          
655       }
656       else{
657          tc.tm_year = tb.tm_year + year;
658          tc.tm_mon = (tb.tm_mon + ta.tm_mon )/2;
659          tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;  
660       }
661
662       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
663       LogDebug("## cmp cert with validation time : " << msg);
664       fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
665
666       time_t outCurrent = mktime(&tc);
667
668       fprintf(stderr, "## cmp outCurrent time : %ld\n", outCurrent);
669
670       context.validationTime = outCurrent;
671       //return WrtSignatureValidator::SIGNATURE_INVALID;
672     }   
673
674 #endif
675
676 #if 0
677         time_t notAfter = data.getEndEntityCertificatePtr()->getNotAfter();
678         time_t notBefore = data.getEndEntityCertificatePtr()->getNotBefore();
679
680         struct tm *t;
681
682         if (data.isAuthorSignature())
683         {
684                 // time_t 2038 year bug exist. So, notAtter() cann't check...
685                 /*
686                 if (notAfter < nowTime)
687                 {
688                         context.validationTime = notAfter - TIMET_DAY;
689                         LogWarning("Author certificate is expired. notAfter...");
690                  }
691                  */
692
693                 if (notBefore > nowTime)
694                 {
695                         LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
696
697                         t = localtime(&nowTime);
698                         LogDebug("System's current Year : " << (t->tm_year + 1900));
699                         LogDebug("System's current month : " << (t->tm_mon + 1));
700                         LogDebug("System's current day : " << (t->tm_mday));
701
702                         t = localtime(&notBefore);
703                         LogDebug("Author certificate's notBefore Year : " << (t->tm_year + 1900));
704                         LogDebug("Author certificate's notBefore month : " << (t->tm_mon + 1));
705                         LogDebug("Author certificate's notBefore day : " << (t->tm_mday));
706
707                         context.validationTime = notBefore + TIMET_DAY;
708
709                         t = localtime(&context.validationTime);
710                         LogDebug("Modified current Year : " << (t->tm_year + 1900));
711                         LogDebug("Modified current notBefore month : " << (t->tm_mon + 1));
712                         LogDebug("Modified current notBefore day : " << (t->tm_mday));
713                 }
714         }
715 #endif
716
717         if (!data.isAuthorSignature())
718         {
719                 if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
720                         LogWarning("Installation break - invalid package!");
721                         return WrtSignatureValidator::SIGNATURE_INVALID;
722                 }
723
724                 data.setReference(context.referenceSet);
725
726                 if (!checkObjectReferences(data)) {
727                         return WrtSignatureValidator::SIGNATURE_INVALID;
728                 }
729
730                 ReferenceValidator fileValidator(widgetContentPath);
731                 if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
732                         LogWarning("Invalid package - file references broken");
733                         return WrtSignatureValidator::SIGNATURE_INVALID;
734                 }
735         }
736
737 #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
738     // It is good time to do OCSP check
739     // ocspCheck will throw an exception on any error.
740     // TODO Probably we should catch this exception and add
741     // some information to SignatureData.
742     if (!m_complianceModeEnabled && !data.isAuthorSignature()) {
743         CertificateCollection coll;
744         coll.load(sortedCertificateList);
745
746         if (!coll.sort()) {
747             LogDebug("Collection does not contain chain!");
748             return WrtSignatureValidator::SIGNATURE_INVALID;
749         }
750
751         CertificateVerifier verificator(m_ocspEnable, m_crlEnable);
752         VerificationStatus result = verificator.check(coll);
753
754         if (result == VERIFICATION_STATUS_REVOKED) {
755             return WrtSignatureValidator::SIGNATURE_REVOKED;
756         }
757
758         if (result == VERIFICATION_STATUS_UNKNOWN ||
759             result == VERIFICATION_STATUS_ERROR)
760         {
761 #ifdef _OCSP_POLICY_DISREGARD_UNKNOWN_OR_ERROR_CERTS_
762             disregard = true;
763 #endif //_OCSP_POLICY_DISREGARD_UNKNOWN_OR_ERROR_CERTS_
764         }
765     }
766 #endif
767
768     if (disregard) {
769         LogWarning("Signature is disregard. RootCA is not a member of Tizen.");
770         return WrtSignatureValidator::SIGNATURE_DISREGARD;
771     }
772     return WrtSignatureValidator::SIGNATURE_VERIFIED;
773 }
774
775 // Implementation of WrtSignatureValidator
776
777 WrtSignatureValidator::WrtSignatureValidator(
778     AppType appType,
779     bool ocspEnable,
780     bool crlEnable,
781     bool complianceMode)
782   : m_impl(0)
783 {
784     if (appType == TIZEN)
785         m_impl = new ImplTizen(ocspEnable,crlEnable,complianceMode);
786     else
787         m_impl = new ImplWac(ocspEnable,crlEnable,complianceMode);
788 }
789
790 WrtSignatureValidator::~WrtSignatureValidator()
791 {
792     delete m_impl;
793 }
794
795 WrtSignatureValidator::Result WrtSignatureValidator::check(
796     SignatureData &data,
797     const std::string &widgetContentPath)
798 {
799     return m_impl->check(data, widgetContentPath);
800 }
801
802 } // namespace ValidationCore
803