monotone

monotone Mtn Source Tree

Root/botan/asn1_alt.cpp

1/*************************************************
2* AlternativeName Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/asn1_obj.h>
7#include <botan/charset.h>
8
9namespace Botan {
10
11/*************************************************
12* Create an AlternativeName *
13*************************************************/
14AlternativeName::AlternativeName(const std::string& email_addr,
15 const std::string& uri,
16 const std::string& dns)
17 {
18 add_attribute("RFC822", email_addr);
19 add_attribute("DNS", dns);
20 add_attribute("URI", uri);
21 }
22
23/*************************************************
24* Add an attribute to an alternative name *
25*************************************************/
26void AlternativeName::add_attribute(const std::string& type,
27 const std::string& str)
28 {
29 if(type == "" || str == "")
30 return;
31
32 typedef std::multimap<std::string, std::string>::iterator iter;
33 std::pair<iter, iter> range = alt_info.equal_range(type);
34 for(iter j = range.first; j != range.second; j++)
35 if(j->second == str)
36 return;
37
38 multimap_insert(alt_info, type, str);
39 }
40
41/*************************************************
42* Add an OtherName field *
43*************************************************/
44void AlternativeName::add_othername(const OID& oid, const std::string& value,
45 ASN1_Tag type)
46 {
47 if(value == "")
48 return;
49 multimap_insert(othernames, oid, ASN1_String(value, type));
50 }
51
52/*************************************************
53* Get the attributes of this alternative name *
54*************************************************/
55std::multimap<std::string, std::string> AlternativeName::get_attributes() const
56 {
57 return alt_info;
58 }
59
60/*************************************************
61* Get the otherNames *
62*************************************************/
63std::multimap<OID, ASN1_String> AlternativeName::get_othernames() const
64 {
65 return othernames;
66 }
67
68/*************************************************
69* Return if this object has anything useful *
70*************************************************/
71bool AlternativeName::has_items() const
72 {
73 return (alt_info.size() > 0 || othernames.size() > 0);
74 }
75
76namespace DER {
77
78/*************************************************
79* DER encode a AlternativeName entry *
80*************************************************/
81void encode_entries(DER_Encoder& encoder, const AlternativeName& alt_name,
82 const std::string& type, ASN1_Tag tagging)
83 {
84 std::multimap<std::string, std::string> attr = alt_name.get_attributes();
85 typedef std::multimap<std::string, std::string>::iterator iter;
86
87 std::pair<iter, iter> range = attr.equal_range(type);
88 for(iter j = range.first; j != range.second; j++)
89 {
90 ASN1_String asn1_string(j->second, IA5_STRING);
91 DER::encode(encoder, asn1_string, tagging, CONTEXT_SPECIFIC);
92 }
93 }
94
95/*************************************************
96* DER encode a AlternativeName *
97*************************************************/
98void encode(DER_Encoder& encoder, const AlternativeName& alt_name)
99 {
100 encoder.start_sequence();
101
102 encode_entries(encoder, alt_name, "RFC822", ASN1_Tag(1));
103 encode_entries(encoder, alt_name, "DNS", ASN1_Tag(2));
104 encode_entries(encoder, alt_name, "URI", ASN1_Tag(6));
105
106 std::multimap<OID, ASN1_String> othernames = alt_name.get_othernames();
107
108 std::multimap<OID, ASN1_String>::const_iterator i;
109 for(i = othernames.begin(); i != othernames.end(); i++)
110 {
111 encoder.start_explicit(ASN1_Tag(0));
112 DER::encode(encoder, i->first);
113 encoder.start_explicit(ASN1_Tag(0));
114 DER::encode(encoder, i->second);
115 encoder.end_explicit(ASN1_Tag(0));
116 encoder.end_explicit(ASN1_Tag(0));
117 }
118
119 encoder.end_sequence();
120 }
121
122}
123
124namespace BER {
125
126/*************************************************
127* Decode a BER encoded AlternativeName *
128*************************************************/
129void decode(BER_Decoder& source, AlternativeName& alt_name)
130 {
131 BER_Decoder names = BER::get_subsequence(source);
132 while(names.more_items())
133 {
134 BER_Object obj = names.get_next_object();
135 if((obj.class_tag != CONTEXT_SPECIFIC) &&
136 (obj.class_tag != (CONTEXT_SPECIFIC | CONSTRUCTED)))
137 continue;
138
139 ASN1_Tag tag = obj.type_tag;
140
141 if(tag == 0)
142 {
143 BER_Decoder othername(obj.value);
144
145 OID oid;
146 BER::decode(othername, oid);
147 if(othername.more_items())
148 {
149 BER_Object othername_value_outer = othername.get_next_object();
150 othername.verify_end();
151
152 if(othername_value_outer.type_tag != ASN1_Tag(0) ||
153 othername_value_outer.class_tag !=
154 (CONTEXT_SPECIFIC | CONSTRUCTED)
155 )
156 throw Decoding_Error("Invalid tags on otherName value");
157
158 BER_Decoder othername_value_inner(othername_value_outer.value);
159
160 BER_Object value = othername_value_inner.get_next_object();
161 othername_value_inner.verify_end();
162
163 ASN1_Tag value_type = value.type_tag;
164
165 if(is_string_type(value_type) && value.class_tag == UNIVERSAL)
166 alt_name.add_othername(oid, BER::to_string(value), value_type);
167 }
168 }
169 else if(tag == 1 || tag == 2 || tag == 6)
170 {
171 const std::string value = iso2local(BER::to_string(obj));
172
173 if(tag == 1) alt_name.add_attribute("RFC822", value);
174 if(tag == 2) alt_name.add_attribute("DNS", value);
175 if(tag == 6) alt_name.add_attribute("URI", value);
176 }
177
178 }
179 }
180
181}
182
183}

Archive Download this file

Branches

Tags

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