aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli/x509.cpp
diff options
context:
space:
mode:
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