5 #include "cvmfs_config.h"
23 const int Whitelist::kFlagVerifyRsa = 0x01;
24 const int Whitelist::kFlagVerifyPkcs7 = 0x02;
25 const int Whitelist::kFlagVerifyCaChain = 0x04;
28 void Whitelist::CopyBuffers(
unsigned *plain_size,
unsigned char **plain_buf,
29 unsigned *pkcs7_size,
unsigned char **pkcs7_buf)
32 *plain_size = plain_size_;
33 *pkcs7_size = pkcs7_size_;
36 if (plain_size_ > 0) {
37 *plain_buf =
reinterpret_cast<unsigned char *
>(smalloc(plain_size_));
38 memcpy(*plain_buf, plain_buf_, plain_size_);
40 if (pkcs7_size_ > 0) {
41 *pkcs7_buf =
reinterpret_cast<unsigned char *
>(smalloc(pkcs7_size_));
42 memcpy(*pkcs7_buf, pkcs7_buf_, pkcs7_size_);
47 std::string Whitelist::CreateString(
48 const std::string &fqrn,
60 std::string hash_str = hash.
ToString();
63 whitelist +=
"--\n" + hash_str +
"\n";
64 unsigned char *signature;
65 unsigned signature_size;
66 bool retval = signature_manager->
SignRsa(
67 reinterpret_cast<const unsigned char *>(hash_str.data()), hash_str.length(),
68 &signature, &signature_size);
70 whitelist += std::string(reinterpret_cast<char *>(signature), signature_size);
77 std::string Whitelist::ExportString()
const {
78 if (plain_buf_ == NULL)
return "";
79 return std::string(reinterpret_cast<char *>(plain_buf_), plain_size_);
83 time_t Whitelist::expires()
const {
84 assert(status_ == kStAvailable);
89 bool Whitelist::IsExpired()
const {
90 assert(status_ == kStAvailable);
91 return time(NULL) > expires_;
95 Failures Whitelist::VerifyLoadedCertificate()
const {
96 assert(status_ == kStAvailable);
98 vector<string> blacklist = signature_manager_->GetBlacklist();
99 for (
unsigned i = 0; i < blacklist.size(); ++i) {
106 if (this_hash == signature_manager_->HashCertificate(algorithm))
110 for (
unsigned i = 0; i < fingerprints_.size(); ++i) {
112 if (signature_manager_->HashCertificate(algorithm) == fingerprints_[i]) {
113 if (verification_flags_ & kFlagVerifyCaChain) {
114 bool retval = signature_manager_->VerifyCaChain();
133 assert(verification_flags_ != 0);
135 if (verification_flags_ & kFlagVerifyRsa) {
136 retval_b = signature_manager_->VerifyLetter(plain_buf_, plain_size_,
true);
143 if (verification_flags_ & kFlagVerifyPkcs7) {
144 unsigned char *extracted_whitelist;
145 unsigned extracted_whitelist_size;
146 vector<string> alt_uris;
148 signature_manager_->VerifyPkcs7(pkcs7_buf_, pkcs7_size_,
149 &extracted_whitelist,
150 &extracted_whitelist_size,
154 "failed to verify repository whitelist (pkcs#7): %s",
155 signature_manager_->GetCryptoError().c_str());
160 bool found_uri =
false;
161 for (
unsigned i = 0; i < alt_uris.size(); ++i) {
163 alt_uris[i].c_str());
164 if (alt_uris[i] ==
"cvmfs:" + fqrn_) {
171 "failed to find whitelist signer with SAN/URI cvmfs:%s",
173 free(extracted_whitelist);
180 string(reinterpret_cast<char *>(extracted_whitelist),
181 extracted_whitelist_size).c_str());
182 retval_wl = ParseWhitelist(extracted_whitelist, extracted_whitelist_size);
185 "failed to verify repository certificate against pkcs#7 "
191 status_ = kStAvailable;
201 plain_size_ = whitelist.length();
202 plain_buf_ =
reinterpret_cast<unsigned char *
>(smalloc(plain_size_));
203 memcpy(plain_buf_, whitelist.data(), plain_size_);
205 retval_wl = ParseWhitelist(plain_buf_, plain_size_);
209 if (verification_flags_ & kFlagVerifyPkcs7)
212 return VerifyWhitelist();
216 Failures Whitelist::LoadUrl(
const std::string &base_url) {
217 const bool probe_hosts = base_url ==
"";
223 const string whitelist_url = base_url + string(
"/.cvmfswhitelist");
225 false, probe_hosts, NULL);
226 retval_dl = download_manager_->Fetch(&download_whitelist);
230 if (plain_size_ == 0)
235 retval_wl = ParseWhitelist(plain_buf_, plain_size_);
239 if (verification_flags_ & kFlagVerifyPkcs7) {
241 const string whitelist_pkcs7_url =
242 base_url + string(
"cvmfswhitelist.pkcs7");
245 retval_dl = download_manager_->Fetch(&download_whitelist_pkcs7);
249 if (pkcs7_size_ == 0)
251 pkcs7_buf_ =
reinterpret_cast<unsigned char *
>
255 return VerifyWhitelist();
263 bool Whitelist::IsBefore(time_t now,
const struct tm &t_whitelist) {
265 if (gmtime_r(&now, &t_local) == NULL)
267 if (t_local.tm_year < t_whitelist.tm_year)
return true;
268 if (t_local.tm_year > t_whitelist.tm_year)
return false;
269 if (t_local.tm_mon < t_whitelist.tm_mon)
return true;
270 if (t_local.tm_mon > t_whitelist.tm_mon)
return false;
271 if (t_local.tm_mday < t_whitelist.tm_mday)
return true;
272 if (t_local.tm_mday > t_whitelist.tm_mday)
return false;
273 if (t_local.tm_hour < t_whitelist.tm_hour)
return true;
279 const unsigned whitelist_size)
281 time_t local_timestamp = time(NULL);
283 unsigned payload_bytes = 0;
284 bool verify_pkcs7 =
false;
285 bool verify_cachain =
false;
288 line =
GetLineMem(reinterpret_cast<const char *>(whitelist), whitelist_size);
289 if (line.length() != 14) {
296 line =
GetLineMem(reinterpret_cast<const char *>(whitelist)+payload_bytes,
297 whitelist_size-payload_bytes);
298 if (line.length() != 15) {
303 memset(&tm_wl, 0,
sizeof(
struct tm));
308 tm_wl.tm_min = tm_wl.tm_sec = 0;
309 time_t timestamp = timegm(&tm_wl);
311 "whitelist UTC expiry timestamp in localtime: %s",
317 if (!IsBefore(local_timestamp, tm_wl)) {
319 "whitelist lifetime verification failed, expired");
331 expires_ = timestamp;
335 line =
GetLineMem(reinterpret_cast<const char *>(whitelist)+payload_bytes,
336 whitelist_size-payload_bytes);
337 if ((fqrn_ !=
"") && (
"N" + fqrn_ != line)) {
339 "repository name on the whitelist does not match "
340 "(found %s, expected %s)",
341 line.c_str(), fqrn_.c_str());
344 payload_bytes += line.length() + 1;
347 line =
GetLineMem(reinterpret_cast<const char *>(whitelist)+payload_bytes,
348 whitelist_size-payload_bytes);
349 if (line ==
"Vpkcs7") {
352 payload_bytes += line.length() + 1;
353 line =
GetLineMem(reinterpret_cast<const char *>(whitelist)+payload_bytes,
354 whitelist_size-payload_bytes);
358 line =
GetLineMem(reinterpret_cast<const char *>(whitelist)+payload_bytes,
359 whitelist_size-payload_bytes);
360 if (line ==
"Wcachain") {
362 "whitelist imposes ca chain verification of manifest signature");
363 verify_cachain =
true;
364 payload_bytes += line.length() + 1;
365 line =
GetLineMem(reinterpret_cast<const char *>(whitelist)+payload_bytes,
366 whitelist_size-payload_bytes);
370 if (line ==
"--")
break;
373 fingerprints_.push_back(this_hash);
375 payload_bytes += line.length() + 1;
376 line =
GetLineMem(reinterpret_cast<const char *>(whitelist)+payload_bytes,
377 whitelist_size-payload_bytes);
378 }
while (payload_bytes < whitelist_size);
380 verification_flags_ = verify_pkcs7 ? kFlagVerifyPkcs7 : kFlagVerifyRsa;
382 verification_flags_ |= kFlagVerifyCaChain;
387 void Whitelist::Reset() {
389 fingerprints_.clear();
391 verification_flags_ = 0;
403 Whitelist::Whitelist(
const string &fqrn,
407 download_manager_(download_manager),
408 signature_manager_(signature_manager),
420 download_manager_(other.download_manager_),
421 signature_manager_(other.signature_manager_),
422 status_(other.status_),
423 fingerprints_(other.fingerprints_),
424 expires_(other.expires_),
425 verification_flags_(other.verification_flags_)
433 : download_manager_(NULL)
434 , signature_manager_(NULL)
437 , verification_flags_(0)
void HashString(const std::string &content, Any *any_digest)
#define LogCvmfs(source, mask,...)
bool SignRsa(const unsigned char *buffer, const unsigned buffer_size, unsigned char **signature, unsigned *signature_size)
string GetLineMem(const char *text, const int text_size)
static shash::Any MkFromFingerprint(const std::string &fingerprint)
std::string ToString(const bool with_suffix=false) const
unsigned char * pkcs7_buf_
void CopyBuffers(unsigned *plain_size, unsigned char **plain_buf, unsigned *pkcs7_size, unsigned char **pkcs7_buf) const
assert((mem||(size==0))&&"Out Of Memory")
string StringifyTime(const time_t seconds, const bool utc)
unsigned char * plain_buf_
int64_t String2Int64(const string &value)
std::string WhitelistTimestamp(time_t when)
download::DownloadManager * download_manager_
const whitelist::Whitelist * whitelist() const
Whitelist & operator=(const Whitelist &other)
struct download::JobInfo::@4 destination_mem
std::string FingerprintCertificate(const shash::Algorithms hash_algorithm)
std::vector< shash::Any > fingerprints_
signature::SignatureManager * signature_manager_