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,
30 unsigned char **pkcs7_buf)
const {
31 *plain_size = plain_size_;
32 *pkcs7_size = pkcs7_size_;
35 if (plain_size_ > 0) {
36 *plain_buf =
reinterpret_cast<unsigned char *
>(smalloc(plain_size_));
37 memcpy(*plain_buf, plain_buf_, plain_size_);
39 if (pkcs7_size_ > 0) {
40 *pkcs7_buf =
reinterpret_cast<unsigned char *
>(smalloc(pkcs7_size_));
41 memcpy(*pkcs7_buf, pkcs7_buf_, pkcs7_size_);
46 std::string Whitelist::CreateString(
47 const std::string &fqrn,
53 + validity_days * 24 * 3600)
54 +
"\n" +
"N" + fqrn +
"\n"
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()),
68 hash_str.length(), &signature, &signature_size);
70 whitelist += std::string(reinterpret_cast<char *>(signature), signature_size);
77 std::string Whitelist::ExportString()
const {
78 if (plain_buf_ == NULL)
80 return std::string(reinterpret_cast<char *>(plain_buf_), plain_size_);
84 time_t Whitelist::expires()
const {
85 assert(status_ == kStAvailable);
90 bool Whitelist::IsExpired()
const {
91 assert(status_ == kStAvailable);
92 return time(NULL) > expires_;
96 Failures Whitelist::VerifyLoadedCertificate()
const {
97 assert(status_ == kStAvailable);
99 vector<string> blacklist = signature_manager_->GetBlacklist();
100 for (
unsigned i = 0; i < blacklist.size(); ++i) {
107 if (this_hash == signature_manager_->HashCertificate(algorithm))
111 for (
unsigned i = 0; i < fingerprints_.size(); ++i) {
113 if (signature_manager_->HashCertificate(algorithm) == fingerprints_[i]) {
114 if (verification_flags_ & kFlagVerifyCaChain) {
115 bool retval = signature_manager_->VerifyCaChain();
134 assert(verification_flags_ != 0);
136 if (verification_flags_ & kFlagVerifyRsa) {
137 retval_b = signature_manager_->VerifyLetter(plain_buf_, plain_size_,
true);
144 if (verification_flags_ & kFlagVerifyPkcs7) {
145 unsigned char *extracted_whitelist;
146 unsigned extracted_whitelist_size;
147 vector<string> alt_uris;
148 retval_b = signature_manager_->VerifyPkcs7(
149 pkcs7_buf_, pkcs7_size_, &extracted_whitelist,
150 &extracted_whitelist_size, &alt_uris);
153 "failed to verify repository whitelist (pkcs#7): %s",
154 signature_manager_->GetCryptoError().c_str());
159 bool found_uri =
false;
160 for (
unsigned i = 0; i < alt_uris.size(); ++i) {
162 alt_uris[i].c_str());
163 if (alt_uris[i] ==
"cvmfs:" + fqrn_) {
170 "failed to find whitelist signer with SAN/URI cvmfs:%s",
172 free(extracted_whitelist);
179 string(reinterpret_cast<char *>(extracted_whitelist),
180 extracted_whitelist_size)
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");
227 retval_dl = download_manager_->Fetch(&download_whitelist);
230 plain_size_ = whitelist_memsink.
pos();
231 if (plain_size_ == 0)
234 plain_buf_ = whitelist_memsink.
data();
236 retval_wl = ParseWhitelist(plain_buf_, plain_size_);
240 if (verification_flags_ & kFlagVerifyPkcs7) {
242 const string whitelist_pkcs7_url = base_url
243 + string(
"cvmfswhitelist.pkcs7");
246 &whitelist_pkcs7_url,
false, probe_hosts, NULL, &pkcs7_memsink);
247 retval_dl = download_manager_->Fetch(&download_whitelist_pkcs7);
250 pkcs7_size_ = pkcs7_memsink.
pos();
251 if (pkcs7_size_ == 0)
254 pkcs7_buf_ = pkcs7_memsink.
data();
257 return VerifyWhitelist();
265 bool Whitelist::IsBefore(time_t now,
const struct tm &t_whitelist) {
267 if (gmtime_r(&now, &t_local) == NULL)
269 if (t_local.tm_year < t_whitelist.tm_year)
271 if (t_local.tm_year > t_whitelist.tm_year)
273 if (t_local.tm_mon < t_whitelist.tm_mon)
275 if (t_local.tm_mon > t_whitelist.tm_mon)
277 if (t_local.tm_mday < t_whitelist.tm_mday)
279 if (t_local.tm_mday > t_whitelist.tm_mday)
281 if (t_local.tm_hour < t_whitelist.tm_hour)
288 const unsigned whitelist_size) {
289 time_t local_timestamp = time(NULL);
291 unsigned payload_bytes = 0;
292 bool verify_pkcs7 =
false;
293 bool verify_cachain =
false;
296 line =
GetLineMem(reinterpret_cast<const char *>(whitelist), whitelist_size);
297 if (line.length() != 14) {
304 line =
GetLineMem(reinterpret_cast<const char *>(whitelist) + payload_bytes,
305 whitelist_size - payload_bytes);
306 if (line.length() != 15) {
311 memset(&tm_wl, 0,
sizeof(
struct tm));
316 tm_wl.tm_min = tm_wl.tm_sec = 0;
317 time_t timestamp = timegm(&tm_wl);
319 "whitelist UTC expiry timestamp in localtime: %s",
325 if (!IsBefore(local_timestamp, tm_wl)) {
327 "whitelist lifetime verification failed, expired");
339 expires_ = timestamp;
343 line =
GetLineMem(reinterpret_cast<const char *>(whitelist) + payload_bytes,
344 whitelist_size - payload_bytes);
345 if ((fqrn_ !=
"") && (
"N" + fqrn_ != line)) {
347 "repository name on the whitelist does not match "
348 "(found %s, expected %s)",
349 line.c_str(), fqrn_.c_str());
352 payload_bytes += line.length() + 1;
355 line =
GetLineMem(reinterpret_cast<const char *>(whitelist) + payload_bytes,
356 whitelist_size - payload_bytes);
357 if (line ==
"Vpkcs7") {
360 payload_bytes += line.length() + 1;
361 line =
GetLineMem(reinterpret_cast<const char *>(whitelist) + payload_bytes,
362 whitelist_size - payload_bytes);
366 line =
GetLineMem(reinterpret_cast<const char *>(whitelist) + payload_bytes,
367 whitelist_size - payload_bytes);
368 if (line ==
"Wcachain") {
370 "whitelist imposes ca chain verification of manifest signature");
371 verify_cachain =
true;
372 payload_bytes += line.length() + 1;
373 line =
GetLineMem(reinterpret_cast<const char *>(whitelist) + payload_bytes,
374 whitelist_size - payload_bytes);
382 fingerprints_.push_back(this_hash);
384 payload_bytes += line.length() + 1;
385 line =
GetLineMem(reinterpret_cast<const char *>(whitelist) + payload_bytes,
386 whitelist_size - payload_bytes);
387 }
while (payload_bytes < whitelist_size);
389 verification_flags_ = verify_pkcs7 ? kFlagVerifyPkcs7 : kFlagVerifyRsa;
391 verification_flags_ |= kFlagVerifyCaChain;
396 void Whitelist::Reset() {
398 fingerprints_.clear();
400 verification_flags_ = 0;
412 Whitelist::Whitelist(
const string &fqrn,
416 , download_manager_(download_manager)
417 , signature_manager_(signature_manager)
428 , download_manager_(other.download_manager_)
429 , signature_manager_(other.signature_manager_)
430 , status_(other.status_)
431 , fingerprints_(other.fingerprints_)
432 , expires_(other.expires_)
433 , verification_flags_(other.verification_flags_) {
440 : download_manager_(NULL)
441 , signature_manager_(NULL)
444 , verification_flags_(0)
void HashString(const std::string &content, Any *any_digest)
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)
std::string FingerprintCertificate(const shash::Algorithms hash_algorithm)
std::vector< shash::Any > fingerprints_
signature::SignatureManager * signature_manager_
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)