aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-05-27 16:51:00 +0000
committerlloyd <[email protected]>2012-05-27 16:51:00 +0000
commit0beeb8caab674b173902b3a44952240d34710d30 (patch)
tree64d95e58bbd3b16b5fb6d3768ccfd4829f6731f9 /src
parent446d572d4984fa1f62001a0db7ac65b1201cbf45 (diff)
Derive X509_Object from ASN1_Object.
In the path validator, pass singlular Certificate_Store args as const reference and const_cast them. It's not ideal but it seems to lead to the cleanest external API. Treat all v1 X.509 certs as implicit CAs.
Diffstat (limited to 'src')
-rw-r--r--src/asn1/ber_dec.h12
-rw-r--r--src/cert/x509/x509_obj.cpp38
-rw-r--r--src/cert/x509/x509_obj.h7
-rw-r--r--src/cert/x509/x509cert.cpp6
-rw-r--r--src/cert/x509/x509cert.h2
-rw-r--r--src/cert/x509/x509path.cpp13
-rw-r--r--src/cert/x509/x509path.h4
7 files changed, 52 insertions, 30 deletions
diff --git a/src/asn1/ber_dec.h b/src/asn1/ber_dec.h
index 6ca9aa777..3aa141550 100644
--- a/src/asn1/ber_dec.h
+++ b/src/asn1/ber_dec.h
@@ -95,7 +95,8 @@ class BOTAN_DLL BER_Decoder
template<typename T>
BER_Decoder& decode_list(std::vector<T>& out,
- bool clear_out = true);
+ ASN1_Tag type_tag = SEQUENCE,
+ ASN1_Tag class_tag = UNIVERSAL);
template<typename T>
BER_Decoder& decode_and_check(const T& expected,
@@ -171,12 +172,11 @@ BER_Decoder& BER_Decoder::decode_optional(T& out,
* Decode a list of homogenously typed values
*/
template<typename T>
-BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec, bool clear_it)
+BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec,
+ ASN1_Tag type_tag,
+ ASN1_Tag class_tag)
{
- if(clear_it)
- vec.clear();
-
- BER_Decoder list = start_cons(SEQUENCE);
+ BER_Decoder list = start_cons(type_tag, class_tag);
while(list.more_items())
{
diff --git a/src/cert/x509/x509_obj.cpp b/src/cert/x509/x509_obj.cpp
index 4270dfec2..ff116d894 100644
--- a/src/cert/x509/x509_obj.cpp
+++ b/src/cert/x509/x509_obj.cpp
@@ -58,7 +58,10 @@ void X509_Object::init(DataSource& in, const std::string& labels)
try {
if(ASN1::maybe_BER(in) && !PEM_Code::matches(in))
- decode_info(in);
+ {
+ BER_Decoder dec(in);
+ decode_from(dec);
+ }
else
{
std::string got_label;
@@ -67,7 +70,9 @@ void X509_Object::init(DataSource& in, const std::string& labels)
if(!std::binary_search(PEM_labels_allowed.begin(),
PEM_labels_allowed.end(), got_label))
throw Decoding_Error("Invalid PEM label: " + got_label);
- decode_info(ber);
+
+ BER_Decoder dec(ber);
+ decode_from(dec);
}
}
catch(Decoding_Error& e)
@@ -76,13 +81,24 @@ void X509_Object::init(DataSource& in, const std::string& labels)
}
}
+
+void X509_Object::encode_into(DER_Encoder& to) const
+ {
+ to.start_cons(SEQUENCE)
+ .start_cons(SEQUENCE)
+ .raw_bytes(tbs_bits)
+ .end_cons()
+ .encode(sig_algo)
+ .encode(sig, BIT_STRING)
+ .end_cons();
+ }
+
/*
* Read a BER encoded X.509 object
*/
-void X509_Object::decode_info(DataSource& source)
+void X509_Object::decode_from(BER_Decoder& from)
{
- BER_Decoder(source)
- .start_cons(SEQUENCE)
+ from.start_cons(SEQUENCE)
.start_cons(SEQUENCE)
.raw_bytes(tbs_bits)
.end_cons()
@@ -108,15 +124,9 @@ void X509_Object::encode(Pipe& out, X509_Encoding encoding) const
*/
std::vector<byte> X509_Object::BER_encode() const
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .start_cons(SEQUENCE)
- .raw_bytes(tbs_bits)
- .end_cons()
- .encode(sig_algo)
- .encode(sig, BIT_STRING)
- .end_cons()
- .get_contents_unlocked();
+ DER_Encoder der;
+ encode_into(der);
+ return der.get_contents_unlocked();
}
/*
diff --git a/src/cert/x509/x509_obj.h b/src/cert/x509/x509_obj.h
index e91389acf..75a0b5c02 100644
--- a/src/cert/x509/x509_obj.h
+++ b/src/cert/x509/x509_obj.h
@@ -20,7 +20,7 @@ namespace Botan {
* This class represents abstract X.509 signed objects as
* in the X.500 SIGNED macro
*/
-class BOTAN_DLL X509_Object
+class BOTAN_DLL X509_Object : public ASN1_Object
{
public:
/**
@@ -72,6 +72,10 @@ class BOTAN_DLL X509_Object
*/
bool check_signature(const Public_Key* key) const;
+ void encode_into(class DER_Encoder& to) const override;
+
+ void decode_from(class BER_Decoder& from) override;
+
/**
* @return BER encoding of this
*/
@@ -104,7 +108,6 @@ class BOTAN_DLL X509_Object
private:
virtual void force_decode() = 0;
void init(DataSource&, const std::string&);
- void decode_info(DataSource&);
std::vector<std::string> PEM_labels_allowed;
std::string PEM_label_pref;
diff --git a/src/cert/x509/x509cert.cpp b/src/cert/x509/x509cert.cpp
index a2dc1d7b5..176604b63 100644
--- a/src/cert/x509/x509cert.cpp
+++ b/src/cert/x509/x509cert.cpp
@@ -144,6 +144,12 @@ void X509_Certificate::force_decode()
subject.add("X509.Certificate.public_key",
hex_encode(public_key.value));
+ if(self_signed && version == 0)
+ {
+ subject.add("X509v3.BasicConstraints.is_ca", 1);
+ subject.add("X509v3.BasicConstraints.path_constraint", Cert_Extension::NO_CERT_PATH_LIMIT);
+ }
+
if(is_CA_cert() &&
!subject.has_value("X509v3.BasicConstraints.path_constraint"))
{
diff --git a/src/cert/x509/x509cert.h b/src/cert/x509/x509cert.h
index 9f8fdadb8..0accf7113 100644
--- a/src/cert/x509/x509cert.h
+++ b/src/cert/x509/x509cert.h
@@ -200,6 +200,8 @@ class BOTAN_DLL X509_Certificate : public X509_Object
private:
void force_decode();
friend class X509_CA;
+ friend class BER_Decoder;
+
X509_Certificate() {}
Data_Store subject, issuer;
diff --git a/src/cert/x509/x509path.cpp b/src/cert/x509/x509path.cpp
index 159787800..9b2b3227f 100644
--- a/src/cert/x509/x509path.cpp
+++ b/src/cert/x509/x509path.cpp
@@ -41,8 +41,9 @@ X509_Certificate find_issuing_cert(const X509_Certificate& cert,
certstores[i]->find_cert_by_subject_and_key_id(issuer_dn, auth_key_id);
if(certs.size() == 0)
- throw PKIX_Validation_Failure(Path_Validation_Result::CERT_ISSUER_NOT_FOUND);
- else if(certs.size() > 1)
+ continue;
+
+ if(certs.size() > 1)
throw PKIX_Validation_Failure(Path_Validation_Result::CERT_MULTIPLE_ISSUERS_FOUND);
return certs[0];
@@ -160,10 +161,10 @@ Path_Validation_Result x509_path_validate(
Path_Validation_Result x509_path_validate(
const std::vector<X509_Certificate>& end_certs,
const Path_Validation_Restrictions& restrictions,
- Certificate_Store& store)
+ const Certificate_Store& store)
{
std::vector<Certificate_Store*> certstores;
- certstores.push_back(&store);
+ certstores.push_back(const_cast<Certificate_Store*>(&store));
return x509_path_validate(end_certs, restrictions, certstores);
}
@@ -171,13 +172,13 @@ Path_Validation_Result x509_path_validate(
Path_Validation_Result x509_path_validate(
const X509_Certificate& end_cert,
const Path_Validation_Restrictions& restrictions,
- Certificate_Store& store)
+ const Certificate_Store& store)
{
std::vector<X509_Certificate> certs;
certs.push_back(end_cert);
std::vector<Certificate_Store*> certstores;
- certstores.push_back(&store);
+ certstores.push_back(const_cast<Certificate_Store*>(&store));
return x509_path_validate(certs, restrictions, certstores);
}
diff --git a/src/cert/x509/x509path.h b/src/cert/x509/x509path.h
index 18129a236..21b808073 100644
--- a/src/cert/x509/x509path.h
+++ b/src/cert/x509/x509path.h
@@ -112,12 +112,12 @@ Path_Validation_Result BOTAN_DLL x509_path_validate(
Path_Validation_Result BOTAN_DLL x509_path_validate(
const X509_Certificate& end_cert,
const Path_Validation_Restrictions& restrictions,
- Certificate_Store& store);
+ const Certificate_Store& store);
Path_Validation_Result BOTAN_DLL x509_path_validate(
const std::vector<X509_Certificate>& end_certs,
const Path_Validation_Restrictions& restrictions,
- Certificate_Store& store);
+ const Certificate_Store& store);
}