2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file CachedOCSP.cpp
19 * @author Tomasz Swierczek (t.swierczek@samsung.com)
21 * @brief Cached OCSP class implementation
27 #include <dpl/foreach.h>
28 #include <dpl/log/log.h>
30 #include <vcore/OCSP.h>
31 #include <vcore/OCSPImpl.h>
32 #include <vcore/CachedOCSP.h>
33 #include <vcore/Certificate.h>
34 #include <vcore/CertificateCacheDAO.h>
38 // one hour in seconds
39 const time_t OCSP_minTimeValid = 3600; // one hour in seconds
41 // one week in seconds
42 const time_t OCSP_maxTimeValid = 3600 * 24 * 7;
44 // one hour in seconds
45 const time_t OCSP_refreshBefore = 3600;
47 } // anonymous namespace
49 namespace ValidationCore {
51 time_t CachedOCSP::getOCSPMinTimeValid() {
52 return OCSP_minTimeValid;
55 time_t CachedOCSP::getOCSPMaxTimeValid() {
56 return OCSP_maxTimeValid;
59 time_t CachedOCSP::getOCSPRefreshBefore() {
60 return OCSP_refreshBefore;
63 CachedOCSP::CachedOCSP(){}
65 CachedOCSP::~CachedOCSP(){}
67 VerificationStatus CachedOCSP::check(const CertificateCollection &certs)
69 OCSPCachedStatus db_status;
73 db_status.cert_chain = certs.toBase64String();
74 db_status.end_entity_check = false;
76 if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
77 LogDebug("Found cache entry for OCSP");
78 if (now < db_status.next_update_time) {
79 LogDebug("Cache response valid");
80 return db_status.ocsp_status;
84 // here we need to get OCSP result and add/update cache
86 CertificateList list = certs.getChain();
87 ocsp.setTrustedStore(list);
89 VerificationStatusSet statusSet = ocsp.validateCertificateList(list);
90 db_status.ocsp_status = statusSet.convertToStatus();
91 db_status.next_update_time = ocsp.getResponseValidity();
92 CertificateCacheDAO::setOCSPStatus(db_status.cert_chain,
93 db_status.ocsp_status,
94 db_status.end_entity_check,
97 db_status.next_update_time));
98 return db_status.ocsp_status;
101 VerificationStatus CachedOCSP::checkEndEntity(CertificateCollection &certs)
103 OCSPCachedStatus db_status;
107 db_status.cert_chain = certs.toBase64String();
108 db_status.end_entity_check = true;
110 if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
111 LogDebug("Found cache entry for OCSP");
112 if (now < db_status.next_update_time) {
113 LogDebug("Cache response valid");
114 return db_status.ocsp_status;
118 // here we need to send request via OCSP and add/update cache
119 CertificateList clst;
120 getCertsForEndEntity(certs, &clst);
123 ocsp.setTrustedStore(certs.getCertificateList());
125 VerificationStatusSet statusSet = ocsp.validateCertificateList(clst);
126 db_status.ocsp_status = statusSet.convertToStatus();
127 db_status.next_update_time = ocsp.getResponseValidity();
129 CertificateCacheDAO::setOCSPStatus(db_status.cert_chain,
130 db_status.ocsp_status,
131 db_status.end_entity_check,
134 db_status.next_update_time));
136 return db_status.ocsp_status;
139 void CachedOCSP::updateCache()
143 now += OCSP_refreshBefore;
144 OCSPCachedStatusList list;
145 CertificateCacheDAO::getOCSPStatusList(&list);
146 FOREACH(db_status, list) {
147 if (now >= db_status->next_update_time) {
148 // this response needs to be refreshed
149 CertificateCollection col;
150 col.load(db_status->cert_chain);
152 LogError("Certificate collection does not create chain.");
157 CertificateList chain = col.getChain();
158 ocsp.setTrustedStore(chain);
160 VerificationStatusSet statusSet;
162 if (db_status->end_entity_check) {
163 CertificateList clst;
164 getCertsForEndEntity(col, &clst);
165 statusSet = ocsp.validateCertificateList(clst);
167 statusSet = ocsp.validateCertificateList(chain);
170 db_status->ocsp_status = statusSet.convertToStatus();
171 db_status->next_update_time = ocsp.getResponseValidity();
173 CertificateCacheDAO::setOCSPStatus(db_status->cert_chain,
174 db_status->ocsp_status,
175 db_status->end_entity_check,
176 db_status->next_update_time);
181 void CachedOCSP::getCertsForEndEntity(
182 const CertificateCollection &certs, CertificateList* clst)
185 LogError("NULL pointer");
189 if (certs.isChain() && certs.size() >= 2) {
190 CertificateList::const_iterator icert = certs.begin();
191 clst->push_back(*icert);
193 clst->push_back(*icert);
197 time_t CachedOCSP::getNextUpdateTime(time_t now, time_t response_validity)
199 long min = now + OCSP_minTimeValid;
200 long max = now + OCSP_maxTimeValid;
201 if (response_validity < min) {
204 if (response_validity > max) {
207 return response_validity;
210 } // namespace ValidationCore