monotone

monotone Mtn Source Tree

Root/cryptopp/asn.cpp

1// asn.cpp - written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "asn.h"
5
6#include <iomanip>
7#include <time.h>
8
9NAMESPACE_BEGIN(CryptoPP)
10USING_NAMESPACE(std)
11
12/// DER Length
13unsigned int DERLengthEncode(BufferedTransformation &bt, unsigned int length)
14{
15unsigned int i=0;
16if (length <= 0x7f)
17{
18bt.Put(byte(length));
19i++;
20}
21else
22{
23bt.Put(byte(BytePrecision(length) | 0x80));
24i++;
25for (int j=BytePrecision(length); j; --j)
26{
27bt.Put(byte(length >> (j-1)*8));
28i++;
29}
30}
31return i;
32}
33
34bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length, bool &definiteLength)
35{
36byte b;
37
38if (!bt.Get(b))
39return false;
40
41if (!(b & 0x80))
42{
43definiteLength = true;
44length = b;
45}
46else
47{
48unsigned int lengthBytes = b & 0x7f;
49
50if (lengthBytes == 0)
51{
52definiteLength = false;
53return true;
54}
55
56definiteLength = true;
57length = 0;
58while (lengthBytes--)
59{
60if (length >> (8*(sizeof(length)-1)))
61BERDecodeError();// length about to overflow
62
63if (!bt.Get(b))
64return false;
65
66length = (length << 8) | b;
67}
68}
69return true;
70}
71
72bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length)
73{
74bool definiteLength;
75if (!BERLengthDecode(bt, length, definiteLength))
76BERDecodeError();
77return definiteLength;
78}
79
80void DEREncodeNull(BufferedTransformation &out)
81{
82out.Put(TAG_NULL);
83out.Put(0);
84}
85
86void BERDecodeNull(BufferedTransformation &in)
87{
88byte b;
89if (!in.Get(b) || b != TAG_NULL)
90BERDecodeError();
91unsigned int length;
92if (!BERLengthDecode(in, length) || length != 0)
93BERDecodeError();
94}
95
96/// ASN Strings
97unsigned int DEREncodeOctetString(BufferedTransformation &bt, const byte *str, unsigned int strLen)
98{
99bt.Put(OCTET_STRING);
100unsigned int lengthBytes = DERLengthEncode(bt, strLen);
101bt.Put(str, strLen);
102return 1+lengthBytes+strLen;
103}
104
105unsigned int DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str)
106{
107return DEREncodeOctetString(bt, str.begin(), str.size());
108}
109
110unsigned int BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
111{
112byte b;
113if (!bt.Get(b) || b != OCTET_STRING)
114BERDecodeError();
115
116unsigned int bc;
117if (!BERLengthDecode(bt, bc))
118BERDecodeError();
119
120str.resize(bc);
121if (bc != bt.Get(str, bc))
122BERDecodeError();
123return bc;
124}
125
126unsigned int BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str)
127{
128byte b;
129if (!bt.Get(b) || b != OCTET_STRING)
130BERDecodeError();
131
132unsigned int bc;
133if (!BERLengthDecode(bt, bc))
134BERDecodeError();
135
136bt.TransferTo(str, bc);
137return bc;
138}
139
140unsigned int DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag)
141{
142bt.Put(asnTag);
143unsigned int lengthBytes = DERLengthEncode(bt, str.size());
144bt.Put((const byte *)str.data(), str.size());
145return 1+lengthBytes+str.size();
146}
147
148unsigned int BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag)
149{
150byte b;
151if (!bt.Get(b) || b != asnTag)
152BERDecodeError();
153
154unsigned int bc;
155if (!BERLengthDecode(bt, bc))
156BERDecodeError();
157
158SecByteBlock temp(bc);
159if (bc != bt.Get(temp, bc))
160BERDecodeError();
161str.assign((char *)temp.begin(), bc);
162return bc;
163}
164
165/// ASN BitString
166unsigned int DEREncodeBitString(BufferedTransformation &bt, const byte *str, unsigned int strLen, unsigned int unusedBits)
167{
168bt.Put(BIT_STRING);
169unsigned int lengthBytes = DERLengthEncode(bt, strLen+1);
170bt.Put((byte)unusedBits);
171bt.Put(str, strLen);
172return 2+lengthBytes+strLen;
173}
174
175unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
176{
177byte b;
178if (!bt.Get(b) || b != BIT_STRING)
179BERDecodeError();
180
181unsigned int bc;
182if (!BERLengthDecode(bt, bc))
183BERDecodeError();
184
185byte unused;
186if (!bt.Get(unused))
187BERDecodeError();
188unusedBits = unused;
189str.resize(bc-1);
190if ((bc-1) != bt.Get(str, bc-1))
191BERDecodeError();
192return bc-1;
193}
194
195void OID::EncodeValue(BufferedTransformation &bt, unsigned long v)
196{
197for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
198bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
199bt.Put((byte)(v & 0x7f));
200}
201
202unsigned int OID::DecodeValue(BufferedTransformation &bt, unsigned long &v)
203{
204byte b;
205unsigned int i=0;
206v = 0;
207while (true)
208{
209if (!bt.Get(b))
210BERDecodeError();
211i++;
212v <<= 7;
213v += b & 0x7f;
214if (!(b & 0x80))
215return i;
216}
217}
218
219void OID::DEREncode(BufferedTransformation &bt) const
220{
221assert(m_values.size() >= 2);
222ByteQueue temp;
223temp.Put(byte(m_values[0] * 40 + m_values[1]));
224for (unsigned int i=2; i<m_values.size(); i++)
225EncodeValue(temp, m_values[i]);
226bt.Put(OBJECT_IDENTIFIER);
227DERLengthEncode(bt, temp.CurrentSize());
228temp.TransferTo(bt);
229}
230
231void OID::BERDecode(BufferedTransformation &bt)
232{
233byte b;
234if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
235BERDecodeError();
236
237unsigned int length;
238if (!BERLengthDecode(bt, length) || length < 1)
239BERDecodeError();
240
241if (!bt.Get(b))
242BERDecodeError();
243
244length--;
245m_values.resize(2);
246m_values[0] = b / 40;
247m_values[1] = b % 40;
248
249while (length > 0)
250{
251unsigned long v;
252unsigned int valueLen = DecodeValue(bt, v);
253if (valueLen > length)
254BERDecodeError();
255m_values.push_back(v);
256length -= valueLen;
257}
258}
259
260void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
261{
262OID oid(bt);
263if (*this != oid)
264BERDecodeError();
265}
266
267inline BufferedTransformation & EncodedObjectFilter::CurrentTarget()
268{
269if (m_flags & PUT_OBJECTS)
270return *AttachedTransformation();
271else
272return TheBitBucket();
273}
274
275void EncodedObjectFilter::Put(const byte *inString, unsigned int length)
276{
277if (m_nCurrentObject == m_nObjects)
278{
279AttachedTransformation()->Put(inString, length);
280return;
281}
282
283LazyPutter lazyPutter(m_queue, inString, length);
284
285while (m_queue.AnyRetrievable())
286{
287switch (m_state)
288{
289case IDENTIFIER:
290if (!m_queue.Get(m_id))
291return;
292m_queue.TransferTo(CurrentTarget(), 1);
293m_state = LENGTH;// fall through
294case LENGTH:
295{
296byte b;
297if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0)
298{
299m_queue.TransferTo(CurrentTarget(), 1);
300m_level--;
301m_state = IDENTIFIER;
302break;
303}
304ByteQueue::Walker walker(m_queue);
305bool definiteLength;
306if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength))
307return;
308m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition());
309if (!((m_id & CONSTRUCTED) || definiteLength))
310BERDecodeError();
311if (!definiteLength)
312{
313if (!(m_id & CONSTRUCTED))
314BERDecodeError();
315m_level++;
316m_state = IDENTIFIER;
317break;
318}
319m_state = BODY;// fall through
320}
321case BODY:
322m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining);
323
324if (m_lengthRemaining == 0)
325m_state = IDENTIFIER;
326}
327
328if (m_state == IDENTIFIER && m_level == 0)
329{
330// just finished processing a level 0 object
331++m_nCurrentObject;
332
333if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT)
334AttachedTransformation()->MessageEnd();
335
336if (m_nCurrentObject == m_nObjects)
337{
338if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS)
339AttachedTransformation()->MessageEnd();
340
341if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS)
342AttachedTransformation()->MessageSeriesEnd();
343
344m_queue.TransferAllTo(*AttachedTransformation());
345return;
346}
347}
348}
349}
350
351BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
352: m_inQueue(inQueue), m_finished(false)
353{
354byte b;
355if (!m_inQueue.Get(b) || b != asnTag)
356BERDecodeError();
357
358m_definiteLength = BERLengthDecode(m_inQueue, m_length);
359}
360
361BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
362: m_inQueue(inQueue), m_finished(false)
363{
364byte b;
365if (!m_inQueue.Get(b) || b != asnTag)
366BERDecodeError();
367
368m_definiteLength = BERLengthDecode(m_inQueue, m_length);
369if (!m_definiteLength && !(asnTag & CONSTRUCTED))
370BERDecodeError();// cannot be primitive have indefinite length
371}
372
373BERGeneralDecoder::~BERGeneralDecoder()
374{
375try// avoid throwing in constructor
376{
377if (!m_finished)
378MessageEnd();
379}
380catch (...)
381{
382}
383}
384
385bool BERGeneralDecoder::EndReached() const
386{
387if (m_definiteLength)
388return m_length == 0;
389else
390{// check end-of-content octets
391word16 i;
392return (m_inQueue.PeekWord16(i)==2 && i==0);
393}
394}
395
396byte BERGeneralDecoder::PeekByte() const
397{
398byte b;
399if (!Peek(b))
400BERDecodeError();
401return b;
402}
403
404void BERGeneralDecoder::CheckByte(byte check)
405{
406byte b;
407if (!Get(b) || b != check)
408BERDecodeError();
409}
410
411void BERGeneralDecoder::MessageEnd()
412{
413m_finished = true;
414if (m_definiteLength)
415{
416if (m_length != 0)
417BERDecodeError();
418}
419else
420{// remove end-of-content octets
421word16 i;
422if (m_inQueue.GetWord16(i) != 2 || i != 0)
423BERDecodeError();
424}
425}
426
427unsigned int BERGeneralDecoder::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
428{
429if (m_definiteLength && transferBytes > m_length)
430transferBytes = m_length;
431unsigned int blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking);
432ReduceLength(transferBytes);
433return blockedBytes;
434}
435
436unsigned int BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
437{
438if (m_definiteLength)
439end = STDMIN((unsigned long)m_length, end);
440return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking);
441}
442
443unsigned int BERGeneralDecoder::ReduceLength(unsigned int delta)
444{
445if (m_definiteLength)
446{
447if (m_length < delta)
448BERDecodeError();
449m_length -= delta;
450}
451return delta;
452}
453
454DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
455: m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
456{
457}
458
459DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
460: m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
461{
462}
463
464DERGeneralEncoder::~DERGeneralEncoder()
465{
466try// avoid throwing in constructor
467{
468if (!m_finished)
469MessageEnd();
470}
471catch (...)
472{
473}
474}
475
476void DERGeneralEncoder::MessageEnd()
477{
478m_finished = true;
479unsigned int length = (unsigned int)CurrentSize();
480m_outQueue.Put(m_asnTag);
481DERLengthEncode(m_outQueue, length);
482TransferTo(m_outQueue);
483}
484
485// *************************************************************
486
487void X509PublicKey::BERDecode(BufferedTransformation &bt)
488{
489BERSequenceDecoder subjectPublicKeyInfo(bt);
490BERSequenceDecoder algorithm(subjectPublicKeyInfo);
491GetAlgorithmID().BERDecodeAndCheck(algorithm);
492bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
493algorithm.MessageEnd();
494
495BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
496subjectPublicKey.CheckByte(0);// unused bits
497BERDecodeKey2(subjectPublicKey, parametersPresent, subjectPublicKey.RemainingLength());
498subjectPublicKey.MessageEnd();
499subjectPublicKeyInfo.MessageEnd();
500}
501
502void X509PublicKey::DEREncode(BufferedTransformation &bt) const
503{
504DERSequenceEncoder subjectPublicKeyInfo(bt);
505
506DERSequenceEncoder algorithm(subjectPublicKeyInfo);
507GetAlgorithmID().DEREncode(algorithm);
508DEREncodeAlgorithmParameters(algorithm);
509algorithm.MessageEnd();
510
511DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
512subjectPublicKey.Put(0);// unused bits
513DEREncodeKey(subjectPublicKey);
514subjectPublicKey.MessageEnd();
515
516subjectPublicKeyInfo.MessageEnd();
517}
518
519void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt)
520{
521BERSequenceDecoder privateKeyInfo(bt);
522word32 version;
523BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0);// check version
524
525BERSequenceDecoder algorithm(privateKeyInfo);
526GetAlgorithmID().BERDecodeAndCheck(algorithm);
527bool parametersPresent = BERDecodeAlgorithmParameters(algorithm);
528algorithm.MessageEnd();
529
530BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
531BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.RemainingLength());
532octetString.MessageEnd();
533
534BERDecodeOptionalAttributes(privateKeyInfo);
535privateKeyInfo.MessageEnd();
536}
537
538void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const
539{
540DERSequenceEncoder privateKeyInfo(bt);
541DEREncodeUnsigned<word32>(privateKeyInfo, 0);// version
542
543DERSequenceEncoder algorithm(privateKeyInfo);
544GetAlgorithmID().DEREncode(algorithm);
545DEREncodeAlgorithmParameters(algorithm);
546algorithm.MessageEnd();
547
548DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
549DEREncodeKey(octetString);
550octetString.MessageEnd();
551
552DEREncodeOptionalAttributes(privateKeyInfo);
553privateKeyInfo.MessageEnd();
554}
555
556NAMESPACE_END

Archive Download this file

Branches

Tags

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