diff options
author | lloyd <[email protected]> | 2010-11-29 15:14:32 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-11-29 15:14:32 +0000 |
commit | 01bbd9f35711a059e9f90e1a79bf8d0e862c9950 (patch) | |
tree | 16b9b277d68658bc13be49fe96877ab464f7d79a | |
parent | 53a6da362130ae60ce0f93b341b4825200d9966d (diff) |
Add X509_Certificate::to_string
The x509info example now just calls that
-rw-r--r-- | doc/examples/x509info.cpp | 123 | ||||
-rw-r--r-- | doc/log.txt | 2 | ||||
-rw-r--r-- | src/cert/x509cert/x509cert.cpp | 107 | ||||
-rw-r--r-- | src/cert/x509cert/x509cert.h | 5 |
4 files changed, 113 insertions, 124 deletions
diff --git a/doc/examples/x509info.cpp b/doc/examples/x509info.cpp index 52cc4afbd..b22b4ebd8 100644 --- a/doc/examples/x509info.cpp +++ b/doc/examples/x509info.cpp @@ -7,48 +7,9 @@ #include <botan/botan.h> #include <botan/x509cert.h> -#include <botan/oids.h> using namespace Botan; #include <iostream> -#include <iterator> -#include <algorithm> - -namespace { - -std::string to_hex(const SecureVector<byte>& bin) - { - Pipe pipe(new Hex_Encoder); - pipe.process_msg(bin); - if(pipe.remaining()) - return pipe.read_all_as_string(); - else - return "(none)"; - } - -void do_print(const std::string& what, - const std::vector<std::string>& vals) - { - if(vals.size() == 0) - return; - - std::cout << " " << what << ": "; - std::copy(vals.begin(), vals.end(), - std::ostream_iterator<std::string>(std::cout, " ")); - std::cout << "\n"; - } - -void do_subject(const X509_Certificate& cert, const std::string& what) - { - do_print(what, cert.subject_info(what)); - } - -void do_issuer(const X509_Certificate& cert, const std::string& what) - { - do_print(what, cert.issuer_info(what)); - } - -} int main(int argc, char* argv[]) { @@ -63,89 +24,7 @@ int main(int argc, char* argv[]) try { X509_Certificate cert(argv[1]); - std::cout << "Version: " << cert.x509_version() << std::endl; - - std::cout << "Subject" << std::endl; - do_subject(cert, "Name"); - do_subject(cert, "Email"); - do_subject(cert, "Organization"); - do_subject(cert, "Organizational Unit"); - do_subject(cert, "Locality"); - do_subject(cert, "State"); - do_subject(cert, "Country"); - do_subject(cert, "IP"); - do_subject(cert, "DNS"); - do_subject(cert, "URI"); - do_subject(cert, "PKIX.XMPPAddr"); - - std::cout << "Issuer" << std::endl; - do_issuer(cert, "Name"); - do_issuer(cert, "Email"); - do_issuer(cert, "Organization"); - do_issuer(cert, "Organizational Unit"); - do_issuer(cert, "Locality"); - do_issuer(cert, "State"); - do_issuer(cert, "Country"); - do_issuer(cert, "IP"); - do_issuer(cert, "DNS"); - do_issuer(cert, "URI"); - - std::cout << "Validity" << std::endl; - - std::cout << " Not before: " << cert.start_time() << std::endl; - std::cout << " Not after: " << cert.end_time() << std::endl; - - std::cout << "Constraints" << std::endl; - Key_Constraints constraints = cert.constraints(); - if(constraints == NO_CONSTRAINTS) - std::cout << "No constraints" << std::endl; - else - { - if(constraints & DIGITAL_SIGNATURE) - std::cout << " Digital Signature\n"; - if(constraints & NON_REPUDIATION) - std::cout << " Non-Repuidation\n"; - if(constraints & KEY_ENCIPHERMENT) - std::cout << " Key Encipherment\n"; - if(constraints & DATA_ENCIPHERMENT) - std::cout << " Data Encipherment\n"; - if(constraints & KEY_AGREEMENT) - std::cout << " Key Agreement\n"; - if(constraints & KEY_CERT_SIGN) - std::cout << " Cert Sign\n"; - if(constraints & CRL_SIGN) - std::cout << " CRL Sign\n"; - } - - std::vector<std::string> policies = cert.policies(); - if(policies.size()) - { - std::cout << "Policies: " << std::endl; - for(u32bit j = 0; j != policies.size(); j++) - std::cout << " " << policies[j] << std::endl; - } - - std::vector<std::string> ex_constraints = cert.ex_constraints(); - if(ex_constraints.size()) - { - std::cout << "Extended Constraints: " << std::endl; - for(u32bit j = 0; j != ex_constraints.size(); j++) - std::cout << " " << ex_constraints[j] << std::endl; - } - - std::cout << "Signature algorithm: " << - OIDS::lookup(cert.signature_algorithm().oid) << std::endl; - - std::cout << "Serial: " - << to_hex(cert.serial_number()) << std::endl; - std::cout << "Authority keyid: " - << to_hex(cert.authority_key_id()) << std::endl; - std::cout << "Subject keyid: " - << to_hex(cert.subject_key_id()) << std::endl; - - X509_PublicKey* pubkey = cert.subject_public_key(); - std::cout << "Public Key:\n" << X509::PEM_encode(*pubkey); - delete pubkey; + std::cout << cert.to_string(); } catch(std::exception& e) { diff --git a/doc/log.txt b/doc/log.txt index 09054b496..b3837eff9 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -10,6 +10,7 @@ - Removed AES class: app must choose AES-128, AES-192, or AES-256 - Add hex encoding/decoding functions that can be used without a Pipe - Add base64 encoding functions that can be used without a Pipe + - Add to_string function to X509_Certificate - Add support for dynamic engine loading on Windows - Replace BlockCipher::BLOCK_SIZE attribute with function block_size() - Replace HashFunction::HASH_BLOCK_SIZE attribute with hash_block_size() @@ -22,6 +23,7 @@ - Switch default PKCS #8 encryption algorithm from AES-128 to AES-256 - Update Skein-512 to match the v1.3 specification - Allow using PBKDF2 with empty passphrases + - Add compile-time deprecation warnings for GCC, Clang, and MSVC - Support use of HMAC(SHA-256) and CMAC(Blowfish) in passhash9 - Improve support for Intel Atom processors - Fix compilation problems under Sun Studio and Clang diff --git a/src/cert/x509cert/x509cert.cpp b/src/cert/x509cert/x509cert.cpp index 05f23298b..4eef215f8 100644 --- a/src/cert/x509cert/x509cert.cpp +++ b/src/cert/x509cert/x509cert.cpp @@ -1,6 +1,6 @@ /* * X.509 Certificates -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -14,7 +14,10 @@ #include <botan/bigint.h> #include <botan/oids.h> #include <botan/pem.h> +#include <botan/hex.h> #include <algorithm> +#include <iterator> +#include <sstream> namespace Botan { @@ -84,7 +87,7 @@ void X509_Certificate::force_decode() .decode(dn_subject); if(version > 2) - throw Decoding_Error("Unknown X.509 cert version " + to_string(version)); + throw Decoding_Error("Unknown X.509 cert version " + Botan::to_string(version)); if(sig_algo != sig_algo_inner) throw Decoding_Error("Algorithm identifier mismatch"); @@ -299,6 +302,106 @@ bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2) return !(cert1 == cert2); } +std::string X509_Certificate::to_string() const + { + const char* dn_fields[] = { "Name", + "Email", + "Organization", + "Organizational Unit", + "Locality", + "State", + "Country", + "IP", + "DNS", + "URI", + "PKIX.XMPPAddr", + 0 }; + + std::ostringstream out; + + for(size_t i = 0; dn_fields[i]; ++i) + { + const std::vector<std::string> vals = this->subject_info(dn_fields[i]); + + if(vals.empty()) + continue; + + out << "Subject " << dn_fields[i] << ":"; + for(size_t i = 0; i != vals.size(); ++i) + out << " " << vals[i]; + out << "\n"; + } + + for(size_t i = 0; dn_fields[i]; ++i) + { + const std::vector<std::string> vals = this->issuer_info(dn_fields[i]); + + if(vals.empty()) + continue; + + out << "Issuer " << dn_fields[i] << ":"; + for(size_t i = 0; i != vals.size(); ++i) + out << " " << vals[i]; + out << "\n"; + } + + out << "Version: " << this->x509_version() << "\n"; + + out << "Not valid before: " << this->start_time() << "\n"; + out << "Not valid after: " << this->end_time() << "\n"; + + out << "Constraints:\n"; + Key_Constraints constraints = this->constraints(); + if(constraints == NO_CONSTRAINTS) + out << " None\n"; + else + { + if(constraints & DIGITAL_SIGNATURE) + out << " Digital Signature\n"; + if(constraints & NON_REPUDIATION) + out << " Non-Repuidation\n"; + if(constraints & KEY_ENCIPHERMENT) + out << " Key Encipherment\n"; + if(constraints & DATA_ENCIPHERMENT) + out << " Data Encipherment\n"; + if(constraints & KEY_AGREEMENT) + out << " Key Agreement\n"; + if(constraints & KEY_CERT_SIGN) + out << " Cert Sign\n"; + if(constraints & CRL_SIGN) + out << " CRL Sign\n"; + } + + std::vector<std::string> policies = this->policies(); + if(policies.size()) + { + out << "Policies: " << "\n"; + for(u32bit j = 0; j != policies.size(); j++) + out << " " << policies[j] << "\n"; + } + + std::vector<std::string> ex_constraints = this->ex_constraints(); + if(ex_constraints.size()) + { + out << "Extended Constraints:\n"; + for(u32bit j = 0; j != ex_constraints.size(); j++) + out << " " << ex_constraints[j] << "\n"; + } + + out << "Signature algorithm: " << + OIDS::lookup(this->signature_algorithm().oid) << "\n"; + + out << "Serial number: " << hex_encode(this->serial_number()) << "\n"; + out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n"; + out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n"; + + X509_PublicKey* pubkey = this->subject_public_key(); + out << "Public Key:\n" << X509::PEM_encode(*pubkey); + delete pubkey; + + return out.str(); + } + /* * Create and populate a X509_DN */ diff --git a/src/cert/x509cert/x509cert.h b/src/cert/x509cert/x509cert.h index 754553f3d..8798ef1c2 100644 --- a/src/cert/x509cert/x509cert.h +++ b/src/cert/x509cert/x509cert.h @@ -141,6 +141,11 @@ class BOTAN_DLL X509_Certificate : public X509_Object std::vector<std::string> policies() const; /** + * @return a string describing the certificate + */ + std::string to_string() const; + + /** * Check to certificates for equality. * @return true both certificates are (binary) equal */ |