d03f4f5331d0af3d09ddbc28692e41150e0dc488
[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/CertificateCollection.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         (void) ocspEnable;
95         (void) crlEnable;
96     }
97
98     virtual ~Impl() {}
99
100     bool checkRoleURI(const SignatureData &data) {
101         std::string roleURI = data.getRoleURI();
102
103         if (roleURI.empty()) {
104             LogWarning("URI attribute in Role tag couldn't be empty.");
105             return false;
106         }
107
108         if (roleURI != TOKEN_ROLE_AUTHOR_URI && data.isAuthorSignature()) {
109             LogWarning("URI attribute in Role tag does not "
110               "match with signature filename.");
111             return false;
112         }
113
114         if (roleURI != TOKEN_ROLE_DISTRIBUTOR_URI && !data.isAuthorSignature()) {
115             LogWarning("URI attribute in Role tag does not "
116               "match with signature filename.");
117             return false;
118         }
119         return true;
120     }
121
122     bool checkProfileURI(const SignatureData &data) {
123         if (TOKEN_PROFILE_URI != data.getProfileURI()) {
124             LogWarning("Profile tag contains unsupported value in URI attribute " << data.getProfileURI());
125             return false;
126         }
127         return true;
128     }
129
130     bool checkObjectReferences(const SignatureData &data) {
131         ObjectList objectList = data.getObjectList();
132         ObjectList::const_iterator iter;
133         for (iter = objectList.begin(); iter != objectList.end(); ++iter) {
134             if (!data.containObjectReference(*iter)) {
135                 LogWarning("Signature does not contain reference for object " << *iter);
136                 return false;
137             }
138         }
139         return true;
140     }
141 protected:
142     bool m_complianceModeEnabled;
143
144 };
145
146 class ImplTizen : public WrtSignatureValidator::Impl {
147 public:
148     WrtSignatureValidator::Result check(SignatureData &data,
149             const std::string &widgetContentPath);
150
151     explicit ImplTizen(bool ocspEnable,
152                        bool crlEnable,
153                        bool complianceMode)
154       : Impl(ocspEnable, crlEnable, complianceMode)
155     {}
156
157     virtual ~ImplTizen() {}
158 };
159
160 WrtSignatureValidator::Result ImplTizen::check(
161         SignatureData &data,
162         const std::string &widgetContentPath)
163 {
164     bool disregard = false;
165
166     if (!checkRoleURI(data)) {
167         return WrtSignatureValidator::SIGNATURE_INVALID;
168     }
169
170     if (!checkProfileURI(data)) {
171         return WrtSignatureValidator::SIGNATURE_INVALID;
172     }
173
174     //  CertificateList sortedCertificateList = data.getCertList();
175
176     CertificateCollection collection;
177     collection.load(data.getCertList());
178
179     // First step - sort certificate
180     if (!collection.sort()) {
181         LogWarning("Certificates do not form valid chain.");
182         return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
183     }
184
185     // Check for error
186     if (collection.empty()) {
187         LogWarning("Certificate list in signature is empty.");
188         return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
189     }
190
191     CertificateList sortedCertificateList = collection.getChain();
192
193     // TODO move it to CertificateCollection
194     // Add root CA and CA certificates (if chain is incomplete)
195     sortedCertificateList =
196         OCSPCertMgrUtil::completeCertificateChain(sortedCertificateList);
197
198     CertificatePtr root = sortedCertificateList.back();
199
200     // Is Root CA certificate trusted?
201     CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
202
203     LogDebug("Is root certificate from TIZEN_DEVELOPER domain : " << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
204     LogDebug("Is root certificate from TIZEN_TEST domain      : " << storeIdSet.contains(CertStoreId::TIZEN_TEST));
205     LogDebug("Is root certificate from TIZEN_VERIFY domain    : " << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
206     LogDebug("Is root certificate from TIZEN_PUBLIC domain    : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
207     LogDebug("Is root certificate from TIZEN_PARTNER domain   : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
208     LogDebug("Is root certificate from TIZEN_PLATFORM domain  : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
209     LogDebug("Visibility level is public   : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
210     LogDebug("Visibility level is partner  : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
211         LogDebug("Visibility level is platform : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
212
213         if (data.isAuthorSignature())
214         {
215                 if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
216                 {
217                         LogWarning("author-signature.xml has got unrecognized Root CA "
218                                         "certificate. Signature will be disregarded.");
219                         disregard = true;
220                 }
221         }
222         else // distributor
223         {
224                 if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
225                 {
226                         LogWarning("distributor has author level siganture! Signature will be disregarded.");
227                         return WrtSignatureValidator::SIGNATURE_IN_DISTRIBUTOR_CASE_AUTHOR_CERT;//SIGNATURE_INVALID;
228                 }
229                 LogDebug("signaturefile name = " << data.getSignatureFileName());
230
231
232                 if (data.getSignatureNumber() == 1)
233                 {
234                         if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
235                         {
236                                 LogDebug("Root CA for signature1.xml is correct.");
237                         }
238                         else
239                         {
240                                 LogWarning("signature1.xml has got unrecognized Root CA "
241                                         "certificate. Signature will be disregarded.");
242                                 disregard = true;
243                         }
244                 }
245         }
246
247     data.setStorageType(storeIdSet);
248     data.setSortedCertificateList(sortedCertificateList);
249
250     // We add only Root CA certificate because WAC ensure that the rest
251     // of certificates are present in signature files ;-)
252     XmlSec::XmlSecContext context;
253     context.signatureFile = data.getSignatureFileName();
254     context.certificatePtr = root;
255
256     // Now we should have full certificate chain.
257     // If the end certificate is not ROOT CA we should disregard signature
258     // but still signature must be valid... Aaaaaa it's so stupid...
259     if (!(root->isSignedBy(root))) {
260         LogWarning("Root CA certificate not found. Chain is incomplete.");
261         //context.allowBrokenChain = true;
262     }
263
264     // WAC 2.0 SP-2066 The wrt must not block widget installation
265     // due to expiration of the author certificate.
266     time_t nowTime = time(NULL);
267 #define CHECK_TIME
268 #ifdef CHECK_TIME
269
270     ASN1_TIME* notAfterTime = data.getEndEntityCertificatePtr()->getNotAfterTime();
271     ASN1_TIME* notBeforeTime = data.getEndEntityCertificatePtr()->getNotBeforeTime();
272
273         if (X509_cmp_time(notBeforeTime, &nowTime) > 0  || X509_cmp_time(notAfterTime, &nowTime) < 0)
274     {
275       struct tm *t;
276       struct tm ta, tb, tc;
277       char msg[1024];
278
279       t = localtime(&nowTime);
280       if (!t)
281           return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;
282
283       memset(&tc, 0, sizeof(tc));
284
285       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
286       LogDebug("## System's currentTime : " << msg);
287       fprintf(stderr, "## System's currentTime : %s\n", msg);
288
289       tb = _ASN1_GetTimeT(notBeforeTime);
290       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
291       LogDebug("## certificate's notBeforeTime : " << msg);
292       fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
293
294       ta = _ASN1_GetTimeT(notAfterTime);
295       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
296       LogDebug("## certificate's notAfterTime : " << msg);
297       fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
298
299           if (storeIdSet.contains(CertStoreId::TIZEN_TEST) || storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
300           {
301          LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
302          fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
303          return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;//SIGNATURE_INVALID;
304       }
305
306       int year = (ta.tm_year - tb.tm_year) / 4;
307
308       if(year == 0)
309       {
310           tc.tm_year = tb.tm_year; 
311           tc.tm_mon = tb.tm_mon + 1;
312           tc.tm_mday = tb.tm_mday;
313
314           if(tc.tm_mon == 12)
315           {
316               tc.tm_year = ta.tm_year;       
317               tc.tm_mon = ta.tm_mon - 1;
318               tc.tm_mday = ta.tm_mday;
319               
320               if(tc.tm_mon < 0)
321               {
322                  tc.tm_year = ta.tm_year;
323                  tc.tm_mon = ta.tm_mon;
324                  tc.tm_mday = ta.tm_mday -1;
325
326                  if(tc.tm_mday == 0)
327                  {
328                     tc.tm_year = tb.tm_year;                
329                     tc.tm_mon = tb.tm_mon;
330                     tc.tm_mday = tb.tm_mday +1;
331                  }
332               }
333           }          
334       }
335       else{
336          tc.tm_year = tb.tm_year + year;
337          tc.tm_mon = (tb.tm_mon + ta.tm_mon )/2;
338          tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;  
339       }
340
341       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
342       LogDebug("## cmp cert with validation time : " << msg);
343       fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
344
345       time_t outCurrent = mktime(&tc);
346       context.validationTime = outCurrent;
347
348       fprintf(stderr, "## cmp outCurrent time : %ld\n", outCurrent);
349
350       //return WrtSignatureValidator::SIGNATURE_INVALID;
351     }   
352
353 #endif
354
355 #if 0
356     time_t notAfter = data.getEndEntityCertificatePtr()->getNotAfter();
357     time_t notBefore = data.getEndEntityCertificatePtr()->getNotBefore();
358
359         struct tm *t;
360
361         if (data.isAuthorSignature())
362         {
363                 // time_t 2038 year bug exist. So, notAtter() cann't check...
364                 /*
365                 if (notAfter < nowTime)
366                 {
367                         context.validationTime = notAfter - TIMET_DAY;
368                         LogWarning("Author certificate is expired. notAfter...");
369                 }
370                 */
371
372                 if (notBefore > nowTime)
373                 {
374                         LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
375
376                         t = localtime(&nowTime);
377                         LogDebug("System's current Year : " << (t->tm_year + 1900));
378                         LogDebug("System's current month : " << (t->tm_mon + 1));
379                         LogDebug("System's current day : " << (t->tm_mday));
380
381                         t = localtime(&notBefore);
382                         LogDebug("Author certificate's notBefore Year : " << (t->tm_year + 1900));
383                         LogDebug("Author certificate's notBefore month : " << (t->tm_mon + 1));
384                         LogDebug("Author certificate's notBefore day : " << (t->tm_mday));
385
386                         context.validationTime = notBefore + TIMET_DAY;
387
388                         t = localtime(&context.validationTime);
389                         LogDebug("Modified current Year : " << (t->tm_year + 1900));
390                         LogDebug("Modified current notBefore month : " << (t->tm_mon + 1));
391                         LogDebug("Modified current notBefore day : " << (t->tm_mday));
392                 }
393         }
394 #endif
395     // WAC 2.0 SP-2066 The wrt must not block widget installation
396         //context.allowBrokenChain = true;
397
398         // end
399         if (!data.isAuthorSignature())
400         {
401                 if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
402                         LogWarning("Installation break - invalid package!");
403                         return WrtSignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
404                 }
405
406                 data.setReference(context.referenceSet);
407
408                 if (!checkObjectReferences(data)) {
409                         LogWarning("Failed to check Object References");
410                         return WrtSignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
411                 }
412
413                 ReferenceValidator fileValidator(widgetContentPath);
414                 if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
415                         LogWarning("Invalid package - file references broken");
416                         return WrtSignatureValidator::SIGNATURE_INVALID_NO_HASH_FILE;//SIGNATURE_INVALID;
417                 }
418         }
419
420     if (disregard) {
421         LogWarning("Signature is disregard. RootCA is not a member of Tizen");
422         return WrtSignatureValidator::SIGNATURE_INVALID_DISTRIBUTOR_CERT;//SIGNATURE_DISREGARD;
423     }
424     return WrtSignatureValidator::SIGNATURE_VERIFIED;
425 }
426
427 class ImplWac : public WrtSignatureValidator::Impl
428 {
429 public:
430     WrtSignatureValidator::Result check(SignatureData &data,
431             const std::string &widgetContentPath);
432
433     explicit ImplWac(bool ocspEnable,
434                      bool crlEnable,
435                      bool complianceMode)
436       : Impl(ocspEnable, crlEnable, complianceMode)
437     {}
438
439     virtual ~ImplWac() {}
440 };
441
442 WrtSignatureValidator::Result ImplWac::check(
443     SignatureData &data,
444     const std::string &widgetContentPath)
445 {
446     bool disregard = false;
447
448     if (!checkRoleURI(data)) {
449         return WrtSignatureValidator::SIGNATURE_INVALID;
450     }
451
452     if (!checkProfileURI(data)) {
453         return WrtSignatureValidator::SIGNATURE_INVALID;
454     }
455
456     //  CertificateList sortedCertificateList = data.getCertList();
457
458     CertificateCollection collection;
459     collection.load(data.getCertList());
460
461     // First step - sort certificate
462     if (!collection.sort()) {
463         LogWarning("Certificates do not form valid chain.");
464         return WrtSignatureValidator::SIGNATURE_INVALID;
465     }
466
467     // Check for error
468     if (collection.empty()) {
469         LogWarning("Certificate list in signature is empty.");
470         return WrtSignatureValidator::SIGNATURE_INVALID;
471     }
472
473     CertificateList sortedCertificateList = collection.getChain();
474
475     // TODO move it to CertificateCollection
476     // Add root CA and CA certificates (if chain is incomplete)
477     sortedCertificateList =
478         OCSPCertMgrUtil::completeCertificateChain(sortedCertificateList);
479
480     CertificatePtr root = sortedCertificateList.back();
481
482     // Is Root CA certificate trusted?
483     CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
484
485     LogDebug("Is root certificate from TIZEN_DEVELOPER domain : " << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
486     LogDebug("Is root certificate from TIZEN_TEST domain      : " << storeIdSet.contains(CertStoreId::TIZEN_TEST));
487     LogDebug("Is root certificate from TIZEN_VERIFY domain    : " << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
488     LogDebug("Is root certificate from TIZEN_PUBLIC domain    : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
489     LogDebug("Is root certificate from TIZEN_PARTNER domain   : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
490     LogDebug("Is root certificate from TIZEN_PLATFORM domain  : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
491     LogDebug("Visibility level is public   : " << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
492     LogDebug("Visibility level is partner  : " << storeIdSet.contains(CertStoreId::VIS_PARTNER));
493         LogDebug("Visibility level is platform : " << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
494
495         if (data.isAuthorSignature())
496         {
497                 if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
498                 {
499                         LogWarning("author-signature.xml has got unrecognized Root CA "
500                                         "certificate. Signature will be disregarded.");
501                         disregard = true;
502                 }
503         }
504         else
505         {
506                 if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
507                 {
508                         LogWarning("distributor has author level siganture! Signature will be disregarded.");
509                         return WrtSignatureValidator::SIGNATURE_INVALID;
510                 }
511                 LogDebug("signaturefile name = " << data.getSignatureFileName());
512
513                 if (data.getSignatureNumber() == 1)
514                 {
515                         if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
516                         {
517                                 LogDebug("Root CA for signature1.xml is correct.");
518                         }
519                         else
520                         {
521                                 LogWarning("signature1.xml has got unrecognized Root CA "
522                                         "certificate. Signature will be disregarded.");
523                                 disregard = true;
524                         }
525                 }
526         }
527
528     data.setStorageType(storeIdSet);
529     data.setSortedCertificateList(sortedCertificateList);
530
531     // We add only Root CA certificate because WAC ensure that the rest
532     // of certificates are present in signature files ;-)
533     XmlSec::XmlSecContext context;
534     context.signatureFile = data.getSignatureFileName();
535     context.certificatePtr = root;
536
537     // Now we should have full certificate chain.
538     // If the end certificate is not ROOT CA we should disregard signature
539     // but still signature must be valid... Aaaaaa it's so stupid...
540     if (!(root->isSignedBy(root))) {
541         LogWarning("Root CA certificate not found. Chain is incomplete.");
542 //        context.allowBrokenChain = true;
543     }
544
545     time_t nowTime = time(NULL);
546     // WAC 2.0 SP-2066 The wrt must not block widget installation
547         // due to expiration of the author certificate.
548 #define CHECK_TIME
549 #ifdef CHECK_TIME
550
551     ASN1_TIME* notAfterTime = data.getEndEntityCertificatePtr()->getNotAfterTime();
552     ASN1_TIME* notBeforeTime = data.getEndEntityCertificatePtr()->getNotBeforeTime();
553
554                 if (X509_cmp_time(notBeforeTime, &nowTime) > 0  || X509_cmp_time(notAfterTime, &nowTime) < 0)
555     {
556       struct tm *t;
557       struct tm ta, tb, tc;
558       char msg[1024];
559
560       t = localtime(&nowTime);
561       if (!t)
562           return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;
563
564       memset(&tc, 0, sizeof(tc));
565
566       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
567       LogDebug("## System's currentTime : " << msg);
568       fprintf(stderr, "## System's currentTime : %s\n", msg);
569
570       tb = _ASN1_GetTimeT(notBeforeTime);
571       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
572       LogDebug("## certificate's notBeforeTime : " << msg);
573       fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
574
575       ta = _ASN1_GetTimeT(notAfterTime);
576       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
577       LogDebug("## certificate's notAfterTime : " << msg);
578       fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
579
580       if (storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
581       {
582          LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
583          fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
584          return WrtSignatureValidator::SIGNATURE_INVALID;
585       }
586
587       int year = (ta.tm_year - tb.tm_year) / 4;
588
589       if(year == 0)
590       {
591           tc.tm_year = tb.tm_year; 
592           tc.tm_mon = tb.tm_mon + 1;
593           tc.tm_mday = tb.tm_mday;
594
595           if(tc.tm_mon == 12)
596           {
597               tc.tm_year = ta.tm_year;       
598               tc.tm_mon = ta.tm_mon - 1;
599               tc.tm_mday = ta.tm_mday;
600               
601               if(tc.tm_mon < 0)
602               {
603                  tc.tm_year = ta.tm_year;
604                  tc.tm_mon = ta.tm_mon;
605                  tc.tm_mday = ta.tm_mday -1;
606
607                  if(tc.tm_mday == 0)
608                  {
609                     tc.tm_year = tb.tm_year;                
610                     tc.tm_mon = tb.tm_mon;
611                     tc.tm_mday = tb.tm_mday +1;
612                  }
613               }
614           }          
615       }
616       else{
617          tc.tm_year = tb.tm_year + year;
618          tc.tm_mon = (tb.tm_mon + ta.tm_mon )/2;
619          tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;  
620       }
621
622       snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
623       LogDebug("## cmp cert with validation time : " << msg);
624       fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
625
626       time_t outCurrent = mktime(&tc);
627
628       fprintf(stderr, "## cmp outCurrent time : %ld\n", outCurrent);
629
630       context.validationTime = outCurrent;
631       //return WrtSignatureValidator::SIGNATURE_INVALID;
632     }   
633
634 #endif
635
636 #if 0
637         time_t notAfter = data.getEndEntityCertificatePtr()->getNotAfter();
638         time_t notBefore = data.getEndEntityCertificatePtr()->getNotBefore();
639
640         struct tm *t;
641
642         if (data.isAuthorSignature())
643         {
644                 // time_t 2038 year bug exist. So, notAtter() cann't check...
645                 /*
646                 if (notAfter < nowTime)
647                 {
648                         context.validationTime = notAfter - TIMET_DAY;
649                         LogWarning("Author certificate is expired. notAfter...");
650                  }
651                  */
652
653                 if (notBefore > nowTime)
654                 {
655                         LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
656
657                         t = localtime(&nowTime);
658                         LogDebug("System's current Year : " << (t->tm_year + 1900));
659                         LogDebug("System's current month : " << (t->tm_mon + 1));
660                         LogDebug("System's current day : " << (t->tm_mday));
661
662                         t = localtime(&notBefore);
663                         LogDebug("Author certificate's notBefore Year : " << (t->tm_year + 1900));
664                         LogDebug("Author certificate's notBefore month : " << (t->tm_mon + 1));
665                         LogDebug("Author certificate's notBefore day : " << (t->tm_mday));
666
667                         context.validationTime = notBefore + TIMET_DAY;
668
669                         t = localtime(&context.validationTime);
670                         LogDebug("Modified current Year : " << (t->tm_year + 1900));
671                         LogDebug("Modified current notBefore month : " << (t->tm_mon + 1));
672                         LogDebug("Modified current notBefore day : " << (t->tm_mday));
673                 }
674         }
675 #endif
676
677         if (!data.isAuthorSignature())
678         {
679                 if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
680                         LogWarning("Installation break - invalid package!");
681                         return WrtSignatureValidator::SIGNATURE_INVALID;
682                 }
683
684                 data.setReference(context.referenceSet);
685
686                 if (!checkObjectReferences(data)) {
687                         return WrtSignatureValidator::SIGNATURE_INVALID;
688                 }
689
690                 ReferenceValidator fileValidator(widgetContentPath);
691                 if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
692                         LogWarning("Invalid package - file references broken");
693                         return WrtSignatureValidator::SIGNATURE_INVALID;
694                 }
695         }
696
697     if (disregard) {
698         LogWarning("Signature is disregard. RootCA is not a member of Tizen.");
699         return WrtSignatureValidator::SIGNATURE_DISREGARD;
700     }
701     return WrtSignatureValidator::SIGNATURE_VERIFIED;
702 }
703
704 // Implementation of WrtSignatureValidator
705
706 WrtSignatureValidator::WrtSignatureValidator(
707     AppType appType,
708     bool ocspEnable,
709     bool crlEnable,
710     bool complianceMode)
711   : m_impl(0)
712 {
713     if (appType == TIZEN)
714         m_impl = new ImplTizen(ocspEnable,crlEnable,complianceMode);
715     else
716         m_impl = new ImplWac(ocspEnable,crlEnable,complianceMode);
717 }
718
719 WrtSignatureValidator::~WrtSignatureValidator()
720 {
721     delete m_impl;
722 }
723
724 WrtSignatureValidator::Result WrtSignatureValidator::check(
725     SignatureData &data,
726     const std::string &widgetContentPath)
727 {
728     return m_impl->check(data, widgetContentPath);
729 }
730
731 } // namespace ValidationCore
732