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