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