CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
signature.cc
Go to the documentation of this file.
1 
15 #include "crypto/signature.h"
16 
17 #include <openssl/bn.h>
18 #include <openssl/evp.h>
19 #include <openssl/pkcs7.h>
20 #include <openssl/x509v3.h>
21 
22 #include <cassert>
23 #include <cctype>
24 #include <cstdio>
25 #include <cstdlib>
26 #include <cstring>
27 #include <string>
28 #include <vector>
29 
30 #include "crypto/hash.h"
31 #include "crypto/openssl_version.h"
32 #include "util/concurrency.h"
33 #include "util/logging.h"
34 #include "util/platform.h"
35 #include "util/posix.h"
36 #include "util/prng.h"
37 #include "util/smalloc.h"
38 #include "util/string.h"
39 
40 using namespace std; // NOLINT
41 
42 namespace signature {
43 
44 const char *kDefaultPublicKey = "/etc/cvmfs/keys/cern.ch/cern-it4.pub";
45 
46 
47 static int CallbackCertVerify(int ok, X509_STORE_CTX *ctx) {
48  LogCvmfs(kLogCvmfs, kLogDebug, "certificate chain verification: %d", ok);
49  if (ok)
50  return ok;
51 
52  const int error = X509_STORE_CTX_get_error(ctx);
53  X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
54  string subject = "subject n/a";
55  if (current_cert) {
56  char *buffer = NULL;
57  buffer = X509_NAME_oneline(X509_get_subject_name(current_cert), NULL, 0);
58  if (buffer) {
59  subject = string(buffer);
60  free(buffer);
61  }
62  }
64  "certificate verification error: %s, error %s (%d)", subject.c_str(),
65  X509_verify_cert_error_string(error), error);
66  return ok;
67 }
68 
69 
70 SignatureManager::SignatureManager() {
71  private_key_ = NULL;
72  private_master_key_ = NULL;
73  certificate_ = NULL;
74  x509_store_ = NULL;
75  x509_lookup_ = NULL;
76  const int retval = pthread_mutex_init(&lock_blacklist_, NULL);
77  assert(retval == 0);
78 }
79 
80 
81 void SignatureManager::InitX509Store() {
82  if (x509_store_)
83  X509_STORE_free(x509_store_);
84  x509_lookup_ = NULL;
85  x509_store_ = X509_STORE_new();
86  assert(x509_store_ != NULL);
87 
88  const unsigned long verify_flags = // NOLINT(runtime/int)
89  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
90 #ifdef OPENSSL_API_INTERFACE_V09
91  X509_STORE_set_flags(x509_store_, verify_flags);
92 #else
93  int retval;
94  X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
95  assert(param != NULL);
96  retval = X509_VERIFY_PARAM_set_flags(param, verify_flags);
97  assert(retval == 1);
98  retval = X509_STORE_set1_param(x509_store_, param);
99  assert(retval == 1);
100  X509_VERIFY_PARAM_free(param);
101 #endif
102 
103  x509_lookup_ = X509_STORE_add_lookup(x509_store_, X509_LOOKUP_hash_dir());
104  assert(x509_lookup_ != NULL);
105 
106  X509_STORE_set_verify_cb_func(x509_store_, CallbackCertVerify);
107 }
108 
109 
111  OpenSSL_add_all_algorithms();
112  InitX509Store();
113 }
114 
115 
117  UnloadCertificate();
118  UnloadPrivateKey();
119  UnloadPrivateMasterKey();
120  UnloadPublicRsaKeys();
121  // Lookup is freed automatically
122  if (x509_store_)
123  X509_STORE_free(x509_store_);
124 
125  EVP_cleanup();
126 
127  private_key_ = NULL;
128  private_master_key_ = NULL;
129  certificate_ = NULL;
130  x509_store_ = NULL;
131  x509_lookup_ = NULL;
132 }
133 
134 
138 string SignatureManager::GetCryptoError() {
139  char buf[121];
140  string err;
141  while (ERR_peek_error() != 0) {
142  ERR_error_string(ERR_get_error(), buf);
143  err += string(buf);
144  }
145  return err;
146 }
147 
148 
155 bool SignatureManager::LoadPrivateMasterKeyPath(const string &file_pem) {
156  UnloadPrivateMasterKey();
157  FILE *fp;
158  if ((fp = fopen(file_pem.c_str(), "r")) == NULL)
159  return false;
160  private_master_key_ = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
161  fclose(fp);
162  return (private_master_key_ != NULL);
163 }
164 
165 bool SignatureManager::LoadPrivateMasterKeyMem(const string &key) {
166  UnloadPrivateMasterKey();
167  BIO *bp = BIO_new(BIO_s_mem());
168  assert(bp != NULL);
169  if (BIO_write(bp, key.data(), key.size()) <= 0) {
170  BIO_free(bp);
171  return false;
172  }
173  private_master_key_ = PEM_read_bio_RSAPrivateKey(bp, NULL, NULL, NULL);
174  BIO_free(bp);
175  return (private_master_key_ != NULL);
176 }
177 
178 
185 bool SignatureManager::LoadPrivateKeyPath(const string &file_pem,
186  const string &password) {
187  UnloadPrivateKey();
188  bool result;
189  FILE *fp = NULL;
190  char *tmp = strdupa(password.c_str());
191 
192  if ((fp = fopen(file_pem.c_str(), "r")) == NULL)
193  return false;
194  result = (private_key_ = PEM_read_PrivateKey(fp, NULL, NULL, tmp)) != NULL;
195  fclose(fp);
196  return result;
197 }
198 
199 bool SignatureManager::LoadPrivateKeyMem(const std::string &key) {
200  UnloadPrivateKey();
201  BIO *bp = BIO_new(BIO_s_mem());
202  assert(bp != NULL);
203  if (BIO_write(bp, key.data(), key.size()) <= 0) {
204  BIO_free(bp);
205  return false;
206  }
207  private_key_ = PEM_read_bio_PrivateKey(bp, NULL, NULL, NULL);
208  BIO_free(bp);
209  return (private_key_ != NULL);
210 }
211 
212 
216 void SignatureManager::UnloadPrivateKey() {
217  if (private_key_)
218  EVP_PKEY_free(private_key_);
219  private_key_ = NULL;
220 }
221 
222 
223 void SignatureManager::UnloadCertificate() {
224  if (certificate_)
225  X509_free(certificate_);
226  certificate_ = NULL;
227 }
228 
229 
233 void SignatureManager::UnloadPrivateMasterKey() {
234  if (private_master_key_)
235  RSA_free(private_master_key_);
236  private_master_key_ = NULL;
237 }
238 
239 
246 bool SignatureManager::LoadCertificatePath(const string &file_pem) {
247  if (certificate_) {
248  X509_free(certificate_);
249  certificate_ = NULL;
250  }
251 
252  bool result;
253  char *nopwd = strdupa("");
254  FILE *fp;
255 
256  if ((fp = fopen(file_pem.c_str(), "r")) == NULL)
257  return false;
258  result = (certificate_ = PEM_read_X509_AUX(fp, NULL, NULL, nopwd)) != NULL;
259 
260  if (!result && certificate_) {
261  X509_free(certificate_);
262  certificate_ = NULL;
263  }
264 
265  fclose(fp);
266  return result;
267 }
268 
269 
273 bool SignatureManager::LoadCertificateMem(const unsigned char *buffer,
274  const unsigned buffer_size) {
275  if (certificate_) {
276  X509_free(certificate_);
277  certificate_ = NULL;
278  }
279 
280  bool result;
281  char *nopwd = strdupa("");
282 
283  BIO *mem = BIO_new(BIO_s_mem());
284  if (!mem)
285  return false;
286  if (BIO_write(mem, buffer, buffer_size) <= 0) {
287  BIO_free(mem);
288  return false;
289  }
290  result = (certificate_ = PEM_read_bio_X509_AUX(mem, NULL, NULL, nopwd))
291  != NULL;
292  BIO_free(mem);
293 
294  if (!result && certificate_) {
295  X509_free(certificate_);
296  certificate_ = NULL;
297  }
298 
299  return result;
300 }
301 
302 
306 bool SignatureManager::LoadPublicRsaKeys(const string &path_list) {
307  UnloadPublicRsaKeys();
308 
309  if (path_list == "")
310  return true;
311  const vector<string> pem_files = SplitString(path_list, ':');
312 
313  char *nopwd = strdupa("");
314  FILE *fp;
315 
316  for (unsigned i = 0; i < pem_files.size(); ++i) {
317  const char *pubkey_file = pem_files[i].c_str();
318 
319  // open public key file
320  fp = fopen(pubkey_file, "r");
321  if (fp == NULL) {
323  "failed to open "
324  "public key '%s'",
325  pubkey_file);
326  return false;
327  }
328 
329  // load the public key from the file (and close it)
330  EVP_PKEY *this_key = PEM_read_PUBKEY(fp, NULL, NULL, nopwd);
331  fclose(fp);
332  if (this_key == NULL) {
334  "failed to load "
335  "public key '%s'",
336  pubkey_file);
337  return false;
338  }
339 
340  // read the RSA key from the loaded public key
341  RSA *key = EVP_PKEY_get1_RSA(this_key);
342  EVP_PKEY_free(this_key);
343  if (key == NULL) {
345  "failed to read "
346  "public key '%s'",
347  pubkey_file);
348  return false;
349  }
350 
351  // store the loaded public key
352  public_keys_.push_back(key);
353  }
354 
355  return true;
356 }
357 
358 
359 void SignatureManager::UnloadPublicRsaKeys() {
360  for (unsigned i = 0; i < public_keys_.size(); ++i)
361  RSA_free(public_keys_[i]);
362  public_keys_.clear();
363 }
364 
365 
366 std::string SignatureManager::GenerateKeyText(RSA *pubkey) const {
367  if (!pubkey) {
368  return "";
369  }
370 
371  BIO *bp = BIO_new(BIO_s_mem());
372  if (bp == NULL) {
374  "Failed to allocate"
375  " memory for pubkey");
376  return "";
377  }
378  if (!PEM_write_bio_RSA_PUBKEY(bp, pubkey)) {
380  "Failed to write"
381  " pubkey to memory");
382  return "";
383  }
384  char *bio_pubkey_text;
385  long bytes = BIO_get_mem_data(bp, &bio_pubkey_text); // NOLINT
386  std::string bio_pubkey_str(bio_pubkey_text, bytes);
387  BIO_free(bp);
388 
389  return bio_pubkey_str;
390 }
391 
392 
393 std::string SignatureManager::GetActivePubkeys() const {
394  std::string pubkeys;
395  for (std::vector<RSA *>::const_iterator it = public_keys_.begin();
396  it != public_keys_.end();
397  it++) {
398  pubkeys += GenerateKeyText(*it);
399  }
400  // NOTE: we do not add the pubkey of the certificate here, as it is
401  // not used for the whitelist verification.
402  return pubkeys;
403 }
404 
405 std::vector<std::string> SignatureManager::GetActivePubkeysAsVector() const {
406  std::vector<std::string> pubkeys;
407  for (std::vector<RSA *>::const_iterator it = public_keys_.begin();
408  it != public_keys_.end();
409  it++) {
410  pubkeys.push_back(GenerateKeyText(*it));
411  }
412  // NOTE: we do not add the pubkey of the certificate here, as it is
413  // not used for the whitelist verification.
414  return pubkeys;
415 }
416 
417 std::string SignatureManager::GetCertificate() const {
418  if (!certificate_)
419  return "";
420 
421  BIO *bp = BIO_new(BIO_s_mem());
422  assert(bp != NULL);
423  const bool rvb = PEM_write_bio_X509(bp, certificate_);
424  assert(rvb);
425  char *bio_crt_text;
426  long bytes = BIO_get_mem_data(bp, &bio_crt_text); // NOLINT
427  assert(bytes > 0);
428  std::string bio_crt_str(bio_crt_text, bytes);
429  BIO_free(bp);
430  return bio_crt_str;
431 }
432 
433 
434 std::string SignatureManager::GetPrivateKey() {
435  if (!private_key_)
436  return "";
437 
438  BIO *bp = BIO_new(BIO_s_mem());
439  assert(bp != NULL);
440  const bool rvb =
441  PEM_write_bio_PrivateKey(bp, private_key_, NULL, NULL, 0, 0, NULL);
442  assert(rvb);
443  char *bio_privkey_text;
444  long bytes = BIO_get_mem_data(bp, &bio_privkey_text); // NOLINT
445  assert(bytes > 0);
446  std::string bio_privkey_str(bio_privkey_text, bytes);
447  BIO_free(bp);
448  return bio_privkey_str;
449 }
450 
451 
452 std::string SignatureManager::GetPrivateMasterKey() {
453  if (!private_master_key_)
454  return "";
455 
456  BIO *bp = BIO_new(BIO_s_mem());
457  assert(bp != NULL);
458  const bool rvb = PEM_write_bio_RSAPrivateKey(bp, private_master_key_, NULL,
459  NULL, 0, 0, NULL);
460  assert(rvb);
461  char *bio_master_privkey_text;
462  long bytes = BIO_get_mem_data(bp, &bio_master_privkey_text); // NOLINT
463  assert(bytes > 0);
464  std::string bio_master_privkey_str(bio_master_privkey_text, bytes);
465  BIO_free(bp);
466  return bio_master_privkey_str;
467 }
468 
469 RSA *SignatureManager::GenerateRsaKeyPair() {
470  RSA *rsa = NULL;
471  BIGNUM *bn = BN_new();
472  int retval = BN_set_word(bn, RSA_F4);
473  assert(retval == 1);
474 #ifdef OPENSSL_API_INTERFACE_V09
475  rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
476  assert(rsa != NULL);
477 #else
478  rsa = RSA_new();
479  retval = RSA_generate_key_ex(rsa, 2048, bn, NULL);
480  assert(retval == 1);
481 #endif
482  BN_free(bn);
483  return rsa;
484 }
485 
486 
490 void SignatureManager::GenerateMasterKeyPair() {
491  UnloadPrivateMasterKey();
492  UnloadPublicRsaKeys();
493 
494  RSA *rsa = GenerateRsaKeyPair();
495  private_master_key_ = RSAPrivateKey_dup(rsa);
496  public_keys_.push_back(RSAPublicKey_dup(rsa));
497  RSA_free(rsa);
498 }
499 
503 void SignatureManager::GenerateCertificate(const std::string &cn) {
504  UnloadPrivateKey();
505  UnloadCertificate();
506  int retval;
507 
508  RSA *rsa = GenerateRsaKeyPair();
509  private_key_ = EVP_PKEY_new();
510  retval = EVP_PKEY_set1_RSA(private_key_, RSAPrivateKey_dup(rsa));
511  assert(retval == 1);
512  EVP_PKEY *pkey = EVP_PKEY_new();
513  retval = EVP_PKEY_set1_RSA(pkey, rsa);
514  assert(retval == 1);
515 
516  certificate_ = X509_new();
517  X509_set_version(certificate_, 2L);
518  X509_set_pubkey(certificate_, pkey);
519 
520  Prng prng;
521  prng.InitLocaltime();
522  unsigned long rnd_serial_no = prng.Next(uint64_t(1) + uint32_t(-1)); // NOLINT
523  rnd_serial_no = rnd_serial_no
524  | uint64_t(prng.Next(uint64_t(1) + uint32_t(-1))) << 32;
525  ASN1_INTEGER_set(X509_get_serialNumber(certificate_), rnd_serial_no);
526 
527  // valid as of now
528  X509_gmtime_adj(
529  reinterpret_cast<ASN1_TIME *>(X509_get_notBefore(certificate_)), 0);
530  // valid for 1 year (validity range is unused)
531  X509_gmtime_adj(
532  reinterpret_cast<ASN1_TIME *>(X509_get_notAfter(certificate_)),
533  3600 * 24 * 365);
534 
535  X509_NAME *name = X509_get_subject_name(certificate_);
536 #ifdef OPENSSL_API_INTERFACE_V09
537  X509_NAME_add_entry_by_txt(
538  name, "CN", MBSTRING_ASC,
539  const_cast<unsigned char *>(
540  reinterpret_cast<const unsigned char *>(cn.c_str())),
541  -1, -1, 0);
542 #else
543  X509_NAME_add_entry_by_txt(
544  name, "CN", MBSTRING_ASC,
545  reinterpret_cast<const unsigned char *>(cn.c_str()), -1, -1, 0);
546 #endif
547  retval = X509_set_issuer_name(certificate_, name);
548  assert(retval == 1);
549 
550 #ifdef OPENSSL_API_INTERFACE_V09
551  retval = X509_sign(certificate_, pkey, EVP_sha1());
552 #else
553  retval = X509_sign(certificate_, pkey, EVP_sha256());
554 #endif
555  EVP_PKEY_free(pkey);
556  assert(retval > 0);
557 }
558 
562 bool SignatureManager::LoadBlacklist(const std::string &path_blacklist,
563  bool append) {
564  const MutexLockGuard lock_guard(&lock_blacklist_);
565  LogCvmfs(kLogSignature, kLogDebug, "reading from blacklist %s",
566  path_blacklist.c_str());
567  if (!append)
568  blacklist_.clear();
569 
570  const int fd = open(path_blacklist.c_str(), O_RDONLY);
571  if (fd < 0)
572  return false;
573  std::string blacklist_buffer;
574  const bool retval = SafeReadToString(fd, &blacklist_buffer);
575  close(fd);
576  if (!retval)
577  return false;
578 
579  unsigned num_bytes = 0;
580  while (num_bytes < blacklist_buffer.size()) {
581  const string line = GetLineMem(blacklist_buffer.data() + num_bytes,
582  blacklist_buffer.size() - num_bytes);
583  blacklist_.push_back(line);
584  num_bytes += line.length() + 1;
585  }
586 
587  return true;
588 }
589 
590 
591 vector<string> SignatureManager::GetBlacklist() {
592  const MutexLockGuard lock_guard(&lock_blacklist_);
593  return blacklist_;
594 }
595 
596 
604 bool SignatureManager::LoadTrustedCaCrl(const string &path_list) {
605  InitX509Store();
606 
607  /* TODO if (path_list == "") {
608  return true;
609  }*/
610  const vector<string> paths = SplitString(path_list, ':');
611  for (unsigned i = 0; i < paths.size(); ++i) {
612  const int retval =
613  X509_LOOKUP_add_dir(x509_lookup_, paths[i].c_str(), X509_FILETYPE_PEM);
614  if (!retval)
615  return false;
616  }
617  return true;
618 }
619 
620 
626 shash::Any SignatureManager::HashCertificate(
627  const shash::Algorithms hash_algorithm) {
628  shash::Any result;
629  if (!certificate_)
630  return result;
631 
632  int buffer_size;
633  unsigned char *buffer = NULL;
634 
635  buffer_size = i2d_X509(certificate_, &buffer);
636  if (buffer_size < 0)
637  return result;
638 
639  result.algorithm = hash_algorithm;
640  shash::HashMem(buffer, buffer_size, &result);
641  free(buffer);
642 
643  return result;
644 }
645 
646 
652 string SignatureManager::FingerprintCertificate(
653  const shash::Algorithms hash_algorithm) {
654  const shash::Any hash = HashCertificate(hash_algorithm);
655  if (hash.IsNull())
656  return "";
657 
658  const string hash_str = hash.ToString();
659  string result;
660  for (unsigned i = 0; i < hash_str.length(); ++i) {
661  if (i < 2 * shash::kDigestSizes[hash_algorithm]) {
662  if ((i > 0) && (i % 2 == 0))
663  result += ":";
664  }
665  result += toupper(hash_str[i]);
666  }
667  return result;
668 }
669 
670 
674 shash::Any SignatureManager::MkFromFingerprint(const std::string &fingerprint) {
675  string convert;
676  for (unsigned i = 0; i < fingerprint.length(); ++i) {
677  if ((fingerprint[i] == ' ') || (fingerprint[i] == '\t')
678  || (fingerprint[i] == '#')) {
679  break;
680  }
681  if (fingerprint[i] != ':')
682  convert.push_back(tolower(fingerprint[i]));
683  }
684 
685  return shash::MkFromHexPtr(shash::HexPtr(convert));
686 }
687 
688 
692 string SignatureManager::Whois() {
693  if (!certificate_)
694  return "No certificate loaded";
695 
696  string result;
697  X509_NAME *subject = X509_get_subject_name(certificate_);
698  X509_NAME *issuer = X509_get_issuer_name(certificate_);
699  char *buffer = NULL;
700  buffer = X509_NAME_oneline(subject, NULL, 0);
701  if (buffer) {
702  result = "Publisher: " + string(buffer);
703  free(buffer);
704  }
705  buffer = X509_NAME_oneline(issuer, NULL, 0);
706  if (buffer) {
707  result += "\nCertificate issued by: " + string(buffer);
708  free(buffer);
709  }
710  return result;
711 }
712 
713 
714 bool SignatureManager::WriteCertificateMem(unsigned char **buffer,
715  unsigned *buffer_size) {
716  BIO *mem = BIO_new(BIO_s_mem());
717  if (!mem)
718  return false;
719  if (!PEM_write_bio_X509(mem, certificate_)) {
720  BIO_free(mem);
721  return false;
722  }
723 
724  void *bio_buffer;
725  *buffer_size = BIO_get_mem_data(mem, &bio_buffer);
726  *buffer = reinterpret_cast<unsigned char *>(smalloc(*buffer_size));
727  memcpy(*buffer, bio_buffer, *buffer_size);
728  BIO_free(mem);
729  return true;
730 }
731 
732 
738 bool SignatureManager::KeysMatch() {
739  if (!certificate_ || !private_key_)
740  return false;
741 
742  bool result = false;
743  const unsigned char *sign_me = reinterpret_cast<const unsigned char *>(
744  "sign me");
745  unsigned char *signature = NULL;
746  unsigned signature_size;
747  if (Sign(sign_me, 7, &signature, &signature_size)
748  && Verify(sign_me, 7, signature, signature_size)) {
749  result = true;
750  }
751  if (signature)
752  free(signature);
753  return result;
754 }
755 
756 
760 bool SignatureManager::VerifyCaChain() {
761  if (!certificate_)
762  return false;
763 
764  X509_STORE_CTX *csc = NULL;
765  csc = X509_STORE_CTX_new();
766  assert(csc);
767 
768  X509_STORE_CTX_init(csc, x509_store_, certificate_, NULL);
769  const bool result = X509_verify_cert(csc) == 1;
770  X509_STORE_CTX_free(csc);
771 
772  return result;
773 }
774 
775 
781 bool SignatureManager::Sign(const unsigned char *buffer,
782  const unsigned buffer_size,
783  unsigned char **signature,
784  unsigned *signature_size) {
785  if (!private_key_) {
786  *signature_size = 0;
787  *signature = NULL;
788  return false;
789  }
790 
791  bool result = false;
792 #ifdef OPENSSL_API_INTERFACE_V11
793  EVP_MD_CTX *ctx_ptr = EVP_MD_CTX_new();
794 #else
795  EVP_MD_CTX ctx;
796  EVP_MD_CTX_init(&ctx);
797  EVP_MD_CTX *ctx_ptr = &ctx;
798 #endif
799 
800  *signature = reinterpret_cast<unsigned char *>(
801  smalloc(EVP_PKEY_size(private_key_)));
802  if (EVP_SignInit(ctx_ptr, EVP_sha1())
803  && EVP_SignUpdate(ctx_ptr, buffer, buffer_size)
804  && EVP_SignFinal(ctx_ptr, *signature, signature_size, private_key_)) {
805  result = true;
806  }
807 #ifdef OPENSSL_API_INTERFACE_V11
808  EVP_MD_CTX_free(ctx_ptr);
809 #else
810  EVP_MD_CTX_cleanup(&ctx);
811 #endif
812  if (!result) {
813  free(*signature);
814  *signature_size = 0;
815  *signature = NULL;
816  }
817 
818  return result;
819 }
820 
821 
827 bool SignatureManager::SignRsa(const unsigned char *buffer,
828  const unsigned buffer_size,
829  unsigned char **signature,
830  unsigned *signature_size) {
831  if (!private_master_key_) {
832  *signature_size = 0;
833  *signature = NULL;
834  return false;
835  }
836 
837  unsigned char *to = (unsigned char *)smalloc(RSA_size(private_master_key_));
838  unsigned char *from = (unsigned char *)smalloc(buffer_size);
839  memcpy(from, buffer, buffer_size);
840 
841  const int size = RSA_private_encrypt(buffer_size, from, to,
842  private_master_key_, RSA_PKCS1_PADDING);
843  free(from);
844  if (size < 0) {
845  *signature_size = 0;
846  *signature = NULL;
847  return false;
848  }
849  *signature = to;
850  *signature_size = size;
851  return true;
852 }
853 
854 
860 bool SignatureManager::Verify(const unsigned char *buffer,
861  const unsigned buffer_size,
862  const unsigned char *signature,
863  const unsigned signature_size) {
864  if (!certificate_)
865  return false;
866 
867  bool result = false;
868 #ifdef OPENSSL_API_INTERFACE_V11
869  EVP_MD_CTX *ctx_ptr = EVP_MD_CTX_new();
870 #else
871  EVP_MD_CTX ctx;
872  EVP_MD_CTX_init(&ctx);
873  EVP_MD_CTX *ctx_ptr = &ctx;
874 #endif
875 
876  EVP_PKEY *pubkey = X509_get_pubkey(certificate_);
877  if (EVP_VerifyInit(ctx_ptr, EVP_sha1())
878  && EVP_VerifyUpdate(ctx_ptr, buffer, buffer_size) &&
880  EVP_VerifyFinal(ctx_ptr, const_cast<unsigned char *>(signature),
881  signature_size, pubkey)
882 #else
883  EVP_VerifyFinal(ctx_ptr, signature, signature_size, pubkey)
884 #endif
885  ) {
886  result = true;
887  }
888  if (pubkey != NULL)
889  EVP_PKEY_free(pubkey);
890 #ifdef OPENSSL_API_INTERFACE_V11
891  EVP_MD_CTX_free(ctx_ptr);
892 #else
893  EVP_MD_CTX_cleanup(&ctx);
894 #endif
895 
896  return result;
897 }
898 
899 
906 bool SignatureManager::VerifyRsa(const unsigned char *buffer,
907  const unsigned buffer_size,
908  const unsigned char *signature,
909  const unsigned signature_size) {
910  for (unsigned i = 0, s = public_keys_.size(); i < s; ++i) {
911  if (buffer_size > (unsigned)RSA_size(public_keys_[i]))
912  continue;
913 
914  unsigned char *to = (unsigned char *)smalloc(RSA_size(public_keys_[i]));
915  unsigned char *from = (unsigned char *)smalloc(signature_size);
916  memcpy(from, signature, signature_size);
917 
918  const int size = RSA_public_decrypt(signature_size, from, to,
919  public_keys_[i], RSA_PKCS1_PADDING);
920  free(from);
921  if ((size >= 0) && (unsigned(size) == buffer_size)
922  && (memcmp(buffer, to, size) == 0)) {
923  free(to);
924  return true;
925  }
926 
927  free(to);
928  }
929 
930  LogCvmfs(kLogSignature, kLogDebug, "VerifyRsa, no public key fits");
931  return false;
932 }
933 
934 
938 void SignatureManager::CutLetter(const unsigned char *buffer,
939  const unsigned buffer_size,
940  const char separator,
941  unsigned *letter_length,
942  unsigned *pos_after_mark) {
943  unsigned pos = 0;
944  *letter_length = *pos_after_mark = 0;
945  do {
946  if (pos == buffer_size) {
947  *pos_after_mark = pos; // Careful: pos_after_mark points out of buffer
948  *letter_length = pos;
949  break;
950  }
951 
952  if ((buffer[pos] == '\n') && (pos + 4 <= buffer_size)
953  && (buffer[pos + 1] == separator) && (buffer[pos + 2] == separator)
954  && (buffer[pos + 3] == '\n')) {
955  *letter_length = pos + 1;
956  pos += 4;
957  break;
958  }
959  pos++;
960  } while (true);
961  *pos_after_mark = pos;
962 }
963 
964 
972 bool SignatureManager::VerifyLetter(const unsigned char *buffer,
973  const unsigned buffer_size,
974  const bool by_rsa) {
975  unsigned pos = 0;
976  unsigned letter_length = 0;
977  CutLetter(buffer, buffer_size, '-', &letter_length, &pos);
978  if (pos >= buffer_size)
979  return false;
980 
981  string hash_str = "";
982  const unsigned hash_pos = pos;
983  do {
984  if (pos == buffer_size)
985  return false;
986  if (buffer[pos] == '\n') {
987  pos++;
988  break;
989  }
990  hash_str.push_back(buffer[pos++]);
991  } while (true);
992  const shash::Any hash_printed = shash::MkFromHexPtr(shash::HexPtr(hash_str));
993  shash::Any hash_computed(hash_printed.algorithm);
994  shash::HashMem(buffer, letter_length, &hash_computed);
995  if (hash_printed != hash_computed)
996  return false;
997 
998  if (by_rsa) {
999  return VerifyRsa(&buffer[hash_pos], hash_str.length(), &buffer[pos],
1000  buffer_size - pos);
1001  } else {
1002  return Verify(&buffer[hash_pos], hash_str.length(), &buffer[pos],
1003  buffer_size - pos);
1004  }
1005 }
1006 
1007 
1012 bool SignatureManager::VerifyPkcs7(const unsigned char *buffer,
1013  const unsigned buffer_size,
1014  unsigned char **content,
1015  unsigned *content_size,
1016  vector<string> *alt_uris) {
1017  *content = NULL;
1018  *content_size = 0;
1019 
1020  BIO *bp_pkcs7 = BIO_new(BIO_s_mem());
1021  if (!bp_pkcs7)
1022  return false;
1023  if (BIO_write(bp_pkcs7, buffer, buffer_size) <= 0) {
1024  BIO_free(bp_pkcs7);
1025  return false;
1026  }
1027 
1028  PKCS7 *pkcs7 = NULL;
1029  pkcs7 = PEM_read_bio_PKCS7(bp_pkcs7, NULL, NULL, NULL);
1030  BIO_free(bp_pkcs7);
1031  if (!pkcs7) {
1032  LogCvmfs(kLogSignature, kLogDebug, "invalid pkcs#7 signature");
1033  return false;
1034  }
1035 
1036  BIO *bp_content = BIO_new(BIO_s_mem());
1037  if (!bp_content) {
1038  PKCS7_free(pkcs7);
1039  return false;
1040  }
1041 
1042  const int flags = 0;
1043  STACK_OF(X509) *extra_signers = NULL;
1044  BIO *indata = NULL;
1045  const bool result = PKCS7_verify(pkcs7, extra_signers, x509_store_, indata,
1046  bp_content, flags);
1047  if (result != 1) {
1048  BIO_free(bp_content);
1049  PKCS7_free(pkcs7);
1050  return false;
1051  }
1052 
1053  BUF_MEM *bufmem_content;
1054  BIO_get_mem_ptr(bp_content, &bufmem_content);
1055  // BIO_free() leaves BUF_MEM alone
1056  (void)BIO_set_close(bp_content, BIO_NOCLOSE);
1057  BIO_free(bp_content);
1058  *content = reinterpret_cast<unsigned char *>(bufmem_content->data);
1059  *content_size = bufmem_content->length;
1060  free(bufmem_content);
1061  if (*content == NULL) {
1062  PKCS7_free(pkcs7);
1063  LogCvmfs(kLogSignature, kLogDebug, "empty pkcs#7 structure");
1064  return false;
1065  }
1066 
1067  // Extract signing certificates
1068  STACK_OF(X509) *signers = NULL;
1069  signers = PKCS7_get0_signers(pkcs7, NULL, 0);
1070  assert(signers);
1071 
1072  // Extract alternative names
1073  for (int i = 0; i < sk_X509_num(signers); ++i) {
1074  X509 *this_signer = sk_X509_value(signers, i);
1075  GENERAL_NAMES *subject_alt_names = NULL;
1076  subject_alt_names = reinterpret_cast<GENERAL_NAMES *>(
1077  X509_get_ext_d2i(this_signer, NID_subject_alt_name, NULL, NULL));
1078  if (subject_alt_names != NULL) {
1079  for (int j = 0; j < sk_GENERAL_NAME_num(subject_alt_names); ++j) {
1080  GENERAL_NAME *this_name = sk_GENERAL_NAME_value(subject_alt_names, j);
1081  if (this_name->type != GEN_URI)
1082  continue;
1083 
1084  const char *name_ptr = reinterpret_cast<const char *>(
1085 #ifdef OPENSSL_API_INTERFACE_V11
1086  ASN1_STRING_get0_data(this_name->d.uniformResourceIdentifier));
1087 #else
1088  ASN1_STRING_data(this_name->d.uniformResourceIdentifier));
1089 #endif
1090  const int name_len =
1091  ASN1_STRING_length(this_name->d.uniformResourceIdentifier);
1092  if (!name_ptr || (name_len <= 0))
1093  continue;
1094  alt_uris->push_back(string(name_ptr, name_len));
1095  }
1096  }
1097  }
1098  sk_X509_free(signers);
1099  PKCS7_free(pkcs7);
1100  return true;
1101 }
1102 
1103 } // namespace signature
Definition: prng.h:27
bool IsNull() const
Definition: hash.h:371
struct cvmcache_context * ctx
Failures Verify(unsigned char *manifest_data, size_t manifest_size, const std::string &base_url, const std::string &repository_name, const uint64_t minimum_timestamp, const shash::Any *base_catalog, signature::SignatureManager *signature_manager, download::DownloadManager *download_manager, ManifestEnsemble *ensemble)
string GetLineMem(const char *text, const int text_size)
Definition: string.cc:415
std::string ToString(const bool with_suffix=false) const
Definition: hash.h:241
void InitLocaltime()
Definition: prng.h:34
assert((mem||(size==0))&&"Out Of Memory")
Algorithms algorithm
Definition: hash.h:122
Algorithms
Definition: hash.h:41
#define strdupa(s)
Definition: platform_osx.h:285
vector< string > SplitString(const string &str, char delim)
Definition: string.cc:306
const char * kDefaultPublicKey
Definition: signature.cc:44
static int Init(const loader::LoaderExports *loader_exports)
Definition: cvmfs.cc:2320
static int CallbackCertVerify(int ok, X509_STORE_CTX *ctx)
Definition: signature.cc:47
#define OPENSSL_API_INTERFACE_V09
bool SafeReadToString(int fd, std::string *final_result)
Definition: posix.cc:2117
void HashMem(const unsigned char *buffer, const unsigned buffer_size, Any *any_digest)
Definition: hash.cc:255
static void Fini()
Definition: cvmfs.cc:2539
Definition: mutex.h:42
Any MkFromHexPtr(const HexPtr hex, const char suffix)
Definition: hash.cc:82
mem
Definition: smalloc.h:60
static void size_t size
Definition: smalloc.h:54
const unsigned kDigestSizes[]
Definition: hash.h:69
uint32_t Next(const uint64_t boundary)
Definition: prng.h:44
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545