CernVM-FS  2.9.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 "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 "compression.h"
31 #include "duplex_ssl.h"
32 #include "hash.h"
33 #include "logging.h"
34 #include "platform.h"
35 #include "prng.h"
36 #include "smalloc.h"
37 #include "util/string.h"
38 #include "util_concurrency.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 
171 bool SignatureManager::LoadPrivateKeyPath(const string &file_pem,
172  const string &password)
173 {
174  UnloadPrivateKey();
175  bool result;
176  FILE *fp = NULL;
177  char *tmp = strdupa(password.c_str());
178 
179  if ((fp = fopen(file_pem.c_str(), "r")) == NULL)
180  return false;
181  result = (private_key_ = PEM_read_PrivateKey(fp, NULL, NULL, tmp)) != NULL;
182  fclose(fp);
183  return result;
184 }
185 
186 
190 void SignatureManager::UnloadPrivateKey() {
191  if (private_key_) EVP_PKEY_free(private_key_);
192  private_key_ = NULL;
193 }
194 
195 
196 void SignatureManager::UnloadCertificate() {
197  if (certificate_) X509_free(certificate_);
198  certificate_ = NULL;
199 }
200 
201 
205 void SignatureManager::UnloadPrivateMasterKey() {
206  if (private_master_key_) RSA_free(private_master_key_);
207  private_master_key_ = NULL;
208 }
209 
210 
217 bool SignatureManager::LoadCertificatePath(const string &file_pem) {
218  if (certificate_) {
219  X509_free(certificate_);
220  certificate_ = NULL;
221  }
222 
223  bool result;
224  char *nopwd = strdupa("");
225  FILE *fp;
226 
227  if ((fp = fopen(file_pem.c_str(), "r")) == NULL)
228  return false;
229  result = (certificate_ = PEM_read_X509_AUX(fp, NULL, NULL, nopwd)) != NULL;
230 
231  if (!result && certificate_) {
232  X509_free(certificate_);
233  certificate_ = NULL;
234  }
235 
236  fclose(fp);
237  return result;
238 }
239 
240 
244 bool SignatureManager::LoadCertificateMem(const unsigned char *buffer,
245  const unsigned buffer_size)
246 {
247  if (certificate_) {
248  X509_free(certificate_);
249  certificate_ = NULL;
250  }
251 
252  bool result;
253  char *nopwd = strdupa("");
254 
255  BIO *mem = BIO_new(BIO_s_mem());
256  if (!mem) return false;
257  if (BIO_write(mem, buffer, buffer_size) <= 0) {
258  BIO_free(mem);
259  return false;
260  }
261  result = (certificate_ = PEM_read_bio_X509_AUX(mem, NULL, NULL, nopwd))
262  != NULL;
263  BIO_free(mem);
264 
265  if (!result && certificate_) {
266  X509_free(certificate_);
267  certificate_ = NULL;
268  }
269 
270  return result;
271 }
272 
273 
277 bool SignatureManager::LoadPublicRsaKeys(const string &path_list) {
278  UnloadPublicRsaKeys();
279 
280  if (path_list == "")
281  return true;
282  const vector<string> pem_files = SplitString(path_list, ':');
283 
284  char *nopwd = strdupa("");
285  FILE *fp;
286 
287  for (unsigned i = 0; i < pem_files.size(); ++i) {
288  const char* pubkey_file = pem_files[i].c_str();
289 
290  // open public key file
291  fp = fopen(pubkey_file, "r");
292  if (fp == NULL) {
293  LogCvmfs(kLogSignature, kLogDebug | kLogSyslogErr, "failed to open "
294  "public key '%s'",
295  pubkey_file);
296  return false;
297  }
298 
299  // load the public key from the file (and close it)
300  EVP_PKEY *this_key = PEM_read_PUBKEY(fp, NULL, NULL, nopwd);
301  fclose(fp);
302  if (this_key == NULL) {
303  LogCvmfs(kLogSignature, kLogDebug | kLogSyslogErr, "failed to load "
304  "public key '%s'",
305  pubkey_file);
306  return false;
307  }
308 
309  // read the RSA key from the loaded public key
310  RSA *key = EVP_PKEY_get1_RSA(this_key);
311  EVP_PKEY_free(this_key);
312  if (key == NULL) {
313  LogCvmfs(kLogSignature, kLogDebug | kLogSyslogErr, "failed to read "
314  "public key '%s'",
315  pubkey_file);
316  return false;
317  }
318 
319  // store the loaded public key
320  public_keys_.push_back(key);
321  }
322 
323  return true;
324 }
325 
326 
327 void SignatureManager::UnloadPublicRsaKeys() {
328  for (unsigned i = 0; i < public_keys_.size(); ++i)
329  RSA_free(public_keys_[i]);
330  public_keys_.clear();
331 }
332 
333 
334 std::string SignatureManager::GenerateKeyText(RSA *pubkey) const {
335  if (!pubkey) {return "";}
336 
337  BIO *bp = BIO_new(BIO_s_mem());
338  if (bp == NULL) {
339  LogCvmfs(kLogSignature, kLogDebug | kLogSyslogErr, "Failed to allocate"
340  " memory for pubkey");
341  return "";
342  }
343  if (!PEM_write_bio_RSA_PUBKEY(bp, pubkey)) {
344  LogCvmfs(kLogSignature, kLogDebug | kLogSyslogErr, "Failed to write"
345  " pubkey to memory");
346  return "";
347  }
348  char *bio_pubkey_text;
349  long bytes = BIO_get_mem_data(bp, &bio_pubkey_text); // NOLINT
350  std::string bio_pubkey_str(bio_pubkey_text, bytes);
351  BIO_free(bp);
352 
353  return bio_pubkey_str;
354 }
355 
356 
357 std::string SignatureManager::GetActivePubkeys() const {
358  std::string pubkeys;
359  for (std::vector<RSA *>::const_iterator it = public_keys_.begin();
360  it != public_keys_.end();
361  it++) {
362  pubkeys += GenerateKeyText(*it);
363  }
364  // NOTE: we do not add the pubkey of the certificate here, as it is
365  // not used for the whitelist verification.
366  return pubkeys;
367 }
368 
369 
370 std::string SignatureManager::GetCertificate() const {
371  if (!certificate_) return "";
372 
373  BIO *bp = BIO_new(BIO_s_mem());
374  assert(bp != NULL);
375  bool rvb = PEM_write_bio_X509(bp, certificate_);
376  assert(rvb);
377  char *bio_crt_text;
378  long bytes = BIO_get_mem_data(bp, &bio_crt_text); // NOLINT
379  assert(bytes > 0);
380  std::string bio_crt_str(bio_crt_text, bytes);
381  BIO_free(bp);
382  return bio_crt_str;
383 }
384 
385 
386 std::string SignatureManager::GetPrivateKey() {
387  if (!private_key_) return "";
388 
389  BIO *bp = BIO_new(BIO_s_mem());
390  assert(bp != NULL);
391  bool rvb = PEM_write_bio_PrivateKey(bp, private_key_, NULL, NULL, 0, 0, NULL);
392  assert(rvb);
393  char *bio_privkey_text;
394  long bytes = BIO_get_mem_data(bp, &bio_privkey_text); // NOLINT
395  assert(bytes > 0);
396  std::string bio_privkey_str(bio_privkey_text, bytes);
397  BIO_free(bp);
398  return bio_privkey_str;
399 }
400 
401 
402 std::string SignatureManager::GetPrivateMasterKey() {
403  if (!private_master_key_) return "";
404 
405  BIO *bp = BIO_new(BIO_s_mem());
406  assert(bp != NULL);
407  bool rvb = PEM_write_bio_RSAPrivateKey(bp, private_master_key_,
408  NULL, NULL, 0, 0, NULL);
409  assert(rvb);
410  char *bio_master_privkey_text;
411  long bytes = BIO_get_mem_data(bp, &bio_master_privkey_text); // NOLINT
412  assert(bytes > 0);
413  std::string bio_master_privkey_str(bio_master_privkey_text, bytes);
414  BIO_free(bp);
415  return bio_master_privkey_str;
416 }
417 
418 RSA *SignatureManager::GenerateRsaKeyPair() {
419  RSA *rsa = NULL;
420  BIGNUM *bn = BN_new();
421  int retval = BN_set_word(bn, RSA_F4);
422  assert(retval == 1);
423 #ifdef OPENSSL_API_INTERFACE_V09
424  rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
425  assert(rsa != NULL);
426 #else
427  rsa = RSA_new();
428  retval = RSA_generate_key_ex(rsa, 2048, bn, NULL);
429  assert(retval == 1);
430 #endif
431  BN_free(bn);
432  return rsa;
433 }
434 
435 
439 void SignatureManager::GenerateMasterKeyPair() {
440  UnloadPrivateMasterKey();
441  UnloadPublicRsaKeys();
442 
443  RSA *rsa = GenerateRsaKeyPair();
444  private_master_key_ = RSAPrivateKey_dup(rsa);
445  public_keys_.push_back(RSAPublicKey_dup(rsa));
446  RSA_free(rsa);
447 }
448 
452 void SignatureManager::GenerateCertificate(const std::string &cn) {
453  UnloadPrivateKey();
454  UnloadCertificate();
455  int retval;
456 
457  RSA *rsa = GenerateRsaKeyPair();
458  private_key_ = EVP_PKEY_new();
459  retval = EVP_PKEY_set1_RSA(private_key_, RSAPrivateKey_dup(rsa));
460  assert(retval == 1);
461  EVP_PKEY *pkey = EVP_PKEY_new();
462  retval = EVP_PKEY_set1_RSA(pkey, rsa);
463  assert(retval == 1);
464 
465  certificate_ = X509_new();
466  X509_set_version(certificate_, 2L);
467  X509_set_pubkey(certificate_, pkey);
468 
469  Prng prng;
470  prng.InitLocaltime();
471  unsigned long rnd_serial_no = prng.Next(uint64_t(1) + uint32_t(-1)); //NOLINT
472  rnd_serial_no = rnd_serial_no |
473  uint64_t(prng.Next(uint64_t(1) + uint32_t(-1))) << 32;
474  ASN1_INTEGER_set(X509_get_serialNumber(certificate_), rnd_serial_no);
475 
476  // valid as of now
477  X509_gmtime_adj(reinterpret_cast<ASN1_TIME *>(
478  X509_get_notBefore(certificate_)), 0);
479  // valid for 1 year (validity range is unused)
480  X509_gmtime_adj(reinterpret_cast<ASN1_TIME *>(
481  X509_get_notAfter(certificate_)), 3600 * 24 * 365);
482 
483  X509_NAME *name = X509_get_subject_name(certificate_);
484 #ifdef OPENSSL_API_INTERFACE_V09
485  X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
486  const_cast<unsigned char *>(
487  reinterpret_cast<const unsigned char *>(cn.c_str())),
488  -1, -1, 0);
489 #else
490  X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
491  reinterpret_cast<const unsigned char *>(cn.c_str()), -1, -1, 0);
492 #endif
493  retval = X509_set_issuer_name(certificate_, name);
494  assert(retval == 1);
495 
496 #ifdef OPENSSL_API_INTERFACE_V09
497  retval = X509_sign(certificate_, pkey, EVP_sha1());
498 #else
499  retval = X509_sign(certificate_, pkey, EVP_sha256());
500 #endif
501  EVP_PKEY_free(pkey);
502  assert(retval > 0);
503 }
504 
508 bool SignatureManager::LoadBlacklist(
509  const std::string &path_blacklist,
510  bool append)
511 {
512  MutexLockGuard lock_guard(&lock_blacklist_);
513  LogCvmfs(kLogSignature, kLogDebug, "reading from blacklist %s",
514  path_blacklist.c_str());
515  if (!append)
516  blacklist_.clear();
517 
518  char *buffer;
519  unsigned buffer_size;
520  if (!CopyPath2Mem(path_blacklist,
521  reinterpret_cast<unsigned char **>(&buffer), &buffer_size))
522  {
523  return false;
524  }
525 
526  unsigned num_bytes = 0;
527  while (num_bytes < buffer_size) {
528  const string line = GetLineMem(buffer + num_bytes,
529  buffer_size - num_bytes);
530  blacklist_.push_back(line);
531  num_bytes += line.length() + 1;
532  }
533  free(buffer);
534 
535  return true;
536 }
537 
538 
539 vector<string> SignatureManager::GetBlacklist() {
540  MutexLockGuard lock_guard(&lock_blacklist_);
541  return blacklist_;
542 }
543 
544 
552 bool SignatureManager::LoadTrustedCaCrl(const string &path_list) {
553  InitX509Store();
554 
555  /* TODO if (path_list == "") {
556  return true;
557  }*/
558  const vector<string> paths = SplitString(path_list, ':');
559  for (unsigned i = 0; i < paths.size(); ++i) {
560  int retval = X509_LOOKUP_add_dir(x509_lookup_, paths[i].c_str(),
561  X509_FILETYPE_PEM);
562  if (!retval)
563  return false;
564  }
565  return true;
566 }
567 
568 
574 shash::Any SignatureManager::HashCertificate(
575  const shash::Algorithms hash_algorithm)
576 {
577  shash::Any result;
578  if (!certificate_)
579  return result;
580 
581  int buffer_size;
582  unsigned char *buffer = NULL;
583 
584  buffer_size = i2d_X509(certificate_, &buffer);
585  if (buffer_size < 0)
586  return result;
587 
588  result.algorithm = hash_algorithm;
589  shash::HashMem(buffer, buffer_size, &result);
590  free(buffer);
591 
592  return result;
593 }
594 
595 
601 string SignatureManager::FingerprintCertificate(
602  const shash::Algorithms hash_algorithm)
603 {
604  shash::Any hash = HashCertificate(hash_algorithm);
605  if (hash.IsNull())
606  return "";
607 
608  const string hash_str = hash.ToString();
609  string result;
610  for (unsigned i = 0; i < hash_str.length(); ++i) {
611  if (i < 2*shash::kDigestSizes[hash_algorithm]) {
612  if ((i > 0) && (i%2 == 0)) result += ":";
613  }
614  result += toupper(hash_str[i]);
615  }
616  return result;
617 }
618 
619 
623 shash::Any SignatureManager::MkFromFingerprint(const std::string &fingerprint) {
624  string convert;
625  for (unsigned i = 0; i < fingerprint.length(); ++i) {
626  if ((fingerprint[i] == ' ') || (fingerprint[i] == '\t') ||
627  (fingerprint[i] == '#'))
628  {
629  break;
630  }
631  if (fingerprint[i] != ':')
632  convert.push_back(tolower(fingerprint[i]));
633  }
634 
635  return shash::MkFromHexPtr(shash::HexPtr(convert));
636 }
637 
638 
642 string SignatureManager::Whois() {
643  if (!certificate_) return "No certificate loaded";
644 
645  string result;
646  X509_NAME *subject = X509_get_subject_name(certificate_);
647  X509_NAME *issuer = X509_get_issuer_name(certificate_);
648  char *buffer = NULL;
649  buffer = X509_NAME_oneline(subject, NULL, 0);
650  if (buffer) {
651  result = "Publisher: " + string(buffer);
652  free(buffer);
653  }
654  buffer = X509_NAME_oneline(issuer, NULL, 0);
655  if (buffer) {
656  result += "\nCertificate issued by: " + string(buffer);
657  free(buffer);
658  }
659  return result;
660 }
661 
662 
663 bool SignatureManager::WriteCertificateMem(unsigned char **buffer,
664  unsigned *buffer_size)
665 {
666  BIO *mem = BIO_new(BIO_s_mem());
667  if (!mem) return false;
668  if (!PEM_write_bio_X509(mem, certificate_)) {
669  BIO_free(mem);
670  return false;
671  }
672 
673  void *bio_buffer;
674  *buffer_size = BIO_get_mem_data(mem, &bio_buffer);
675  *buffer = reinterpret_cast<unsigned char *>(smalloc(*buffer_size));
676  memcpy(*buffer, bio_buffer, *buffer_size);
677  BIO_free(mem);
678  return true;
679 }
680 
681 
687 bool SignatureManager::KeysMatch() {
688  if (!certificate_ || !private_key_)
689  return false;
690 
691  bool result = false;
692  const unsigned char *sign_me = reinterpret_cast<const unsigned char *>
693  ("sign me");
694  unsigned char *signature = NULL;
695  unsigned signature_size;
696  if (Sign(sign_me, 7, &signature, &signature_size) &&
697  Verify(sign_me, 7, signature, signature_size))
698  {
699  result = true;
700  }
701  if (signature) free(signature);
702  return result;
703 }
704 
705 
709 bool SignatureManager::VerifyCaChain() {
710  if (!certificate_)
711  return false;
712 
713  X509_STORE_CTX *csc = NULL;
714  csc = X509_STORE_CTX_new();
715  assert(csc);
716 
717  X509_STORE_CTX_init(csc, x509_store_, certificate_, NULL);
718  bool result = X509_verify_cert(csc) == 1;
719  X509_STORE_CTX_free(csc);
720 
721  return result;
722 }
723 
724 
730 bool SignatureManager::Sign(const unsigned char *buffer,
731  const unsigned buffer_size,
732  unsigned char **signature,
733  unsigned *signature_size)
734 {
735  if (!private_key_) {
736  *signature_size = 0;
737  *signature = NULL;
738  return false;
739  }
740 
741  bool result = false;
742 #ifdef OPENSSL_API_INTERFACE_V11
743  EVP_MD_CTX *ctx_ptr = EVP_MD_CTX_new();
744 #else
745  EVP_MD_CTX ctx;
746  EVP_MD_CTX_init(&ctx);
747  EVP_MD_CTX *ctx_ptr = &ctx;
748 #endif
749 
750  *signature = reinterpret_cast<unsigned char *>(
751  smalloc(EVP_PKEY_size(private_key_)));
752  if (EVP_SignInit(ctx_ptr, EVP_sha1()) &&
753  EVP_SignUpdate(ctx_ptr, buffer, buffer_size) &&
754  EVP_SignFinal(ctx_ptr, *signature, signature_size, private_key_))
755  {
756  result = true;
757  }
758 #ifdef OPENSSL_API_INTERFACE_V11
759  EVP_MD_CTX_free(ctx_ptr);
760 #else
761  EVP_MD_CTX_cleanup(&ctx);
762 #endif
763  if (!result) {
764  free(*signature);
765  *signature_size = 0;
766  *signature = NULL;
767  }
768 
769  return result;
770 }
771 
772 
778 bool SignatureManager::SignRsa(const unsigned char *buffer,
779  const unsigned buffer_size,
780  unsigned char **signature,
781  unsigned *signature_size)
782 {
783  if (!private_master_key_) {
784  *signature_size = 0;
785  *signature = NULL;
786  return false;
787  }
788 
789  unsigned char *to = (unsigned char *)smalloc(RSA_size(private_master_key_));
790  unsigned char *from = (unsigned char *)smalloc(buffer_size);
791  memcpy(from, buffer, buffer_size);
792 
793  int size = RSA_private_encrypt(buffer_size, from, to,
794  private_master_key_, RSA_PKCS1_PADDING);
795  free(from);
796  if (size < 0) {
797  *signature_size = 0;
798  *signature = NULL;
799  return false;
800  }
801  *signature = to;
802  *signature_size = size;
803  return true;
804 }
805 
806 
812 bool SignatureManager::Verify(const unsigned char *buffer,
813  const unsigned buffer_size,
814  const unsigned char *signature,
815  const unsigned signature_size)
816 {
817  if (!certificate_) return false;
818 
819  bool result = false;
820 #ifdef OPENSSL_API_INTERFACE_V11
821  EVP_MD_CTX *ctx_ptr = EVP_MD_CTX_new();
822 #else
823  EVP_MD_CTX ctx;
824  EVP_MD_CTX_init(&ctx);
825  EVP_MD_CTX *ctx_ptr = &ctx;
826 #endif
827 
828  EVP_PKEY *pubkey = X509_get_pubkey(certificate_);
829  if (EVP_VerifyInit(ctx_ptr, EVP_sha1()) &&
830  EVP_VerifyUpdate(ctx_ptr, buffer, buffer_size) &&
832  EVP_VerifyFinal(ctx_ptr,
833  const_cast<unsigned char *>(signature), signature_size,
834  pubkey)
835 #else
836  EVP_VerifyFinal(ctx_ptr, signature, signature_size, pubkey)
837 #endif
838  )
839  {
840  result = true;
841  }
842  if (pubkey != NULL)
843  EVP_PKEY_free(pubkey);
844 #ifdef OPENSSL_API_INTERFACE_V11
845  EVP_MD_CTX_free(ctx_ptr);
846 #else
847  EVP_MD_CTX_cleanup(&ctx);
848 #endif
849 
850  return result;
851 }
852 
853 
859 bool SignatureManager::VerifyRsa(const unsigned char *buffer,
860  const unsigned buffer_size,
861  const unsigned char *signature,
862  const unsigned signature_size)
863 {
864  for (unsigned i = 0, s = public_keys_.size(); i < s; ++i) {
865  if (buffer_size > (unsigned)RSA_size(public_keys_[i]))
866  continue;
867 
868  unsigned char *to = (unsigned char *)smalloc(RSA_size(public_keys_[i]));
869  unsigned char *from = (unsigned char *)smalloc(signature_size);
870  memcpy(from, signature, signature_size);
871 
872  int size = RSA_public_decrypt(signature_size, from, to,
873  public_keys_[i], RSA_PKCS1_PADDING);
874  free(from);
875  if ((size >= 0) && (unsigned(size) == buffer_size) &&
876  (memcmp(buffer, to, size) == 0))
877  {
878  free(to);
879  return true;
880  }
881 
882  free(to);
883  }
884 
885  LogCvmfs(kLogSignature, kLogDebug, "VerifyRsa, no public key fits");
886  return false;
887 }
888 
889 
893 void SignatureManager::CutLetter(const unsigned char *buffer,
894  const unsigned buffer_size,
895  const char separator,
896  unsigned *letter_length,
897  unsigned *pos_after_mark)
898 {
899  unsigned pos = 0;
900  *letter_length = *pos_after_mark = 0;
901  do {
902  if (pos == buffer_size) {
903  *pos_after_mark = pos; // Careful: pos_after_mark points out of buffer
904  *letter_length = pos;
905  break;
906  }
907 
908  if ((buffer[pos] == '\n') && (pos+4 <= buffer_size) &&
909  (buffer[pos+1] == separator) && (buffer[pos+2] == separator) &&
910  (buffer[pos+3] == '\n'))
911  {
912  *letter_length = pos+1;
913  pos += 4;
914  break;
915  }
916  pos++;
917  } while (true);
918  *pos_after_mark = pos;
919 }
920 
921 
929 bool SignatureManager::VerifyLetter(const unsigned char *buffer,
930  const unsigned buffer_size,
931  const bool by_rsa)
932 {
933  unsigned pos = 0;
934  unsigned letter_length = 0;
935  CutLetter(buffer, buffer_size, '-', &letter_length, &pos);
936  if (pos >= buffer_size)
937  return false;
938 
939  string hash_str = "";
940  unsigned hash_pos = pos;
941  do {
942  if (pos == buffer_size)
943  return false;
944  if (buffer[pos] == '\n') {
945  pos++;
946  break;
947  }
948  hash_str.push_back(buffer[pos++]);
949  } while (true);
950  shash::Any hash_printed = shash::MkFromHexPtr(shash::HexPtr(hash_str));
951  shash::Any hash_computed(hash_printed.algorithm);
952  shash::HashMem(buffer, letter_length, &hash_computed);
953  if (hash_printed != hash_computed)
954  return false;
955 
956  if (by_rsa) {
957  return VerifyRsa(&buffer[hash_pos], hash_str.length(),
958  &buffer[pos], buffer_size-pos);
959  } else {
960  return Verify(&buffer[hash_pos], hash_str.length(),
961  &buffer[pos], buffer_size-pos);
962  }
963 }
964 
965 
970 bool SignatureManager::VerifyPkcs7(const unsigned char *buffer,
971  const unsigned buffer_size,
972  unsigned char **content,
973  unsigned *content_size,
974  vector<string> *alt_uris)
975 {
976  *content = NULL;
977  *content_size = 0;
978 
979  BIO *bp_pkcs7 = BIO_new(BIO_s_mem());
980  if (!bp_pkcs7) return false;
981  if (BIO_write(bp_pkcs7, buffer, buffer_size) <= 0) {
982  BIO_free(bp_pkcs7);
983  return false;
984  }
985 
986  PKCS7 *pkcs7 = NULL;
987  pkcs7 = PEM_read_bio_PKCS7(bp_pkcs7, NULL, NULL, NULL);
988  BIO_free(bp_pkcs7);
989  if (!pkcs7) {
990  LogCvmfs(kLogSignature, kLogDebug, "invalid pkcs#7 signature");
991  return false;
992  }
993 
994  BIO *bp_content = BIO_new(BIO_s_mem());
995  if (!bp_content) {
996  PKCS7_free(pkcs7);
997  return false;
998  }
999 
1000  int flags = 0;
1001  STACK_OF(X509) *extra_signers = NULL;
1002  BIO *indata = NULL;
1003  bool result = PKCS7_verify(pkcs7, extra_signers, x509_store_, indata,
1004  bp_content, flags);
1005  if (result != 1) {
1006  BIO_free(bp_content);
1007  PKCS7_free(pkcs7);
1008  return false;
1009  }
1010 
1011  BUF_MEM *bufmem_content;
1012  BIO_get_mem_ptr(bp_content, &bufmem_content);
1013  // BIO_free() leaves BUF_MEM alone
1014  (void) BIO_set_close(bp_content, BIO_NOCLOSE);
1015  BIO_free(bp_content);
1016  *content = reinterpret_cast<unsigned char *>(bufmem_content->data);
1017  *content_size = bufmem_content->length;
1018  free(bufmem_content);
1019  if (*content == NULL) {
1020  PKCS7_free(pkcs7);
1021  LogCvmfs(kLogSignature, kLogDebug, "empty pkcs#7 structure");
1022  return false;
1023  }
1024 
1025  // Extract signing certificates
1026  STACK_OF(X509) *signers = NULL;
1027  signers = PKCS7_get0_signers(pkcs7, NULL, 0);
1028  assert(signers);
1029 
1030  // Extract alternative names
1031  for (int i = 0; i < sk_X509_num(signers); ++i) {
1032  X509* this_signer = sk_X509_value(signers, i);
1033  GENERAL_NAMES *subject_alt_names = NULL;
1034  subject_alt_names = reinterpret_cast<GENERAL_NAMES *>(
1035  X509_get_ext_d2i(this_signer, NID_subject_alt_name, NULL, NULL));
1036  if (subject_alt_names != NULL) {
1037  for (int j = 0; j < sk_GENERAL_NAME_num(subject_alt_names); ++j) {
1038  GENERAL_NAME *this_name = sk_GENERAL_NAME_value(subject_alt_names, j);
1039  if (this_name->type != GEN_URI)
1040  continue;
1041 
1042  const char *name_ptr = reinterpret_cast<const char *>(
1043 #ifdef OPENSSL_API_INTERFACE_V11
1044  ASN1_STRING_get0_data(this_name->d.uniformResourceIdentifier));
1045 #else
1046  ASN1_STRING_data(this_name->d.uniformResourceIdentifier));
1047 #endif
1048  int name_len =
1049  ASN1_STRING_length(this_name->d.uniformResourceIdentifier);
1050  if (!name_ptr || (name_len <= 0))
1051  continue;
1052  alt_uris->push_back(string(name_ptr, name_len));
1053  }
1054  }
1055  }
1056  sk_X509_free(signers);
1057  PKCS7_free(pkcs7);
1058  return true;
1059 }
1060 
1061 } // namespace signature
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
Definition: prng.h:25
bool IsNull() const
Definition: hash.h:379
struct cvmcache_context * ctx
string GetLineMem(const char *text, const int text_size)
Definition: string.cc:373
vector< string > SplitString(const string &str, const char delim, const unsigned max_chunks)
Definition: string.cc:288
std::string ToString(const bool with_suffix=false) const
Definition: hash.h:245
void InitLocaltime()
Definition: prng.h:35
assert((mem||(size==0))&&"Out Of Memory")
Algorithms algorithm
Definition: hash.h:123
Failures Verify(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)
bool CopyPath2Mem(const string &path, unsigned char **buffer, unsigned *buffer_size)
Definition: compression.cc:108
Algorithms
Definition: hash.h:39
#define strdupa(s)
Definition: platform_osx.h:285
const char * kDefaultPublicKey
Definition: signature.cc:44
#define OPENSSL_API_INTERFACE_V09
Definition: duplex_ssl.h:16
Any MkFromHexPtr(const HexPtr hex, const char suffix)
Definition: hash.cc:83
static int Init(const loader::LoaderExports *loader_exports)
Definition: cvmfs.cc:1755
static int CallbackCertVerify(int ok, X509_STORE_CTX *ctx)
Definition: signature.cc:47
void HashMem(const unsigned char *buffer, const unsigned buffer_size, Any *any_digest)
Definition: hash.cc:255
static void Fini()
Definition: cvmfs.cc:1961
return mem
Definition: smalloc.h:50
static void size_t size
Definition: smalloc.h:47
const unsigned kDigestSizes[]
Definition: hash.h:67
uint32_t Next(const uint64_t boundary)
Definition: prng.h:45