monotone

monotone Mtn Source Tree

Root/cryptopp/asn.h

1#ifndef CRYPTOPP_ASN_H
2#define CRYPTOPP_ASN_H
3
4#include "filters.h"
5#include "queue.h"
6#include <vector>
7
8NAMESPACE_BEGIN(CryptoPP)
9
10// these tags and flags are not complete
11enum ASNTag
12{
13BOOLEAN = 0x01,
14INTEGER = 0x02,
15BIT_STRING= 0x03,
16OCTET_STRING= 0x04,
17TAG_NULL= 0x05,
18OBJECT_IDENTIFIER= 0x06,
19OBJECT_DESCRIPTOR= 0x07,
20EXTERNAL= 0x08,
21REAL= 0x09,
22ENUMERATED= 0x0a,
23UTF8_STRING= 0x0c,
24SEQUENCE= 0x10,
25SET = 0x11,
26NUMERIC_STRING= 0x12,
27PRINTABLE_STRING = 0x13,
28T61_STRING= 0x14,
29VIDEOTEXT_STRING = 0x15,
30IA5_STRING= 0x16,
31UTC_TIME = 0x17,
32GENERALIZED_TIME = 0x18,
33GRAPHIC_STRING= 0x19,
34VISIBLE_STRING= 0x1a,
35GENERAL_STRING= 0x1b
36};
37
38enum ASNIdFlag
39{
40UNIVERSAL= 0x00,
41//DATA= 0x01,
42//HEADER= 0x02,
43CONSTRUCTED = 0x20,
44APPLICATION = 0x40,
45CONTEXT_SPECIFIC= 0x80,
46PRIVATE = 0xc0
47};
48
49inline void BERDecodeError() {throw BERDecodeErr();}
50
51class UnknownOID : public BERDecodeErr
52{
53public:
54UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {}
55UnknownOID(const char *err) : BERDecodeErr(err) {}
56};
57
58// unsigned int DERLengthEncode(unsigned int length, byte *output=0);
59unsigned int DERLengthEncode(BufferedTransformation &out, unsigned int length);
60// returns false if indefinite length
61bool BERLengthDecode(BufferedTransformation &in, unsigned int &length);
62
63void DEREncodeNull(BufferedTransformation &out);
64void BERDecodeNull(BufferedTransformation &in);
65
66unsigned int DEREncodeOctetString(BufferedTransformation &out, const byte *str, unsigned int strLen);
67unsigned int DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str);
68unsigned int BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str);
69unsigned int BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str);
70
71// for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
72unsigned int DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag);
73unsigned int BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag);
74
75unsigned int DEREncodeBitString(BufferedTransformation &out, const byte *str, unsigned int strLen, unsigned int unusedBits=0);
76unsigned int BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits);
77
78//! Object Identifier
79class OID
80{
81public:
82OID() {}
83OID(unsigned long v) : m_values(1, v) {}
84OID(BufferedTransformation &bt) {BERDecode(bt);}
85
86inline OID & operator+=(unsigned long rhs) {m_values.push_back(rhs); return *this;}
87
88void DEREncode(BufferedTransformation &bt) const;
89void BERDecode(BufferedTransformation &bt);
90
91// throw BERDecodeErr() if decoded value doesn't equal this OID
92void BERDecodeAndCheck(BufferedTransformation &bt) const;
93
94std::vector<unsigned long> m_values;
95
96private:
97static void EncodeValue(BufferedTransformation &bt, unsigned long v);
98static unsigned int DecodeValue(BufferedTransformation &bt, unsigned long &v);
99};
100
101class EncodedObjectFilter : public Filter
102{
103public:
104enum Flag {PUT_OBJECTS=1, PUT_MESSANGE_END_AFTER_EACH_OBJECT=2, PUT_MESSANGE_END_AFTER_ALL_OBJECTS=4, PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS=8};
105EncodedObjectFilter(BufferedTransformation *attachment = NULL, unsigned int nObjects = 1, word32 flags = 0);
106
107void Put(const byte *inString, unsigned int length);
108
109unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;}
110unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];}
111
112private:
113BufferedTransformation & CurrentTarget();
114
115word32 m_flags;
116unsigned int m_nObjects, m_nCurrentObject, m_level;
117std::vector<unsigned int> m_positions;
118ByteQueue m_queue;
119enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state;
120byte m_id;
121unsigned int m_lengthRemaining;
122};
123
124//! BER General Decoder
125class BERGeneralDecoder : public Store
126{
127public:
128explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
129explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
130~BERGeneralDecoder();
131
132bool IsDefiniteLength() const {return m_definiteLength;}
133unsigned int RemainingLength() const {assert(m_definiteLength); return m_length;}
134bool EndReached() const;
135byte PeekByte() const;
136void CheckByte(byte b);
137
138unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
139unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
140
141// call this to denote end of sequence
142void MessageEnd();
143
144protected:
145BufferedTransformation &m_inQueue;
146bool m_finished, m_definiteLength;
147unsigned int m_length;
148
149private:
150void StoreInitialize(const NameValuePairs &parameters) {assert(false);}
151unsigned int ReduceLength(unsigned int delta);
152};
153
154//! DER General Encoder
155class DERGeneralEncoder : public ByteQueue
156{
157public:
158explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
159explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
160~DERGeneralEncoder();
161
162// call this to denote end of sequence
163void MessageEnd();
164
165private:
166BufferedTransformation &m_outQueue;
167bool m_finished;
168
169byte m_asnTag;
170};
171
172//! BER Sequence Decoder
173class BERSequenceDecoder : public BERGeneralDecoder
174{
175public:
176explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
177: BERGeneralDecoder(inQueue, asnTag) {}
178explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
179: BERGeneralDecoder(inQueue, asnTag) {}
180};
181
182//! DER Sequence Encoder
183class DERSequenceEncoder : public DERGeneralEncoder
184{
185public:
186explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
187: DERGeneralEncoder(outQueue, asnTag) {}
188explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
189: DERGeneralEncoder(outQueue, asnTag) {}
190};
191
192//! BER Set Decoder
193class BERSetDecoder : public BERGeneralDecoder
194{
195public:
196explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED)
197: BERGeneralDecoder(inQueue, asnTag) {}
198explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED)
199: BERGeneralDecoder(inQueue, asnTag) {}
200};
201
202//! DER Set Encoder
203class DERSetEncoder : public DERGeneralEncoder
204{
205public:
206explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED)
207: DERGeneralEncoder(outQueue, asnTag) {}
208explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED)
209: DERGeneralEncoder(outQueue, asnTag) {}
210};
211
212template <class T>
213class ASNOptional : public member_ptr<T>
214{
215public:
216void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED)
217{
218byte b;
219if (seqDecoder.Peek(b) && (b & mask) == tag)
220reset(new T(seqDecoder));
221}
222void DEREncode(BufferedTransformation &out)
223{
224if (get() != NULL)
225get()->DEREncode(out);
226}
227};
228
229//! .
230class ASN1Key : public ASN1CryptoMaterial
231{
232public:
233virtual OID GetAlgorithmID() const =0;
234virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
235{BERDecodeNull(bt); return false;}
236virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
237{DEREncodeNull(bt); return false;}// see RFC 2459, section 7.3.1
238// one of the following two should be overriden
239//! decode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header
240virtual void BERDecodeKey(BufferedTransformation &bt) {assert(false);}
241virtual void BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size)
242{BERDecodeKey(bt);}
243//! encode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header
244virtual void DEREncodeKey(BufferedTransformation &bt) const =0;
245};
246
247//! encodes/decodes subjectPublicKeyInfo
248class X509PublicKey : virtual public ASN1Key, public PublicKey
249{
250public:
251void BERDecode(BufferedTransformation &bt);
252void DEREncode(BufferedTransformation &bt) const;
253};
254
255//! encodes/decodes privateKeyInfo
256class PKCS8PrivateKey : virtual public ASN1Key, public PrivateKey
257{
258public:
259void BERDecode(BufferedTransformation &bt);
260void DEREncode(BufferedTransformation &bt) const;
261
262virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt)
263{}// TODO: skip optional attributes if present
264virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const
265{}
266};
267
268// ********************************************************
269
270//! DER Encode Unsigned
271/*! for INTEGER, BOOLEAN, and ENUM */
272template <class T>
273unsigned int DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
274{
275byte buf[sizeof(w)+1];
276unsigned int bc;
277if (asnTag == BOOLEAN)
278{
279buf[sizeof(w)] = w ? 0xff : 0;
280bc = 1;
281}
282else
283{
284buf[0] = 0;
285for (unsigned int i=0; i<sizeof(w); i++)
286buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
287bc = sizeof(w);
288while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
289--bc;
290if (buf[sizeof(w)+1-bc] & 0x80)
291++bc;
292}
293out.Put(asnTag);
294unsigned int lengthBytes = DERLengthEncode(out, bc);
295out.Put(buf+sizeof(w)+1-bc, bc);
296return 1+lengthBytes+bc;
297}
298
299//! BER Decode Unsigned
300// VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro
301// CW41 workaround: std::numeric_limits<T>::max causes a template error
302template <class T>
303void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
304 T minValue = 0, T maxValue = 0xffffffff)
305{
306byte b;
307if (!in.Get(b) || b != asnTag)
308BERDecodeError();
309
310unsigned int bc;
311BERLengthDecode(in, bc);
312
313SecByteBlock buf(bc);
314
315if (bc != in.Get(buf, bc))
316BERDecodeError();
317
318const byte *ptr = buf;
319while (bc > sizeof(w) && *ptr == 0)
320{
321bc--;
322ptr++;
323}
324if (bc > sizeof(w))
325BERDecodeError();
326
327w = 0;
328for (unsigned int i=0; i<bc; i++)
329w = (w << 8) | ptr[i];
330
331if (w < minValue || w > maxValue)
332BERDecodeError();
333}
334
335inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
336{return lhs.m_values == rhs.m_values;}
337inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
338{return lhs.m_values != rhs.m_values;}
339inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
340{return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
341inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
342{return ::CryptoPP::OID(lhs)+=rhs;}
343
344NAMESPACE_END
345
346#endif

Archive Download this file

Branches

Tags

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