monotone

monotone Mtn Source Tree

Root/botan/asn1_dn.cpp

1/*************************************************
2* X509_DN Source File *
3* (C) 1999-2007 The Botan Project *
4*************************************************/
5
6#include <botan/asn1_obj.h>
7#include <botan/der_enc.h>
8#include <botan/ber_dec.h>
9#include <botan/parsing.h>
10#include <botan/stl_util.h>
11#include <botan/oids.h>
12
13namespace Botan {
14
15/*************************************************
16* Create an empty X509_DN *
17*************************************************/
18X509_DN::X509_DN()
19 {
20 }
21
22/*************************************************
23* Create an X509_DN *
24*************************************************/
25X509_DN::X509_DN(const std::multimap<OID, std::string>& args)
26 {
27 std::multimap<OID, std::string>::const_iterator j;
28 for(j = args.begin(); j != args.end(); ++j)
29 add_attribute(j->first, j->second);
30 }
31
32/*************************************************
33* Create an X509_DN *
34*************************************************/
35X509_DN::X509_DN(const std::multimap<std::string, std::string>& args)
36 {
37 std::multimap<std::string, std::string>::const_iterator j;
38 for(j = args.begin(); j != args.end(); ++j)
39 add_attribute(OIDS::lookup(j->first), j->second);
40 }
41
42/*************************************************
43* Add an attribute to a X509_DN *
44*************************************************/
45void X509_DN::add_attribute(const std::string& type,
46 const std::string& str)
47 {
48 OID oid = OIDS::lookup(type);
49 add_attribute(oid, str);
50 }
51
52/*************************************************
53* Add an attribute to a X509_DN *
54*************************************************/
55void X509_DN::add_attribute(const OID& oid, const std::string& str)
56 {
57 if(str == "")
58 return;
59
60 typedef std::multimap<OID, ASN1_String>::iterator rdn_iter;
61
62 std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);
63 for(rdn_iter j = range.first; j != range.second; ++j)
64 if(j->second.value() == str)
65 return;
66
67 multimap_insert(dn_info, oid, ASN1_String(str));
68 dn_bits.destroy();
69 }
70
71/*************************************************
72* Get the attributes of this X509_DN *
73*************************************************/
74std::multimap<OID, std::string> X509_DN::get_attributes() const
75 {
76 typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;
77
78 std::multimap<OID, std::string> retval;
79 for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j)
80 multimap_insert(retval, j->first, j->second.value());
81 return retval;
82 }
83
84/*************************************************
85* Get the contents of this X.500 Name *
86*************************************************/
87std::multimap<std::string, std::string> X509_DN::contents() const
88 {
89 typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;
90
91 std::multimap<std::string, std::string> retval;
92 for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j)
93 multimap_insert(retval, OIDS::lookup(j->first), j->second.value());
94 return retval;
95 }
96
97/*************************************************
98* Get a single attribute type *
99*************************************************/
100std::vector<std::string> X509_DN::get_attribute(const std::string& attr) const
101 {
102 typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;
103
104 const OID oid = OIDS::lookup(deref_info_field(attr));
105 std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);
106
107 std::vector<std::string> values;
108 for(rdn_iter j = range.first; j != range.second; ++j)
109 values.push_back(j->second.value());
110 return values;
111 }
112
113/*************************************************
114* Handle the decoding operation of a DN *
115*************************************************/
116void X509_DN::do_decode(const MemoryRegion<byte>& bits)
117 {
118 BER_Decoder sequence(bits);
119
120 while(sequence.more_items())
121 {
122 BER_Decoder rdn = sequence.start_cons(SET);
123
124 while(rdn.more_items())
125 {
126 OID oid;
127 ASN1_String str;
128
129 rdn.start_cons(SEQUENCE)
130 .decode(oid)
131 .decode(str)
132 .verify_end()
133 .end_cons();
134
135 add_attribute(oid, str.value());
136 }
137 }
138
139 dn_bits = bits;
140 }
141
142/*************************************************
143* Return the BER encoded data, if any *
144*************************************************/
145MemoryVector<byte> X509_DN::get_bits() const
146 {
147 return dn_bits;
148 }
149
150/*************************************************
151* Deref aliases in a subject/issuer info request *
152*************************************************/
153std::string X509_DN::deref_info_field(const std::string& info)
154 {
155 if(info == "Name" || info == "CommonName") return "X520.CommonName";
156 if(info == "SerialNumber") return "X520.SerialNumber";
157 if(info == "Country") return "X520.Country";
158 if(info == "Organization") return "X520.Organization";
159 if(info == "Organizational Unit" || info == "OrgUnit")
160 return "X520.OrganizationalUnit";
161 if(info == "Locality") return "X520.Locality";
162 if(info == "State" || info == "Province") return "X520.State";
163 if(info == "Email") return "RFC822";
164 return info;
165 }
166
167/*************************************************
168* Compare two X509_DNs for equality *
169*************************************************/
170bool operator==(const X509_DN& dn1, const X509_DN& dn2)
171 {
172 typedef std::multimap<OID, std::string>::const_iterator rdn_iter;
173
174 std::multimap<OID, std::string> attr1 = dn1.get_attributes();
175 std::multimap<OID, std::string> attr2 = dn2.get_attributes();
176
177 if(attr1.size() != attr2.size()) return false;
178
179 rdn_iter p1 = attr1.begin();
180 rdn_iter p2 = attr2.begin();
181
182 while(true)
183 {
184 if(p1 == attr1.end() && p2 == attr2.end())
185 break;
186 if(p1 == attr1.end()) return false;
187 if(p2 == attr2.end()) return false;
188 if(p1->first != p2->first) return false;
189 if(!x500_name_cmp(p1->second, p2->second))
190 return false;
191 ++p1;
192 ++p2;
193 }
194 return true;
195 }
196
197/*************************************************
198* Compare two X509_DNs for inequality *
199*************************************************/
200bool operator!=(const X509_DN& dn1, const X509_DN& dn2)
201 {
202 return !(dn1 == dn2);
203 }
204
205/*************************************************
206* Compare two X509_DNs *
207*************************************************/
208bool operator<(const X509_DN& dn1, const X509_DN& dn2)
209 {
210 typedef std::multimap<OID, std::string>::const_iterator rdn_iter;
211
212 std::multimap<OID, std::string> attr1 = dn1.get_attributes();
213 std::multimap<OID, std::string> attr2 = dn2.get_attributes();
214
215 if(attr1.size() < attr2.size()) return true;
216 if(attr1.size() > attr2.size()) return false;
217
218 for(rdn_iter p1 = attr1.begin(); p1 != attr1.end(); ++p1)
219 {
220 std::multimap<OID, std::string>::const_iterator p2;
221 p2 = attr2.find(p1->first);
222 if(p2 == attr2.end()) return false;
223 if(p1->second > p2->second) return false;
224 if(p1->second < p2->second) return true;
225 }
226 return false;
227 }
228
229namespace {
230
231/*************************************************
232* DER encode a RelativeDistinguishedName *
233*************************************************/
234void do_ava(DER_Encoder& encoder,
235 const std::multimap<OID, std::string>& dn_info,
236 ASN1_Tag string_type, const std::string& oid_str,
237 bool must_exist = false)
238 {
239 typedef std::multimap<OID, std::string>::const_iterator rdn_iter;
240
241 const OID oid = OIDS::lookup(oid_str);
242 const bool exists = (dn_info.find(oid) != dn_info.end());
243
244 if(!exists && must_exist)
245 throw Encoding_Error("X509_DN: No entry for " + oid_str);
246 if(!exists) return;
247
248 std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);
249
250 for(rdn_iter j = range.first; j != range.second; ++j)
251 {
252 encoder.start_cons(SET)
253 .start_cons(SEQUENCE)
254 .encode(oid)
255 .encode(ASN1_String(j->second, string_type))
256 .end_cons()
257 .end_cons();
258 }
259 }
260
261}
262
263/*************************************************
264* DER encode a DistinguishedName *
265*************************************************/
266void X509_DN::encode_into(DER_Encoder& der) const
267 {
268 std::multimap<OID, std::string> dn_info = get_attributes();
269
270 der.start_cons(SEQUENCE);
271
272 if(dn_bits.has_items())
273 der.raw_bytes(dn_bits);
274 else
275 {
276 do_ava(der, dn_info, PRINTABLE_STRING, "X520.Country", true);
277 do_ava(der, dn_info, DIRECTORY_STRING, "X520.State");
278 do_ava(der, dn_info, DIRECTORY_STRING, "X520.Locality");
279 do_ava(der, dn_info, DIRECTORY_STRING, "X520.Organization");
280 do_ava(der, dn_info, DIRECTORY_STRING, "X520.OrganizationalUnit");
281 do_ava(der, dn_info, DIRECTORY_STRING, "X520.CommonName", true);
282 do_ava(der, dn_info, PRINTABLE_STRING, "X520.SerialNumber");
283 }
284
285 der.end_cons();
286 }
287
288/*************************************************
289* Decode a BER encoded DistinguishedName *
290*************************************************/
291void X509_DN::decode_from(BER_Decoder& source)
292 {
293 dn_info.clear();
294
295 source.start_cons(SEQUENCE)
296 .raw_bytes(dn_bits)
297 .end_cons();
298
299 do_decode(dn_bits);
300 }
301
302}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status