tizen beta release
[framework/web/wrt-commons.git] / modules / vcore / src / vcore / CachedCRL.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  *
18  * @file       CachedCRL.cpp
19  * @author     Tomasz Swierczek (t.swierczek@samsung.com)
20  * @version    0.1
21  * @brief      Cached CRL class implementation
22  */
23
24 #include <string>
25 #include <time.h>
26
27 #include <dpl/foreach.h>
28 #include <dpl/log/log.h>
29 #include <dpl/foreach.h>
30
31 #include "CRL.h"
32 #include "CachedCRL.h"
33 #include "Certificate.h"
34 #include "CertificateCacheDAO.h"
35
36 namespace ValidationCore {
37
38 const time_t CachedCRL::CRL_minTimeValid = 3600;          // one hour in seconds
39
40 const time_t CachedCRL::CRL_maxTimeValid = 3600 * 24 * 7; // one week in seconds
41
42 const time_t CachedCRL::CRL_refreshBefore = 3600;         // one hour in seconds
43
44 VerificationStatus CachedCRL::check(const CertificateCollection &certs)
45 {
46     CRL crl;
47     bool allValid = true;
48     // we dont check CRL validity since
49     // we may use crl for longer time
50     // in smart cache than in regular CRL class (time clamping)
51     crl.addToStore(certs);
52     FOREACH(cert, certs){
53         CRL::StringList crlUris = crl.getCrlUris(*cert);
54         FOREACH(uri, crlUris) {
55             allValid = allValid && updateCRLForUri(*uri,false);
56         }
57     }
58     if (!allValid) {
59         // problems with CRL validity
60         LogDebug("Some CRLs not valid");
61     }
62     CRL::RevocationStatus stat = crl.checkCertificateChain(certs);
63     if (stat.isRevoked) {
64         LogDebug("Status REVOKED");
65         return VERIFICATION_STATUS_REVOKED;
66     }
67     LogDebug("Status GOOD");
68     return VERIFICATION_STATUS_GOOD;
69 }
70
71 VerificationStatus CachedCRL::checkEndEntity(CertificateCollection &certs)
72 {
73     if (certs.empty()) {
74         LogError("Collection empty. This should never happen.");
75         LogDebug("Status ERROR");
76         return VERIFICATION_STATUS_ERROR;
77     }
78     if (!certs.sort()) {
79         LogError("Could not find End Entity certificate. "
80                 "Collection does not form chain.");
81         LogDebug("Status ERROR");
82         return VERIFICATION_STATUS_ERROR;
83     }
84     CRL crl;
85     bool allValid = true;
86     // we dont check CRL validity since
87     // we may use crl for longer time
88     // in smart cache than in regular CRL class (time clamping)
89     crl.addToStore(certs);
90     CertificateList::const_iterator icert = certs.begin();
91     if (icert != certs.end()) {
92         CRL::StringList crlUris = crl.getCrlUris(*icert);
93         FOREACH(uri, crlUris) {
94             allValid = allValid && updateCRLForUri(*uri,false);
95         }
96     }
97     if (!allValid) {
98         // problems with CRL validity
99         LogDebug("Some CRLs not valid");
100     }
101     CertificateList::const_iterator iter = certs.begin();
102     CRL::RevocationStatus stat = crl.checkCertificate(*iter);
103     if (stat.isRevoked) {
104         LogDebug("Status REVOKED");
105         return VERIFICATION_STATUS_REVOKED;
106     }
107     LogDebug("Status GOOD");
108     return VERIFICATION_STATUS_GOOD;
109 }
110
111 void CachedCRL::updateCache()
112 {
113     CRLCachedDataList list;
114     CertificateCacheDAO::getCRLResponseList(&list);
115     FOREACH(db_crl, list) {
116         updateCRLForUri(db_crl->distribution_point, true);
117     }
118 }
119
120 bool CachedCRL::updateCRLForUri(const std::string & uri, bool useExpiredShift)
121 {
122     CRLCachedData cachedCRL;
123     cachedCRL.distribution_point = uri;
124     time_t now;
125     time(&now);
126     if (useExpiredShift) {
127         now += CRL_refreshBefore;
128     }
129     if (CertificateCacheDAO::getCRLResponse(&cachedCRL)) {
130         if (now < cachedCRL.next_update_time) {
131             LogDebug("Cached CRL still valid for: " << uri);
132             return true;
133         }
134     }
135     // need to download new CRL
136     CRL crl;
137     CRL::CRLDataPtr list = crl.downloadCRL(uri);
138     if (!list) {
139         LogWarning("Could not retreive CRL from " << uri);
140         return false;
141     }
142     crl.updateCRL(list);
143     CertificateCacheDAO::getCRLResponse(&cachedCRL); // save it the way CRL does
144     cachedCRL.next_update_time =
145             getNextUpdateTime(now,cachedCRL.next_update_time);
146     CertificateCacheDAO::setCRLResponse(cachedCRL.distribution_point,
147                                         cachedCRL.crl_body,
148                                         cachedCRL.next_update_time);
149     return true;
150 }
151
152 time_t CachedCRL::getNextUpdateTime(time_t now, time_t response_validity)
153 {
154     time_t min = now + CRL_minTimeValid;
155     time_t max = now + CRL_maxTimeValid;
156     if (response_validity < min) {
157         return min;
158     }
159     if (response_validity > max) {
160         return max;
161     }
162     return response_validity;
163 }
164
165 } // namespace ValidationCore