aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-11-29 15:14:32 +0000
committerlloyd <[email protected]>2010-11-29 15:14:32 +0000
commit01bbd9f35711a059e9f90e1a79bf8d0e862c9950 (patch)
tree16b9b277d68658bc13be49fe96877ab464f7d79a
parent53a6da362130ae60ce0f93b341b4825200d9966d (diff)
Add X509_Certificate::to_string
The x509info example now just calls that
-rw-r--r--doc/examples/x509info.cpp123
-rw-r--r--doc/log.txt2
-rw-r--r--src/cert/x509cert/x509cert.cpp107
-rw-r--r--src/cert/x509cert/x509cert.h5
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
*/