monotone

monotone Mtn Source Tree

Root/botan/der_enc.cpp

1/*************************************************
2* DER Encoder Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/der_enc.h>
7#include <botan/asn1_int.h>
8#include <botan/bigint.h>
9#include <botan/bit_ops.h>
10#include <botan/parsing.h>
11#include <algorithm>
12
13namespace Botan {
14
15namespace {
16
17/*************************************************
18* DER encode an ASN.1 type tag *
19*************************************************/
20SecureVector<byte> encode_tag(ASN1_Tag type_tag, ASN1_Tag class_tag)
21 {
22 if((class_tag | 0xE0) != 0xE0)
23 throw Encoding_Error("DER_Encoder: Invalid class tag " +
24 to_string(class_tag));
25
26 SecureVector<byte> encoded_tag;
27 if(type_tag <= 30)
28 encoded_tag.append((byte)(type_tag | class_tag));
29 else
30 {
31 u32bit blocks = high_bit(type_tag) + 6;
32 blocks = (blocks - (blocks % 7)) / 7;
33
34 encoded_tag.append(class_tag | 0x1F);
35 for(u32bit k = 0; k != blocks - 1; ++k)
36 encoded_tag.append(0x80 | ((type_tag >> 7*(blocks-k-1)) & 0x7F));
37 encoded_tag.append(type_tag & 0x7F);
38 }
39
40 return encoded_tag;
41 }
42
43/*************************************************
44* DER encode an ASN.1 length field *
45*************************************************/
46SecureVector<byte> encode_length(u32bit length)
47 {
48 SecureVector<byte> encoded_length;
49 if(length <= 127)
50 encoded_length.append((byte)length);
51 else
52 {
53 const u32bit top_byte = significant_bytes(length);
54 encoded_length.append((byte)(0x80 | top_byte));
55 for(u32bit j = 4-top_byte; j != 4; ++j)
56 encoded_length.append(get_byte(j, length));
57 }
58 return encoded_length;
59 }
60
61}
62
63/*************************************************
64* Return the encoded SEQUENCE/SET *
65*************************************************/
66SecureVector<byte> DER_Encoder::DER_Sequence::get_contents()
67 {
68 const ASN1_Tag real_class_tag = ASN1_Tag(class_tag | CONSTRUCTED);
69
70 SecureVector<byte> encoded_tag = encode_tag(type_tag, real_class_tag);
71
72 if(type_tag == SET)
73 {
74 std::sort(set_contents.begin(), set_contents.end());
75 for(u32bit j = 0; j != set_contents.size(); ++j)
76 contents.append(set_contents[j]);
77 set_contents.clear();
78 }
79
80 SecureVector<byte> encoded_length = encode_length(contents.size());
81
82 SecureVector<byte> retval;
83 retval.append(encoded_tag);
84 retval.append(encoded_length);
85 retval.append(contents);
86 contents.destroy();
87 return retval;
88 }
89
90/*************************************************
91* Add an encoded value to the SEQUENCE/SET *
92*************************************************/
93void DER_Encoder::DER_Sequence::add_bytes(const byte data[], u32bit length)
94 {
95 if(type_tag == SET)
96 set_contents.push_back(SecureVector<byte>(data, length));
97 else
98 contents.append(data, length);
99 }
100
101/*************************************************
102* Return the type and class taggings *
103*************************************************/
104ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const
105 {
106 return ASN1_Tag(type_tag | class_tag);
107 }
108
109/*************************************************
110* DER_Sequence Constructor *
111*************************************************/
112DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) :
113 type_tag(t1), class_tag(t2)
114 {
115 }
116
117/*************************************************
118* Return the encoded contents *
119*************************************************/
120SecureVector<byte> DER_Encoder::get_contents()
121 {
122 if(subsequences.size() != 0)
123 throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
124
125 SecureVector<byte> retval;
126 retval = contents;
127 contents.destroy();
128 return retval;
129 }
130
131/*************************************************
132* Start a new ASN.1 SEQUENCE/SET/EXPLICIT *
133*************************************************/
134DER_Encoder& DER_Encoder::start_cons(ASN1_Tag type_tag,
135 ASN1_Tag class_tag)
136 {
137 subsequences.push_back(DER_Sequence(type_tag, class_tag));
138 return (*this);
139 }
140
141/*************************************************
142* Finish the current ASN.1 SEQUENCE/SET/EXPLICIT *
143*************************************************/
144DER_Encoder& DER_Encoder::end_cons()
145 {
146 if(subsequences.empty())
147 throw Invalid_State("DER_Encoder::end_cons: No such sequence");
148
149 SecureVector<byte> seq = subsequences[subsequences.size()-1].get_contents();
150 subsequences.pop_back();
151 raw_bytes(seq);
152 return (*this);
153 }
154
155/*************************************************
156* Start a new ASN.1 EXPLICIT encoding *
157*************************************************/
158DER_Encoder& DER_Encoder::start_explicit(u16bit type_no)
159 {
160 ASN1_Tag type_tag = (ASN1_Tag)type_no;
161
162 if(type_tag == SET)
163 throw Internal_Error("DER_Encoder.start_explicit(SET); cannot perform");
164
165 return start_cons(type_tag, CONTEXT_SPECIFIC);
166 }
167
168/*************************************************
169* Finish the current ASN.1 EXPLICIT encoding *
170*************************************************/
171DER_Encoder& DER_Encoder::end_explicit()
172 {
173 return end_cons();
174 }
175
176/*************************************************
177* Write raw bytes into the stream *
178*************************************************/
179DER_Encoder& DER_Encoder::raw_bytes(const MemoryRegion<byte>& val)
180 {
181 return raw_bytes(val.begin(), val.size());
182 }
183
184/*************************************************
185* Write raw bytes into the stream *
186*************************************************/
187DER_Encoder& DER_Encoder::raw_bytes(const byte bytes[], u32bit length)
188 {
189 if(subsequences.size())
190 subsequences[subsequences.size()-1].add_bytes(bytes, length);
191 else
192 contents.append(bytes, length);
193
194 return (*this);
195 }
196
197/*************************************************
198* Encode a NULL object *
199*************************************************/
200DER_Encoder& DER_Encoder::encode_null()
201 {
202 return add_object(NULL_TAG, UNIVERSAL, 0, 0);
203 }
204
205/*************************************************
206* DER encode a BOOLEAN *
207*************************************************/
208DER_Encoder& DER_Encoder::encode(bool is_true)
209 {
210 return encode(is_true, BOOLEAN, UNIVERSAL);
211 }
212
213/*************************************************
214* DER encode a small INTEGER *
215*************************************************/
216DER_Encoder& DER_Encoder::encode(u32bit n)
217 {
218 return encode(BigInt(n), INTEGER, UNIVERSAL);
219 }
220
221/*************************************************
222* DER encode a small INTEGER *
223*************************************************/
224DER_Encoder& DER_Encoder::encode(const BigInt& n)
225 {
226 return encode(n, INTEGER, UNIVERSAL);
227 }
228
229/*************************************************
230* DER encode an OCTET STRING or BIT STRING *
231*************************************************/
232DER_Encoder& DER_Encoder::encode(const MemoryRegion<byte>& bytes,
233 ASN1_Tag real_type)
234 {
235 return encode(bytes.begin(), bytes.size(),
236 real_type, real_type, UNIVERSAL);
237 }
238
239/*************************************************
240* Encode this object *
241*************************************************/
242DER_Encoder& DER_Encoder::encode(const byte bytes[], u32bit length,
243 ASN1_Tag real_type)
244 {
245 return encode(bytes, length, real_type, real_type, UNIVERSAL);
246 }
247
248/*************************************************
249* DER encode a BOOLEAN *
250*************************************************/
251DER_Encoder& DER_Encoder::encode(bool is_true,
252 ASN1_Tag type_tag, ASN1_Tag class_tag)
253 {
254 byte val = is_true ? 0xFF : 0x00;
255 return add_object(type_tag, class_tag, &val, 1);
256 }
257
258/*************************************************
259* DER encode a small INTEGER *
260*************************************************/
261DER_Encoder& DER_Encoder::encode(u32bit n,
262 ASN1_Tag type_tag, ASN1_Tag class_tag)
263 {
264 return encode(BigInt(n), type_tag, class_tag);
265 }
266
267/*************************************************
268* DER encode an INTEGER *
269*************************************************/
270DER_Encoder& DER_Encoder::encode(const BigInt& n,
271 ASN1_Tag type_tag, ASN1_Tag class_tag)
272 {
273 if(n == 0)
274 return add_object(type_tag, class_tag, 0);
275
276 bool extra_zero = (n.bits() % 8 == 0);
277 SecureVector<byte> contents(extra_zero + n.bytes());
278 BigInt::encode(contents.begin() + extra_zero, n);
279 if(n < 0)
280 {
281 for(u32bit j = 0; j != contents.size(); ++j)
282 contents[j] = ~contents[j];
283 for(u32bit j = contents.size(); j > 0; --j)
284 if(++contents[j-1])
285 break;
286 }
287
288 return add_object(type_tag, class_tag, contents);
289 }
290
291/*************************************************
292* DER encode an OCTET STRING or BIT STRING *
293*************************************************/
294DER_Encoder& DER_Encoder::encode(const MemoryRegion<byte>& bytes,
295 ASN1_Tag real_type,
296 ASN1_Tag type_tag, ASN1_Tag class_tag)
297 {
298 return encode(bytes.begin(), bytes.size(),
299 real_type, type_tag, class_tag);
300 }
301
302/*************************************************
303* DER encode an OCTET STRING or BIT STRING *
304*************************************************/
305DER_Encoder& DER_Encoder::encode(const byte bytes[], u32bit length,
306 ASN1_Tag real_type,
307 ASN1_Tag type_tag, ASN1_Tag class_tag)
308 {
309 if(real_type != OCTET_STRING && real_type != BIT_STRING)
310 throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string");
311
312 if(real_type == BIT_STRING)
313 {
314 SecureVector<byte> encoded;
315 encoded.append(0);
316 encoded.append(bytes, length);
317 return add_object(type_tag, class_tag, encoded);
318 }
319 else
320 return add_object(type_tag, class_tag, bytes, length);
321 }
322
323/*************************************************
324* Conditionally write some values to the stream *
325*************************************************/
326DER_Encoder& DER_Encoder::encode_if(bool cond, DER_Encoder& codec)
327 {
328 if(cond)
329 return raw_bytes(codec.get_contents());
330 return (*this);
331 }
332
333/*************************************************
334* Request for an object to encode itself *
335*************************************************/
336DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj)
337 {
338 obj.encode_into(*this);
339 return (*this);
340 }
341
342/*************************************************
343* Write the encoding of the byte(s) *
344*************************************************/
345DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
346 const byte rep[], u32bit length)
347 {
348 SecureVector<byte> encoded_tag = encode_tag(type_tag, class_tag);
349 SecureVector<byte> encoded_length = encode_length(length);
350
351 SecureVector<byte> buffer;
352 buffer.append(encoded_tag);
353 buffer.append(encoded_length);
354 buffer.append(rep, length);
355
356 return raw_bytes(buffer);
357 }
358
359/*************************************************
360* Write the encoding of the byte(s) *
361*************************************************/
362DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
363 const MemoryRegion<byte>& rep_buf)
364 {
365 const byte* rep = rep_buf.begin();
366 const u32bit rep_len = rep_buf.size();
367 return add_object(type_tag, class_tag, rep, rep_len);
368 }
369
370/*************************************************
371* Write the encoding of the byte(s) *
372*************************************************/
373DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
374 const std::string& rep_str)
375 {
376 const byte* rep = (const byte*)rep_str.c_str();
377 const u32bit rep_len = rep_str.size();
378 return add_object(type_tag, class_tag, rep, rep_len);
379 }
380
381/*************************************************
382* Write the encoding of the byte *
383*************************************************/
384DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag,
385 ASN1_Tag class_tag, byte rep)
386 {
387 return add_object(type_tag, class_tag, &rep, 1);
388 }
389
390}

Archive Download this file

Branches

Tags

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