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