aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/asn1
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-03-16 01:27:29 -0400
committerJack Lloyd <[email protected]>2016-03-16 01:27:29 -0400
commiteba8e2e0f1baf64637acda3f049fa14f79283201 (patch)
treea9f5311413629259f8169b80eef87312c8760ee2 /src/lib/asn1
parent93966abb3c51a77edf867abe7d7388ec542411bb (diff)
parentefe8e7d46683ceab23889fda7fcbc68303f23d62 (diff)
Merge GH #454 X.509 name constraints
Diffstat (limited to 'src/lib/asn1')
-rw-r--r--src/lib/asn1/oid_lookup/default.cpp1
-rw-r--r--src/lib/asn1/x509_dn.cpp103
-rw-r--r--src/lib/asn1/x509_dn.h1
3 files changed, 96 insertions, 9 deletions
diff --git a/src/lib/asn1/oid_lookup/default.cpp b/src/lib/asn1/oid_lookup/default.cpp
index 5bd268e5b..fe7a42748 100644
--- a/src/lib/asn1/oid_lookup/default.cpp
+++ b/src/lib/asn1/oid_lookup/default.cpp
@@ -177,6 +177,7 @@ const char* default_oid_list()
"2.5.29.21 = X509v3.ReasonCode" "\n"
"2.5.29.23 = X509v3.HoldInstructionCode" "\n"
"2.5.29.24 = X509v3.InvalidityDate" "\n"
+ "2.5.29.30 = X509v3.NameConstraints" "\n"
"2.5.29.31 = X509v3.CRLDistributionPoints" "\n"
"2.5.29.32 = X509v3.CertificatePolicies" "\n"
"2.5.29.35 = X509v3.AuthorityKeyIdentifier" "\n"
diff --git a/src/lib/asn1/x509_dn.cpp b/src/lib/asn1/x509_dn.cpp
index 9c36cd695..e9a4731b3 100644
--- a/src/lib/asn1/x509_dn.cpp
+++ b/src/lib/asn1/x509_dn.cpp
@@ -12,6 +12,7 @@
#include <botan/internal/stl_util.h>
#include <botan/oids.h>
#include <ostream>
+#include <cctype>
namespace Botan {
@@ -117,15 +118,15 @@ std::vector<byte> X509_DN::get_bits() const
*/
std::string X509_DN::deref_info_field(const std::string& info)
{
- if(info == "Name" || info == "CommonName") return "X520.CommonName";
- if(info == "SerialNumber") return "X520.SerialNumber";
- if(info == "Country") return "X520.Country";
- if(info == "Organization") return "X520.Organization";
- if(info == "Organizational Unit" || info == "OrgUnit")
+ if(info == "Name" || info == "CommonName" || info == "CN") return "X520.CommonName";
+ if(info == "SerialNumber" || info == "SN") return "X520.SerialNumber";
+ if(info == "Country" || info == "C") return "X520.Country";
+ if(info == "Organization" || info == "O") return "X520.Organization";
+ if(info == "Organizational Unit" || info == "OrgUnit" || info == "OU")
return "X520.OrganizationalUnit";
- if(info == "Locality") return "X520.Locality";
- if(info == "State" || info == "Province") return "X520.State";
- if(info == "Email") return "RFC822";
+ if(info == "Locality" || info == "L") return "X520.Locality";
+ if(info == "State" || info == "Province" || info == "ST") return "X520.State";
+ if(info == "Email") return "RFC822";
return info;
}
@@ -303,9 +304,93 @@ std::ostream& operator<<(std::ostream& out, const X509_DN& dn)
for(std::multimap<std::string, std::string>::const_iterator i = contents.begin();
i != contents.end(); ++i)
{
- out << to_short_form(i->first) << "=" << i->second << ' ';
+ out << to_short_form(i->first) << "=\"";
+ for(char c: i->second)
+ {
+ if(c == '\\' || c == '\"')
+ {
+ out << "\\";
+ }
+ out << c;
+ }
+ out << "\"";
+
+ if(std::next(i) != contents.end())
+ {
+ out << ",";
+ }
}
return out;
}
+std::istream& operator>>(std::istream& in, X509_DN& dn)
+ {
+ in >> std::noskipws;
+ do
+ {
+ std::string key;
+ std::string val;
+ char c;
+
+ while(in.good())
+ {
+ in >> c;
+
+ if(std::isspace(c) && key.empty())
+ continue;
+ else if(!std::isspace(c))
+ {
+ key.push_back(c);
+ break;
+ }
+ else
+ break;
+ }
+
+ while(in.good())
+ {
+ in >> c;
+
+ if(!std::isspace(c) && c != '=')
+ key.push_back(c);
+ else if(c == '=')
+ break;
+ else
+ throw Invalid_Argument("Ill-formed X.509 DN");
+ }
+
+ bool in_quotes = false;
+ while(in.good())
+ {
+ in >> c;
+
+ if(std::isspace(c))
+ {
+ if(!in_quotes && !val.empty())
+ break;
+ else if(in_quotes)
+ val.push_back(' ');
+ }
+ else if(c == '"')
+ in_quotes = !in_quotes;
+ else if(c == '\\')
+ {
+ if(in.good())
+ in >> c;
+ val.push_back(c);
+ }
+ else if(c == ',' && !in_quotes)
+ break;
+ else
+ val.push_back(c);
+ }
+
+ if(!key.empty() && !val.empty())
+ dn.add_attribute(X509_DN::deref_info_field(key),val);
+ else
+ break;
+ }
+ while(in.good());
+ return in;
+ }
}
diff --git a/src/lib/asn1/x509_dn.h b/src/lib/asn1/x509_dn.h
index 12553a1a0..2b841feb6 100644
--- a/src/lib/asn1/x509_dn.h
+++ b/src/lib/asn1/x509_dn.h
@@ -50,6 +50,7 @@ bool BOTAN_DLL operator!=(const X509_DN&, const X509_DN&);
bool BOTAN_DLL operator<(const X509_DN&, const X509_DN&);
BOTAN_DLL std::ostream& operator<<(std::ostream& out, const X509_DN& dn);
+BOTAN_DLL std::istream& operator>>(std::istream& in, X509_DN& dn);
}