aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli/x509.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-12-19 15:36:40 -0500
committerJack Lloyd <[email protected]>2015-12-19 15:36:40 -0500
commitb48e6fb097c62bb246629ee7a182c57e497e4130 (patch)
tree0cb8ea2d05a89f5e90467f323ae56268d4d3480e /src/cli/x509.cpp
parentd774a9edc46ffcebb28205a678058f083ea75c28 (diff)
CLI rewrite
The command line tools' origin as a collection of examples and test programs glued together led to some unfortunate problems; lots of hardcoded values, missing parameters, and obsolete crypto. Adds a small library for writing command line programs of the sort needed here (cli.h), which cuts the length of many of the commands in half and makes commands more pleasant to write and extend. Generalizes a lot of the commands also, eg previously only signing/verification with DSA/SHA-1 was included! Removes the fuzzer entry point since that's fairly useless outside of an instrumented build. Removes the in-library API for benchmarking.
Diffstat (limited to 'src/cli/x509.cpp')
-rw-r--r--src/cli/x509.cpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/cli/x509.cpp b/src/cli/x509.cpp
new file mode 100644
index 000000000..add73a466
--- /dev/null
+++ b/src/cli/x509.cpp
@@ -0,0 +1,224 @@
+/*
+* (C) 2010,2014,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "cli.h"
+
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+
+#include <botan/auto_rng.h>
+#include <botan/certstor.h>
+#include <botan/pkcs8.h>
+#include <botan/x509_ca.h>
+#include <botan/x509cert.h>
+#include <botan/x509path.h>
+#include <botan/x509self.h>
+
+#if defined(BOTAN_HAS_OCSP)
+ #include <botan/ocsp.h>
+#endif
+
+namespace Botan_CLI {
+
+class Sign_Cert : public Command
+ {
+ public:
+ Sign_Cert() : Command("sign_cert --ca-key-pass= --hash=SHA-256 "
+ "--duration=365 ca_cert ca_key pkcs10_req") {}
+
+ void go() override
+ {
+ Botan::AutoSeeded_RNG rng;
+
+ Botan::X509_Certificate ca_cert(get_arg("ca_cert"));
+
+ std::unique_ptr<Botan::PKCS8_PrivateKey> key(
+ Botan::PKCS8::load_key(get_arg("ca_key"),
+ rng,
+ get_arg("ca_key_pass")));
+
+ if(!key)
+ throw CLI_Error("Failed to load key from " + get_arg("ca_key"));
+
+ Botan::X509_CA ca(ca_cert, *key, get_arg("hash"));
+
+ Botan::PKCS10_Request req(get_arg("pkcs10_req"));
+
+ auto now = std::chrono::system_clock::now();
+
+ Botan::X509_Time start_time(now);
+
+ typedef std::chrono::duration<int, std::ratio<86400>> days;
+
+ Botan::X509_Time end_time(now + days(get_arg_sz("duration")));
+
+ Botan::X509_Certificate new_cert = ca.sign_request(req, rng,
+ start_time, end_time);
+
+ output() << new_cert.PEM_encode();
+ }
+ };
+
+BOTAN_REGISTER_COMMAND(Sign_Cert);
+
+class Cert_Info : public Command
+ {
+ public:
+ Cert_Info() : Command("cert_info file") {}
+
+ void go() override
+ {
+ Botan::X509_Certificate cert(get_arg("file"));
+ output() << cert.to_string() << "\n";
+ }
+ };
+
+BOTAN_REGISTER_COMMAND(Cert_Info);
+
+#if defined(BOTAN_HAS_OCSP)
+class OCSP_Check : public Command
+ {
+ public:
+ OCSP_Check() : Command("ocsp_check subject issuer") {}
+
+ void go() override
+ {
+ Botan::X509_Certificate subject(get_arg("subject"));
+ Botan::X509_Certificate issuer(get_arg("issuer"));
+
+ Botan::Certificate_Store_In_Memory cas;
+ cas.add_certificate(issuer);
+ Botan::OCSP::Response resp = Botan::OCSP::online_check(issuer, subject, &cas);
+
+ auto status = resp.status_for(issuer, subject);
+
+ if(status == Botan::Certificate_Status_Code::VERIFIED)
+ {
+ output() << "OCSP check OK\n";
+ }
+ else
+ {
+ output() << "OCSP check failed " <<
+ Botan::Path_Validation_Result::status_string(status) << "\n";
+ }
+ }
+ };
+
+BOTAN_REGISTER_COMMAND(OCSP_Check);
+
+#endif // OCSP
+
+class Cert_Verify : public Command
+ {
+ public:
+ Cert_Verify() : Command("cert_verify subject *ca_certs") {}
+
+ void go() override
+ {
+ Botan::X509_Certificate subject_cert(get_arg("subject"));
+ Botan::Certificate_Store_In_Memory trusted;
+
+ for(auto&& certfile : get_arg_list("ca_certs"))
+ {
+ trusted.add_certificate(Botan::X509_Certificate(certfile));
+ }
+
+ Botan::Path_Validation_Restrictions restrictions;
+
+ Botan::Path_Validation_Result result =
+ Botan::x509_path_validate(subject_cert,
+ restrictions,
+ trusted);
+
+ if(result.successful_validation())
+ {
+ output() << "Certificate passes validation checks\n";
+ }
+ else
+ {
+ output() << "Certificate did not validate - " << result.result_string() << "\n";
+ }
+ }
+ };
+
+BOTAN_REGISTER_COMMAND(Cert_Verify);
+
+class Gen_Self_Signed : public Command
+ {
+ public:
+ Gen_Self_Signed() : Command("gen_self_signed key CN --country= --dns= "
+ "--organization= --email= --key-pass= --ca --hash=SHA-256") {}
+
+ void go() override
+ {
+ Botan::AutoSeeded_RNG rng;
+
+ std::unique_ptr<Botan::Private_Key> key(
+ Botan::PKCS8::load_key(get_arg("key"),
+ rng,
+ get_arg("key-pass")));
+
+ if(!key)
+ throw CLI_Error("Failed to load key from " + get_arg("key"));
+
+ Botan::X509_Cert_Options opts;
+
+ opts.common_name = get_arg("CN");
+ opts.country = get_arg("country");
+ opts.organization = get_arg("organization");
+ opts.email = get_arg("email");
+ opts.dns = get_arg("dns");
+
+ if(flag_set("ca"))
+ opts.CA_key();
+
+ Botan::X509_Certificate cert =
+ Botan::X509::create_self_signed_cert(opts, *key, get_arg("hash"), rng);
+
+ output() << cert.PEM_encode();
+ }
+ };
+
+BOTAN_REGISTER_COMMAND(Gen_Self_Signed);
+
+class Generate_PKCS10 : public Command
+ {
+ public:
+ Generate_PKCS10() : Command("gen_pkcs10 key CN --country= --organization= "
+ "--email= --key-pass= --hash=SHA-256") {}
+
+ void go() override
+ {
+ Botan::AutoSeeded_RNG rng;
+
+ std::unique_ptr<Botan::Private_Key> key(
+ Botan::PKCS8::load_key(get_arg("key"),
+ rng,
+ get_arg("key-pass")));
+
+ if(!key)
+ throw CLI_Error("Failed to load key from " + get_arg("key"));
+
+ Botan::X509_Cert_Options opts;
+
+ opts.common_name = get_arg("CN");
+ opts.country = get_arg("country");
+ opts.organization = get_arg("organization");
+ opts.email = get_arg("email");
+
+ Botan::PKCS10_Request req =
+ Botan::X509::create_cert_req(opts, *key,
+ get_arg("hash"),
+ rng);
+
+ output() << req.PEM_encode();
+ }
+ };
+
+BOTAN_REGISTER_COMMAND(Generate_PKCS10);
+
+}
+
+#endif