Ejemplo n.º 1
0
/*
 * Read PEM certificate from a file and return as a new X509 structure.
 */
scoped_ptr<X509>
read_x509 (const std::string& path)
{
  const auto bio = make_scoped (BIO_new_file (path.c_str (), "r"), BIO_free);
  if (!bio) {
    throw std::runtime_error ("Cannot open file: " + path);
  }

  X509 *const cert = PEM_read_bio_X509 (bio.get (), nullptr, nullptr, nullptr);
  if (!cert) {
    throw std::runtime_error ("Cannot read certificate: " + path);
  }

  return make_scoped (cert, X509_free);
}
Ejemplo n.º 2
0
int
main (int argc, char* argv[])
{
  // help
  if (argc == 2 && help_requested (argv[1])) {
    usage (argv[0], std::cout);
    return EXIT_SUCCESS;
  }

  // misuse
  if (argc != 4) {
    usage (argv[0], std::cerr);
    return EXIT_FAILURE;
  }

  // This has to be called before the verification where a number of cryptographic
  // algorithms is used (they might not be available by default).
  OpenSSL_add_all_algorithms ();

  try {
    // read the certificate
    const auto cert = read_x509 (argv[1]);
    // get the public key from the certificate (the signature was created with
    // the private key)
    const auto key = make_scoped (X509_get_pubkey (cert.get ()), EVP_PKEY_free);
    if (!key) {
      throw std::runtime_error ("Cannot get public key");
    }

    // create an enveloped message digest context
    const auto ctx = make_scoped (EVP_MD_CTX_create (), EVP_MD_CTX_destroy);

    // initialize the MD context with SHA1 algorithm (the choice of the
    // algorithm should be more flexible in most real cases)
    if (!EVP_VerifyInit_ex (ctx.get (), EVP_sha1 (), nullptr)) {
      throw std::runtime_error("Cannot initialize verification");
    }

    // the data about to be digested
    const std::vector<byte_t> data = read_file (argv[2]);

    // the signature signed by the private key paired with the public key we're
    // about to use (the public key is delivered with the certificate so it's
    // authenticity can be verified)
    const std::vector<byte_t> signature = read_file (argv[3]);

    // calculate the digest
    if (!EVP_VerifyUpdate (ctx.get (), data.data (), data.size ())) {
      throw std::runtime_error("Failed to process data");
    }

    // verify the digest
    const int result =
      EVP_VerifyFinal (
	ctx.get (), signature.data (), signature.size (), key.get ());

    if (result < 0) {
      throw std::runtime_error ("Verification error");
    }

    if (result != 0) {
      std::cout << "Verification OK" << std::endl;
      return EXIT_SUCCESS;
    }
    else {
      std::cerr << "Verification failed\n";
      return EXIT_FAILURE;
    }
  }
  catch (const std::exception& e) {
    std::cerr << "Error: " << e.what () << '\n';
    return EXIT_FAILURE;
  }
  catch (...) {
    std::cerr << "Unknown error\n";
    return EXIT_FAILURE;
  }
}
Ejemplo n.º 3
0
int main()
{
	auto t1 = make_scoped(
		[] (auto x) noexcept {

		} | options,
		[] (auto x) noexcept {

		} | options,
		[] (auto x) noexcept {

		} | on_termination
	);

	auto t2 = make_scoped(
		[] (auto x) noexcept {

		} | options,
		[] (auto x) noexcept {

		} | options,
		[] (auto x) noexcept {

		} | on_termination
	);

	auto t3 = make_scoped(
		[] (auto x) noexcept {

		} | options,
		[] (auto x) noexcept {

		} | options,
		[] (auto x) noexcept {

		} | on_termination
	);

	// Assumptions:
	// - Logical task expressions only store lvalue refs to tasks. So the
	// tasks must have been created earlier, and if the tasks go out of
	// scope before the task created from the logical task expression, bad
	// things will happen.
	// - Don't make abort_early the default. Unexpected behavior will result
	// in situations, say, where the programmer wants to run a task after at
	// least one task in a set finishes, but allow the new task to run
	// concurrently while the other tasks that have yet to be finished
	// continue to run.
	// - Note how the same task can appear in multiple subexpressions.
	// We must prepare for this with respect to synchronization.
	// - When a task expression tree is run, it should run each task that
	// appears in a subexpression. Here, also, we can make the assumption
	// that none of the tasks in the expression tree have already been
	// started or terminated.
	// - To abort early, use cancellation tokens.

	auto t4 = ((t1 && t2) || (t2 && t3)).
	make_scoped(
		[] (auto x) noexcept {
			//
		} | options,
		[] (auto x) noexcept {
			//
		} | options
	);
}
Ejemplo n.º 4
0
/*
 * A RAII wrapper around read_x509_raw().
 */
scoped_ptr<X509>
read_x509 (const std::string& path)
{
  return make_scoped (read_x509_raw (path), X509_free);
}