monotone

monotone Mtn Source Tree

Root/botan/asn1_oid.cpp

1/*************************************************
2* ASN.1 OID Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/asn1.h>
7#include <botan/bit_ops.h>
8#include <botan/parsing.h>
9
10namespace Botan {
11
12/*************************************************
13* ASN.1 OID Constructor *
14*************************************************/
15OID::OID(const std::string& oid_str)
16 {
17 if(oid_str != "")
18 {
19 id = parse_asn1_oid(oid_str);
20 if(id.size() < 2 || id[0] > 2)
21 throw Invalid_OID(oid_str);
22 if((id[0] == 0 || id[0] == 1) && id[1] > 39)
23 throw Invalid_OID(oid_str);
24 }
25 }
26
27/*************************************************
28* Clear the current OID *
29*************************************************/
30void OID::clear()
31 {
32 id.clear();
33 }
34
35/*************************************************
36* Return this OID as a string *
37*************************************************/
38std::string OID::as_string() const
39 {
40 std::string oid_str;
41 for(u32bit j = 0; j != id.size(); j++)
42 {
43 oid_str += to_string(id[j]);
44 if(j != id.size() - 1)
45 oid_str += '.';
46 }
47 return oid_str;
48 }
49
50/*************************************************
51* OID equality comparison *
52*************************************************/
53bool OID::operator==(const OID& oid) const
54 {
55 if(id.size() != oid.id.size())
56 return false;
57 for(u32bit j = 0; j != id.size(); j++)
58 if(id[j] != oid.id[j])
59 return false;
60 return true;
61 }
62
63/*************************************************
64* Append another component to the OID *
65*************************************************/
66OID& OID::operator+=(u32bit component)
67 {
68 id.push_back(component);
69 return (*this);
70 }
71
72/*************************************************
73* Append another component to the OID *
74*************************************************/
75OID operator+(const OID& oid, u32bit component)
76 {
77 OID new_oid(oid);
78 new_oid += component;
79 return new_oid;
80 }
81
82/*************************************************
83* OID inequality comparison *
84*************************************************/
85bool operator!=(const OID& a, const OID& b)
86 {
87 return !(a == b);
88 }
89
90/*************************************************
91* Compare two OIDs *
92*************************************************/
93bool operator<(const OID& a, const OID& b)
94 {
95 std::vector<u32bit> oid1 = a.get_id();
96 std::vector<u32bit> oid2 = b.get_id();
97
98 if(oid1.size() < oid2.size())
99 return true;
100 if(oid1.size() > oid2.size())
101 return false;
102 for(u32bit j = 0; j != oid1.size(); j++)
103 {
104 if(oid1[j] < oid2[j])
105 return true;
106 if(oid1[j] > oid2[j])
107 return false;
108 }
109 return false;
110 }
111
112namespace DER {
113
114/*************************************************
115* DER encode an OBJECT IDENTIFIER *
116*************************************************/
117void encode(DER_Encoder& encoder, const OID& oid_obj)
118 {
119 std::vector<u32bit> oid = oid_obj.get_id();
120
121 if(oid.size() < 2)
122 throw Invalid_Argument("DER::encode(OID): OID is invalid");
123
124 MemoryVector<byte> encoding;
125 encoding.append(40 * oid[0] + oid[1]);
126
127 for(u32bit j = 2; j != oid.size(); j++)
128 {
129 if(oid[j] == 0)
130 encoding.append(0);
131 else
132 {
133 u32bit blocks = high_bit(oid[j]) + 6;
134 blocks = (blocks - (blocks % 7)) / 7;
135
136 for(u32bit k = 0; k != blocks - 1; k++)
137 encoding.append(0x80 | ((oid[j] >> 7*(blocks-k-1)) & 0x7F));
138 encoding.append(oid[j] & 0x7F);
139 }
140 }
141 encoder.add_object(OBJECT_ID, UNIVERSAL, encoding);
142 }
143
144}
145
146namespace BER {
147
148/*************************************************
149* Decode a BER encoded OBJECT IDENTIFIER *
150*************************************************/
151void decode(BER_Decoder& decoder, OID& oid)
152 {
153 BER_Object obj = decoder.get_next_object();
154 if(obj.type_tag != OBJECT_ID || obj.class_tag != UNIVERSAL)
155 throw BER_Bad_Tag("Error decoding OID, unknown tag",
156 obj.type_tag, obj.class_tag);
157 if(obj.value.size() < 2)
158 throw BER_Decoding_Error("OID encoding is too short");
159
160 oid.clear();
161 oid += (obj.value[0] / 40);
162 oid += (obj.value[0] % 40);
163
164 u32bit j = 0;
165 while(j != obj.value.size() - 1)
166 {
167 u32bit component = 0;
168 while(j != obj.value.size() - 1)
169 {
170 j++;
171 component = (component << 7) + (obj.value[j] & 0x7F);
172 if(!(obj.value[j] & 0x80))
173 break;
174 }
175 oid += component;
176 }
177 }
178
179}
180
181}

Archive Download this file

Branches

Tags

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