monotone

monotone Mtn Source Tree

Root/botan/asn1_oid.cpp

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

Archive Download this file

Branches

Tags

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