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  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  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  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  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  bool rvb = PEM_write_bio_PrivateKey(bp, private_key_, NULL, NULL, 0, 0, NULL);
441  assert(rvb);
442  char *bio_privkey_text;
443  long bytes = BIO_get_mem_data(bp, &bio_privkey_text); // NOLINT
444  assert(bytes > 0);
445  std::string bio_privkey_str(bio_privkey_text, bytes);
446  BIO_free(bp);
447  return bio_privkey_str;
448 }
449 
450 
451 std::string SignatureManager::GetPrivateMasterKey() {
452  if (!private_master_key_)
453  return "";
454 
455  BIO *bp = BIO_new(BIO_s_mem());
456  assert(bp != NULL);
457  bool rvb = PEM_write_bio_RSAPrivateKey(bp, private_master_key_, NULL, NULL, 0,
458  0, NULL);
459  assert(rvb);
460  char *bio_master_privkey_text;
461  long bytes = BIO_get_mem_data(bp, &bio_master_privkey_text); // NOLINT
462  assert(bytes > 0);
463  std::string bio_master_privkey_str(bio_master_privkey_text, bytes);
464  BIO_free(bp);
465  return bio_master_privkey_str;
466 }
467 
468 RSA *SignatureManager::GenerateRsaKeyPair() {
469  RSA *rsa = NULL;
470  BIGNUM *bn = BN_new();
471  int retval = BN_set_word(bn, RSA_F4);
472  assert(retval == 1);
473 #ifdef OPENSSL_API_INTERFACE_V09
474  rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
475  assert(rsa != NULL);
476 #else
477  rsa = RSA_new();
478  retval = RSA_generate_key_ex(rsa, 2048, bn, NULL);
479  assert(retval == 1);
480 #endif
481  BN_free(bn);
482  return rsa;
483 }
484 
485 
489 void SignatureManager::GenerateMasterKeyPair() {
490  UnloadPrivateMasterKey();
491  UnloadPublicRsaKeys();
492 
493  RSA *rsa = GenerateRsaKeyPair();
494  private_master_key_ = RSAPrivateKey_dup(rsa);
495  public_keys_.push_back(RSAPublicKey_dup(rsa));
496  RSA_free(rsa);
497 }
498 
502 void SignatureManager::GenerateCertificate(const std::string &cn) {
503  UnloadPrivateKey();
504  UnloadCertificate();
505  int retval;
506 
507  RSA *rsa = GenerateRsaKeyPair();
508  private_key_ = EVP_PKEY_new();
509  retval = EVP_PKEY_set1_RSA(private_key_, RSAPrivateKey_dup(rsa));
510  assert(retval == 1);
511  EVP_PKEY *pkey = EVP_PKEY_new();
512  retval = EVP_PKEY_set1_RSA(pkey, rsa);
513  assert(retval == 1);
514 
515  certificate_ = X509_new();
516  X509_set_version(certificate_, 2L);
517  X509_set_pubkey(certificate_, pkey);
518 
519  Prng prng;
520  prng.InitLocaltime();
521  unsigned long rnd_serial_no = prng.Next(uint64_t(1) + uint32_t(-1)); // NOLINT
522  rnd_serial_no = rnd_serial_no
523  | uint64_t(prng.Next(uint64_t(1) + uint32_t(-1))) << 32;
524  ASN1_INTEGER_set(X509_get_serialNumber(certificate_), rnd_serial_no);
525 
526  // valid as of now
527  X509_gmtime_adj(
528  reinterpret_cast<ASN1_TIME *>(X509_get_notBefore(certificate_)), 0);
529  // valid for 1 year (validity range is unused)
530  X509_gmtime_adj(
531  reinterpret_cast<ASN1_TIME *>(X509_get_notAfter(certificate_)),
532  3600 * 24 * 365);
533 
534  X509_NAME *name = X509_get_subject_name(certificate_);
535 #ifdef OPENSSL_API_INTERFACE_V09
536  X509_NAME_add_entry_by_txt(
537  name, "CN", MBSTRING_ASC,
538  const_cast<unsigned char *>(
539  reinterpret_cast<const unsigned char *>(cn.c_str())),
540  -1, -1, 0);
541 #else
542  X509_NAME_add_entry_by_txt(
543  name, "CN", MBSTRING_ASC,
544  reinterpret_cast<const unsigned char *>(cn.c_str()), -1, -1, 0);
545 #endif
546  retval = X509_set_issuer_name(certificate_, name);
547  assert(retval == 1);
548 
549 #ifdef OPENSSL_API_INTERFACE_V09
550  retval = X509_sign(certificate_, pkey, EVP_sha1());
551 #else
552  retval = X509_sign(certificate_, pkey, EVP_sha256());
553 #endif
554  EVP_PKEY_free(pkey);
555  assert(retval > 0);
556 }
557 
561 bool SignatureManager::LoadBlacklist(const std::string &path_blacklist,
562  bool append) {
563  MutexLockGuard lock_guard(&lock_blacklist_);
564  LogCvmfs(kLogSignature, kLogDebug, "reading from blacklist %s",
565  path_blacklist.c_str());
566  if (!append)
567  blacklist_.clear();
568 
569  int fd = open(path_blacklist.c_str(), O_RDONLY);
570  if (fd < 0)
571  return false;
572  std::string blacklist_buffer;
573  bool retval = SafeReadToString(fd, &blacklist_buffer);
574  close(fd);
575  if (!retval)
576  return false;
577 
578  unsigned num_bytes = 0;
579  while (num_bytes < blacklist_buffer.size()) {
580  const string line = GetLineMem(blacklist_buffer.data() + num_bytes,
581  blacklist_buffer.size() - num_bytes);
582  blacklist_.push_back(line);
583  num_bytes += line.length() + 1;
584  }
585 
586  return true;
587 }
588 
589 
590 vector<string> SignatureManager::GetBlacklist() {
591  MutexLockGuard lock_guard(&lock_blacklist_);
592  return blacklist_;
593 }
594 
595 
603 bool SignatureManager::LoadTrustedCaCrl(const string &path_list) {
604  InitX509Store();
605 
606  /* TODO if (path_list == "") {
607  return true;
608  }*/
609  const vector<string> paths = SplitString(path_list, ':');
610  for (unsigned i = 0; i < paths.size(); ++i) {
611  int retval = X509_LOOKUP_add_dir(x509_lookup_, paths[i].c_str(),
612  X509_FILETYPE_PEM);
613  if (!retval)
614  return false;
615  }
616  return true;
617 }
618 
619 
625 shash::Any SignatureManager::HashCertificate(
626  const shash::Algorithms hash_algorithm) {
627  shash::Any result;
628  if (!certificate_)
629  return result;
630 
631  int buffer_size;
632  unsigned char *buffer = NULL;
633 
634  buffer_size = i2d_X509(certificate_, &buffer);
635  if (buffer_size < 0)
636  return result;
637 
638  result.algorithm = hash_algorithm;
639  shash::HashMem(buffer, buffer_size, &result);
640  free(buffer);
641 
642  return result;
643 }
644 
645 
651 string SignatureManager::FingerprintCertificate(
652  const shash::Algorithms hash_algorithm) {
653  shash::Any hash = HashCertificate(hash_algorithm);
654  if (hash.IsNull())
655  return "";
656 
657  const string hash_str = hash.ToString();
658  string result;
659  for (unsigned i = 0; i < hash_str.length(); ++i) {
660  if (i < 2 * shash::kDigestSizes[hash_algorithm]) {
661  if ((i > 0) && (i % 2 == 0))
662  result += ":";
663  }
664  result += toupper(hash_str[i]);
665  }
666  return result;
667 }
668 
669 
673 shash::Any SignatureManager::MkFromFingerprint(const std::string &fingerprint) {
674  string convert;
675  for (unsigned i = 0; i < fingerprint.length(); ++i) {
676  if ((fingerprint[i] == ' ') || (fingerprint[i] == '\t')
677  || (fingerprint[i] == '#')) {
678  break;
679  }
680  if (fingerprint[i] != ':')
681  convert.push_back(tolower(fingerprint[i]));
682  }
683 
684  return shash::MkFromHexPtr(shash::HexPtr(convert));
685 }
686 
687 
691 string SignatureManager::Whois() {
692  if (!certificate_)
693  return "No certificate loaded";
694 
695  string result;
696  X509_NAME *subject = X509_get_subject_name(certificate_);
697  X509_NAME *issuer = X509_get_issuer_name(certificate_);
698  char *buffer = NULL;
699  buffer = X509_NAME_oneline(subject, NULL, 0);
700  if (buffer) {
701  result = "Publisher: " + string(buffer);
702  free(buffer);
703  }
704  buffer = X509_NAME_oneline(issuer, NULL, 0);
705  if (buffer) {
706  result += "\nCertificate issued by: " + string(buffer);
707  free(buffer);
708  }
709  return result;
710 }
711 
712 
713 bool SignatureManager::WriteCertificateMem(unsigned char **buffer,
714  unsigned *buffer_size) {
715  BIO *mem = BIO_new(BIO_s_mem());
716  if (!mem)
717  return false;
718  if (!PEM_write_bio_X509(mem, certificate_)) {
719  BIO_free(mem);
720  return false;
721  }
722 
723  void *bio_buffer;
724  *buffer_size = BIO_get_mem_data(mem, &bio_buffer);
725  *buffer = reinterpret_cast<unsigned char *>(smalloc(*buffer_size));
726  memcpy(*buffer, bio_buffer, *buffer_size);
727  BIO_free(mem);
728  return true;
729 }
730 
731 
737 bool SignatureManager::KeysMatch() {
738  if (!certificate_ || !private_key_)
739  return false;
740 
741  bool result = false;
742  const unsigned char *sign_me = reinterpret_cast<const unsigned char *>(
743  "sign me");
744  unsigned char *signature = NULL;
745  unsigned signature_size;
746  if (Sign(sign_me, 7, &signature, &signature_size)
747  && Verify(sign_me, 7, signature, signature_size)) {
748  result = true;
749  }
750  if (signature)
751  free(signature);
752  return result;
753 }
754 
755 
759 bool SignatureManager::VerifyCaChain() {
760  if (!certificate_)
761  return false;
762 
763  X509_STORE_CTX *csc = NULL;
764  csc = X509_STORE_CTX_new();
765  assert(csc);
766 
767  X509_STORE_CTX_init(csc, x509_store_, certificate_, NULL);
768  bool result = X509_verify_cert(csc) == 1;
769  X509_STORE_CTX_free(csc);
770 
771  return result;
772 }
773 
774 
780 bool SignatureManager::Sign(const unsigned char *buffer,
781  const unsigned buffer_size,
782  unsigned char **signature,
783  unsigned *signature_size) {
784  if (!private_key_) {
785  *signature_size = 0;
786  *signature = NULL;
787  return false;
788  }
789 
790  bool result = false;
791 #ifdef OPENSSL_API_INTERFACE_V11
792  EVP_MD_CTX *ctx_ptr = EVP_MD_CTX_new();
793 #else
794  EVP_MD_CTX ctx;
795  EVP_MD_CTX_init(&ctx);
796  EVP_MD_CTX *ctx_ptr = &ctx;
797 #endif
798 
799  *signature = reinterpret_cast<unsigned char *>(
800  smalloc(EVP_PKEY_size(private_key_)));
801  if (EVP_SignInit(ctx_ptr, EVP_sha1())
802  && EVP_SignUpdate(ctx_ptr, buffer, buffer_size)
803  && EVP_SignFinal(ctx_ptr, *signature, signature_size, private_key_)) {
804  result = true;
805  }
806 #ifdef OPENSSL_API_INTERFACE_V11
807  EVP_MD_CTX_free(ctx_ptr);
808 #else
809  EVP_MD_CTX_cleanup(&ctx);
810 #endif
811  if (!result) {
812  free(*signature);
813  *signature_size = 0;
814  *signature = NULL;
815  }
816 
817  return result;
818 }
819 
820 
826 bool SignatureManager::SignRsa(const unsigned char *buffer,
827  const unsigned buffer_size,
828  unsigned char **signature,
829  unsigned *signature_size) {
830  if (!private_master_key_) {
831  *signature_size = 0;
832  *signature = NULL;
833  return false;
834  }
835 
836  unsigned char *to = (unsigned char *)smalloc(RSA_size(private_master_key_));
837  unsigned char *from = (unsigned char *)smalloc(buffer_size);
838  memcpy(from, buffer, buffer_size);
839 
840  int size = RSA_private_encrypt(buffer_size, from, to, private_master_key_,
841  RSA_PKCS1_PADDING);
842  free(from);
843  if (size < 0) {
844  *signature_size = 0;
845  *signature = NULL;
846  return false;
847  }
848  *signature = to;
849  *signature_size = size;
850  return true;
851 }
852 
853 
859 bool SignatureManager::Verify(const unsigned char *buffer,
860  const unsigned buffer_size,
861  const unsigned char *signature,
862  const unsigned signature_size) {
863  if (!certificate_)
864  return false;
865 
866  bool result = false;
867 #ifdef OPENSSL_API_INTERFACE_V11
868  EVP_MD_CTX *ctx_ptr = EVP_MD_CTX_new();
869 #else
870  EVP_MD_CTX ctx;
871  EVP_MD_CTX_init(&ctx);
872  EVP_MD_CTX *ctx_ptr = &ctx;
873 #endif
874 
875  EVP_PKEY *pubkey = X509_get_pubkey(certificate_);
876  if (EVP_VerifyInit(ctx_ptr, EVP_sha1())
877  && EVP_VerifyUpdate(ctx_ptr, buffer, buffer_size) &&
879  EVP_VerifyFinal(ctx_ptr, const_cast<unsigned char *>(signature),
880  signature_size, pubkey)
881 #else
882  EVP_VerifyFinal(ctx_ptr, signature, signature_size, pubkey)
883 #endif
884  ) {
885  result = true;
886  }
887  if (pubkey != NULL)
888  EVP_PKEY_free(pubkey);
889 #ifdef OPENSSL_API_INTERFACE_V11
890  EVP_MD_CTX_free(ctx_ptr);
891 #else
892  EVP_MD_CTX_cleanup(&ctx);
893 #endif
894 
895  return result;
896 }
897 
898 
905 bool SignatureManager::VerifyRsa(const unsigned char *buffer,
906  const unsigned buffer_size,
907  const unsigned char *signature,
908  const unsigned signature_size) {
909  for (unsigned i = 0, s = public_keys_.size(); i < s; ++i) {
910  if (buffer_size > (unsigned)RSA_size(public_keys_[i]))
911  continue;
912 
913  unsigned char *to = (unsigned char *)smalloc(RSA_size(public_keys_[i]));
914  unsigned char *from = (unsigned char *)smalloc(signature_size);
915  memcpy(from, signature, signature_size);
916 
917  int size = RSA_public_decrypt(signature_size, from, to, public_keys_[i],
918  RSA_PKCS1_PADDING);
919  free(from);
920  if ((size >= 0) && (unsigned(size) == buffer_size)
921  && (memcmp(buffer, to, size) == 0)) {
922  free(to);
923  return true;
924  }
925 
926  free(to);
927  }
928 
929  LogCvmfs(kLogSignature, kLogDebug, "VerifyRsa, no public key fits");
930  return false;
931 }
932 
933 
937 void SignatureManager::CutLetter(const unsigned char *buffer,
938  const unsigned buffer_size,
939  const char separator,
940  unsigned *letter_length,
941  unsigned *pos_after_mark) {
942  unsigned pos = 0;
943  *letter_length = *pos_after_mark = 0;
944  do {
945  if (pos == buffer_size) {
946  *pos_after_mark = pos; // Careful: pos_after_mark points out of buffer
947  *letter_length = pos;
948  break;
949  }
950 
951  if ((buffer[pos] == '\n') && (pos + 4 <= buffer_size)
952  && (buffer[pos + 1] == separator) && (buffer[pos + 2] == separator)
953  && (buffer[pos + 3] == '\n')) {
954  *letter_length = pos + 1;
955  pos += 4;
956  break;
957  }
958  pos++;
959  } while (true);
960  *pos_after_mark = pos;
961 }
962 
963 
971 bool SignatureManager::VerifyLetter(const unsigned char *buffer,
972  const unsigned buffer_size,
973  const bool by_rsa) {
974  unsigned pos = 0;
975  unsigned letter_length = 0;
976  CutLetter(buffer, buffer_size, '-', &letter_length, &pos);
977  if (pos >= buffer_size)
978  return false;
979 
980  string hash_str = "";
981  unsigned hash_pos = pos;
982  do {
983  if (pos == buffer_size)
984  return false;
985  if (buffer[pos] == '\n') {
986  pos++;
987  break;
988  }
989  hash_str.push_back(buffer[pos++]);
990  } while (true);
991  shash::Any hash_printed = shash::MkFromHexPtr(shash::HexPtr(hash_str));
992  shash::Any hash_computed(hash_printed.algorithm);
993  shash::HashMem(buffer, letter_length, &hash_computed);
994  if (hash_printed != hash_computed)
995  return false;
996 
997  if (by_rsa) {
998  return VerifyRsa(&buffer[hash_pos], hash_str.length(), &buffer[pos],
999  buffer_size - pos);
1000  } else {
1001  return Verify(&buffer[hash_pos], hash_str.length(), &buffer[pos],
1002  buffer_size - pos);
1003  }
1004 }
1005 
1006 
1011 bool SignatureManager::VerifyPkcs7(const unsigned char *buffer,
1012  const unsigned buffer_size,
1013  unsigned char **content,
1014  unsigned *content_size,
1015  vector<string> *alt_uris) {
1016  *content = NULL;
1017  *content_size = 0;
1018 
1019  BIO *bp_pkcs7 = BIO_new(BIO_s_mem());
1020  if (!bp_pkcs7)
1021  return false;
1022  if (BIO_write(bp_pkcs7, buffer, buffer_size) <= 0) {
1023  BIO_free(bp_pkcs7);
1024  return false;
1025  }
1026 
1027  PKCS7 *pkcs7 = NULL;
1028  pkcs7 = PEM_read_bio_PKCS7(bp_pkcs7, NULL, NULL, NULL);
1029  BIO_free(bp_pkcs7);
1030  if (!pkcs7) {
1031  LogCvmfs(kLogSignature, kLogDebug, "invalid pkcs#7 signature");
1032  return false;
1033  }
1034 
1035  BIO *bp_content = BIO_new(BIO_s_mem());
1036  if (!bp_content) {
1037  PKCS7_free(pkcs7);
1038  return false;
1039  }
1040 
1041  int flags = 0;
1042  STACK_OF(X509) *extra_signers = NULL;
1043  BIO *indata = NULL;
1044  bool result = PKCS7_verify(pkcs7, extra_signers, x509_store_, indata,
1045  bp_content, flags);
1046  if (result != 1) {
1047  BIO_free(bp_content);
1048  PKCS7_free(pkcs7);
1049  return false;
1050  }
1051 
1052  BUF_MEM *bufmem_content;
1053  BIO_get_mem_ptr(bp_content, &bufmem_content);
1054  // BIO_free() leaves BUF_MEM alone
1055  (void)BIO_set_close(bp_content, BIO_NOCLOSE);
1056  BIO_free(bp_content);
1057  *content = reinterpret_cast<unsigned char *>(bufmem_content->data);
1058  *content_size = bufmem_content->length;
1059  free(bufmem_content);
1060  if (*content == NULL) {
1061  PKCS7_free(pkcs7);
1062  LogCvmfs(kLogSignature, kLogDebug, "empty pkcs#7 structure");
1063  return false;
1064  }
1065 
1066  // Extract signing certificates
1067  STACK_OF(X509) *signers = NULL;
1068  signers = PKCS7_get0_signers(pkcs7, NULL, 0);
1069  assert(signers);
1070 
1071  // Extract alternative names
1072  for (int i = 0; i < sk_X509_num(signers); ++i) {
1073  X509 *this_signer = sk_X509_value(signers, i);
1074  GENERAL_NAMES *subject_alt_names = NULL;
1075  subject_alt_names = reinterpret_cast<GENERAL_NAMES *>(
1076  X509_get_ext_d2i(this_signer, NID_subject_alt_name, NULL, NULL));
1077  if (subject_alt_names != NULL) {
1078  for (int j = 0; j < sk_GENERAL_NAME_num(subject_alt_names); ++j) {
1079  GENERAL_NAME *this_name = sk_GENERAL_NAME_value(subject_alt_names, j);
1080  if (this_name->type != GEN_URI)
1081  continue;
1082 
1083  const char *name_ptr = reinterpret_cast<const char *>(
1084 #ifdef OPENSSL_API_INTERFACE_V11
1085  ASN1_STRING_get0_data(this_name->d.uniformResourceIdentifier));
1086 #else
1087  ASN1_STRING_data(this_name->d.uniformResourceIdentifier));
1088 #endif
1089  int name_len = ASN1_STRING_length(
1090  this_name->d.uniformResourceIdentifier);
1091  if (!name_ptr || (name_len <= 0))
1092  continue;
1093  alt_uris->push_back(string(name_ptr, name_len));
1094  }
1095  }
1096  }
1097  sk_X509_free(signers);
1098  PKCS7_free(pkcs7);
1099  return true;
1100 }
1101 
1102 } // 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:2309
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:2116
void HashMem(const unsigned char *buffer, const unsigned buffer_size, Any *any_digest)
Definition: hash.cc:257
static void Fini()
Definition: cvmfs.cc:2528
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