aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-03-06 05:55:23 -0500
committerJack Lloyd <[email protected]>2016-03-06 05:55:23 -0500
commitb73ecdcb0ad7199e95b4a06eb029edb49eef6a47 (patch)
treeb18b0580cc64d19f64853fb96013349c57866c73
parent27c9aeb85849b0b2808e95f50656d0a3c0aa6371 (diff)
parent6ab73e03710a93dbef18d65a84fbe1d702b7d795 (diff)
Merge GH #437 add X509_Certificate::v3_extensions
Makes it possible for an application to interpret some extension not supported by the library.
-rw-r--r--src/lib/cert/x509/x509_ext.cpp34
-rw-r--r--src/lib/cert/x509/x509_ext.h8
-rw-r--r--src/lib/cert/x509/x509cert.cpp6
-rw-r--r--src/lib/cert/x509/x509cert.h7
4 files changed, 35 insertions, 20 deletions
diff --git a/src/lib/cert/x509/x509_ext.cpp b/src/lib/cert/x509/x509_ext.cpp
index 7dd4a3190..f8f9adb2b 100644
--- a/src/lib/cert/x509/x509_ext.cpp
+++ b/src/lib/cert/x509/x509_ext.cpp
@@ -53,14 +53,12 @@ Extensions::Extensions(const Extensions& extensions) : ASN1_Object()
* Extensions Assignment Operator
*/
Extensions& Extensions::operator=(const Extensions& other)
- {
- for(size_t i = 0; i != m_extensions.size(); ++i)
- delete m_extensions[i].first;
+ {
m_extensions.clear();
for(size_t i = 0; i != other.m_extensions.size(); ++i)
m_extensions.push_back(
- std::make_pair(other.m_extensions[i].first->copy(),
+ std::make_pair(std::unique_ptr<Certificate_Extension>(other.m_extensions[i].first->copy()),
other.m_extensions[i].second));
m_throw_on_unknown_critical = other.m_throw_on_unknown_critical;
@@ -78,7 +76,14 @@ OID Certificate_Extension::oid_of() const
void Extensions::add(Certificate_Extension* extn, bool critical)
{
- m_extensions.push_back(std::make_pair(extn, critical));
+ m_extensions.push_back(std::make_pair(std::unique_ptr<Certificate_Extension>(extn), critical));
+ m_extensions_raw.emplace(extn->oid_of(), std::make_pair(extn->encode_inner(), critical));
+ }
+
+
+std::map<OID, std::pair<std::vector<byte>, bool>> Extensions::extensions_raw() const
+ {
+ return m_extensions_raw;
}
/*
@@ -88,7 +93,7 @@ void Extensions::encode_into(DER_Encoder& to_object) const
{
for(size_t i = 0; i != m_extensions.size(); ++i)
{
- const Certificate_Extension* ext = m_extensions[i].first;
+ const Certificate_Extension* ext = m_extensions[i].first.get();
const bool is_critical = m_extensions[i].second;
const bool should_encode = ext->should_encode();
@@ -109,9 +114,8 @@ void Extensions::encode_into(DER_Encoder& to_object) const
*/
void Extensions::decode_from(BER_Decoder& from_source)
{
- for(size_t i = 0; i != m_extensions.size(); ++i)
- delete m_extensions[i].first;
m_extensions.clear();
+ m_extensions_raw.clear();
BER_Decoder sequence = from_source.start_cons(SEQUENCE);
@@ -128,7 +132,9 @@ void Extensions::decode_from(BER_Decoder& from_source)
.verify_end()
.end_cons();
- Certificate_Extension* ext = get_extension(oid);
+ m_extensions_raw.emplace(oid, std::make_pair(value, critical));
+
+ std::unique_ptr<Certificate_Extension> ext(get_extension(oid));
if(!ext && critical && m_throw_on_unknown_critical)
throw Decoding_Error("Encountered unknown X.509 extension marked "
@@ -146,7 +152,7 @@ void Extensions::decode_from(BER_Decoder& from_source)
oid.as_string() + ": " + e.what());
}
- m_extensions.push_back(std::make_pair(ext, critical));
+ m_extensions.push_back(std::make_pair(std::move(ext), critical));
}
}
@@ -163,14 +169,6 @@ void Extensions::contents_to(Data_Store& subject_info,
m_extensions[i].first->contents_to(subject_info, issuer_info);
}
-/*
-* Delete an Extensions list
-*/
-Extensions::~Extensions()
- {
- for(size_t i = 0; i != m_extensions.size(); ++i)
- delete m_extensions[i].first;
- }
namespace Cert_Extension {
diff --git a/src/lib/cert/x509/x509_ext.h b/src/lib/cert/x509/x509_ext.h
index 0614b9a52..8d2dcb52b 100644
--- a/src/lib/cert/x509/x509_ext.h
+++ b/src/lib/cert/x509/x509_ext.h
@@ -67,16 +67,20 @@ class BOTAN_DLL Extensions : public ASN1_Object
void add(Certificate_Extension* extn, bool critical = false);
+ std::map<OID, std::pair<std::vector<byte>, bool>> extensions_raw() const;
+
Extensions& operator=(const Extensions&);
Extensions(const Extensions&);
+
explicit Extensions(bool st = true) : m_throw_on_unknown_critical(st) {}
- ~Extensions();
+
private:
static Certificate_Extension* get_extension(const OID&);
- std::vector<std::pair<Certificate_Extension*, bool> > m_extensions;
+ std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> m_extensions;
bool m_throw_on_unknown_critical;
+ std::map<OID, std::pair<std::vector<byte>, bool>> m_extensions_raw;
};
namespace Cert_Extension {
diff --git a/src/lib/cert/x509/x509cert.cpp b/src/lib/cert/x509/x509cert.cpp
index cb24a7a03..8d6d9a70a 100644
--- a/src/lib/cert/x509/x509cert.cpp
+++ b/src/lib/cert/x509/x509cert.cpp
@@ -124,6 +124,7 @@ void X509_Certificate::force_decode()
BER_Decoder(v3_exts_data.value).decode(extensions).verify_end();
+ m_v3_extensions = extensions.extensions_raw();
extensions.contents_to(m_subject, m_issuer);
}
else if(v3_exts_data.type_tag != NO_OBJECT)
@@ -303,6 +304,11 @@ std::vector<std::string> X509_Certificate::policies() const
return lookup_oids(m_subject.get("X509v3.CertificatePolicies"));
}
+std::map<OID, std::pair<std::vector<byte>, bool>> X509_Certificate::v3_extensions() const
+ {
+ return m_v3_extensions;
+ }
+
std::string X509_Certificate::ocsp_responder() const
{
return m_subject.get1("OCSP.responder", "");
diff --git a/src/lib/cert/x509/x509cert.h b/src/lib/cert/x509/x509cert.h
index 0329fde47..32f2bba9f 100644
--- a/src/lib/cert/x509/x509cert.h
+++ b/src/lib/cert/x509/x509cert.h
@@ -178,6 +178,12 @@ class BOTAN_DLL X509_Certificate final : public X509_Object
std::vector<std::string> policies() const;
/**
+ * Get all extensions of this certificate indexed by oid.
+ * @return extension values and critical flag
+ */
+ std::map<OID, std::pair<std::vector<byte>, bool>> v3_extensions() const;
+
+ /**
* Return the listed address of an OCSP responder, or empty if not set
*/
std::string ocsp_responder() const;
@@ -240,6 +246,7 @@ class BOTAN_DLL X509_Certificate final : public X509_Object
Data_Store m_subject, m_issuer;
bool m_self_signed;
+ std::map<OID, std::pair<std::vector<byte>, bool>> m_v3_extensions;
};
/**