Crypto++
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 
8 NAMESPACE_BEGIN(CryptoPP)
9 
10 // these tags and flags are not complete
11 enum ASNTag
12 {
13  BOOLEAN = 0x01,
14  INTEGER = 0x02,
15  BIT_STRING = 0x03,
16  OCTET_STRING = 0x04,
17  TAG_NULL = 0x05,
18  OBJECT_IDENTIFIER = 0x06,
19  OBJECT_DESCRIPTOR = 0x07,
20  EXTERNAL = 0x08,
21  REAL = 0x09,
22  ENUMERATED = 0x0a,
23  UTF8_STRING = 0x0c,
24  SEQUENCE = 0x10,
25  SET = 0x11,
26  NUMERIC_STRING = 0x12,
27  PRINTABLE_STRING = 0x13,
28  T61_STRING = 0x14,
29  VIDEOTEXT_STRING = 0x15,
30  IA5_STRING = 0x16,
31  UTC_TIME = 0x17,
32  GENERALIZED_TIME = 0x18,
33  GRAPHIC_STRING = 0x19,
34  VISIBLE_STRING = 0x1a,
35  GENERAL_STRING = 0x1b
36 };
37 
38 enum ASNIdFlag
39 {
40  UNIVERSAL = 0x00,
41 // DATA = 0x01,
42 // HEADER = 0x02,
43  CONSTRUCTED = 0x20,
44  APPLICATION = 0x40,
45  CONTEXT_SPECIFIC = 0x80,
46  PRIVATE = 0xc0
47 };
48 
49 inline void BERDecodeError() {throw BERDecodeErr();}
50 
51 class CRYPTOPP_DLL UnknownOID : public BERDecodeErr
52 {
53 public:
54  UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {}
55  UnknownOID(const char *err) : BERDecodeErr(err) {}
56 };
57 
58 // unsigned int DERLengthEncode(unsigned int length, byte *output=0);
59 CRYPTOPP_DLL size_t CRYPTOPP_API DERLengthEncode(BufferedTransformation &out, lword length);
60 // returns false if indefinite length
61 CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &in, size_t &length);
62 
63 CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &out);
64 CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &in);
65 
66 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const byte *str, size_t strLen);
67 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str);
68 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str);
69 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str);
70 
71 // for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
72 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag);
73 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag);
74 
75 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeBitString(BufferedTransformation &out, const byte *str, size_t strLen, unsigned int unusedBits=0);
76 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits);
77 
78 // BER decode from source and DER reencode into dest
79 CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &source, BufferedTransformation &dest);
80 
81 //! Object Identifier
82 class CRYPTOPP_DLL OID
83 {
84 public:
85  OID() {}
86  OID(word32 v) : m_values(1, v) {}
87  OID(BufferedTransformation &bt) {BERDecode(bt);}
88 
89  inline OID & operator+=(word32 rhs) {m_values.push_back(rhs); return *this;}
90 
91  void DEREncode(BufferedTransformation &bt) const;
92  void BERDecode(BufferedTransformation &bt);
93 
94  // throw BERDecodeErr() if decoded value doesn't equal this OID
95  void BERDecodeAndCheck(BufferedTransformation &bt) const;
96 
97  std::vector<word32> m_values;
98 
99 private:
100  static void EncodeValue(BufferedTransformation &bt, word32 v);
101  static size_t DecodeValue(BufferedTransformation &bt, word32 &v);
102 };
103 
105 {
106 public:
107  enum 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};
108  EncodedObjectFilter(BufferedTransformation *attachment = NULL, unsigned int nObjects = 1, word32 flags = 0);
109 
110  void Put(const byte *inString, size_t length);
111 
112  unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;}
113  unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];}
114 
115 private:
116  BufferedTransformation & CurrentTarget();
117 
118  word32 m_flags;
119  unsigned int m_nObjects, m_nCurrentObject, m_level;
120  std::vector<unsigned int> m_positions;
121  ByteQueue m_queue;
122  enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state;
123  byte m_id;
124  lword m_lengthRemaining;
125 };
126 
127 //! BER General Decoder
128 class CRYPTOPP_DLL BERGeneralDecoder : public Store
129 {
130 public:
131  explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
132  explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
134 
135  bool IsDefiniteLength() const {return m_definiteLength;}
136  lword RemainingLength() const {assert(m_definiteLength); return m_length;}
137  bool EndReached() const;
138  byte PeekByte() const;
139  void CheckByte(byte b);
140 
141  size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
142  size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
143 
144  // call this to denote end of sequence
145  void MessageEnd();
146 
147 protected:
148  BufferedTransformation &m_inQueue;
149  bool m_finished, m_definiteLength;
150  lword m_length;
151 
152 private:
153  void Init(byte asnTag);
154  void StoreInitialize(const NameValuePairs &parameters) {assert(false);}
155  lword ReduceLength(lword delta);
156 };
157 
158 //! DER General Encoder
159 class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
160 {
161 public:
162  explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
163  explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
165 
166  // call this to denote end of sequence
167  void MessageEnd();
168 
169 private:
170  BufferedTransformation &m_outQueue;
171  bool m_finished;
172 
173  byte m_asnTag;
174 };
175 
176 //! BER Sequence Decoder
177 class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
178 {
179 public:
180  explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
181  : BERGeneralDecoder(inQueue, asnTag) {}
182  explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
183  : BERGeneralDecoder(inQueue, asnTag) {}
184 };
185 
186 //! DER Sequence Encoder
187 class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
188 {
189 public:
190  explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
191  : DERGeneralEncoder(outQueue, asnTag) {}
192  explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
193  : DERGeneralEncoder(outQueue, asnTag) {}
194 };
195 
196 //! BER Set Decoder
197 class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
198 {
199 public:
200  explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED)
201  : BERGeneralDecoder(inQueue, asnTag) {}
202  explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED)
203  : BERGeneralDecoder(inQueue, asnTag) {}
204 };
205 
206 //! DER Set Encoder
207 class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
208 {
209 public:
210  explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED)
211  : DERGeneralEncoder(outQueue, asnTag) {}
212  explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED)
213  : DERGeneralEncoder(outQueue, asnTag) {}
214 };
215 
216 template <class T>
217 class ASNOptional : public member_ptr<T>
218 {
219 public:
220  void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED)
221  {
222  byte b;
223  if (seqDecoder.Peek(b) && (b & mask) == tag)
224  reset(new T(seqDecoder));
225  }
226  void DEREncode(BufferedTransformation &out)
227  {
228  if (this->get() != NULL)
229  this->get()->DEREncode(out);
230  }
231 };
232 
233 //! _
234 template <class BASE>
235 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE
236 {
237 public:
238  void Save(BufferedTransformation &bt) const
239  {BEREncode(bt);}
240  void Load(BufferedTransformation &bt)
241  {BERDecode(bt);}
242 };
243 
244 //! encodes/decodes subjectPublicKeyInfo
245 class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial<PublicKey>
246 {
247 public:
249  void DEREncode(BufferedTransformation &bt) const;
250 
251  virtual OID GetAlgorithmID() const =0;
252  virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
253  {BERDecodeNull(bt); return false;}
254  virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
255  {DEREncodeNull(bt); return false;} // see RFC 2459, section 7.3.1
256 
257  //! decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header
258  virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
259  //! encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header
260  virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0;
261 };
262 
263 //! encodes/decodes privateKeyInfo
264 class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial<PrivateKey>
265 {
266 public:
268  void DEREncode(BufferedTransformation &bt) const;
269 
270  virtual OID GetAlgorithmID() const =0;
271  virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
272  {BERDecodeNull(bt); return false;}
273  virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
274  {DEREncodeNull(bt); return false;} // see RFC 2459, section 7.3.1
275 
276  //! decode privateKey part of privateKeyInfo, without the OCTET STRING header
277  virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
278  //! encode privateKey part of privateKeyInfo, without the OCTET STRING header
279  virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0;
280 
281  //! decode optional attributes including context-specific tag
282  /*! /note default implementation stores attributes to be output in DEREncodeOptionalAttributes */
283  virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt);
284  //! encode optional attributes including context-specific tag
285  virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const;
286 
287 protected:
288  ByteQueue m_optionalAttributes;
289 };
290 
291 // ********************************************************
292 
293 //! DER Encode Unsigned
294 /*! for INTEGER, BOOLEAN, and ENUM */
295 template <class T>
296 size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
297 {
298  byte buf[sizeof(w)+1];
299  unsigned int bc;
300  if (asnTag == BOOLEAN)
301  {
302  buf[sizeof(w)] = w ? 0xff : 0;
303  bc = 1;
304  }
305  else
306  {
307  buf[0] = 0;
308  for (unsigned int i=0; i<sizeof(w); i++)
309  buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
310  bc = sizeof(w);
311  while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
312  --bc;
313  if (buf[sizeof(w)+1-bc] & 0x80)
314  ++bc;
315  }
316  out.Put(asnTag);
317  size_t lengthBytes = DERLengthEncode(out, bc);
318  out.Put(buf+sizeof(w)+1-bc, bc);
319  return 1+lengthBytes+bc;
320 }
321 
322 //! BER Decode Unsigned
323 // VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro
324 // CW41 workaround: std::numeric_limits<T>::max causes a template error
325 template <class T>
326 void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
327  T minValue = 0, T maxValue = 0xffffffff)
328 {
329  byte b;
330  if (!in.Get(b) || b != asnTag)
331  BERDecodeError();
332 
333  size_t bc;
334  BERLengthDecode(in, bc);
335  if (bc > in.MaxRetrievable())
336  BERDecodeError();
337 
338  SecByteBlock buf(bc);
339 
340  if (bc != in.Get(buf, bc))
341  BERDecodeError();
342 
343  const byte *ptr = buf;
344  while (bc > sizeof(w) && *ptr == 0)
345  {
346  bc--;
347  ptr++;
348  }
349  if (bc > sizeof(w))
350  BERDecodeError();
351 
352  w = 0;
353  for (unsigned int i=0; i<bc; i++)
354  w = (w << 8) | ptr[i];
355 
356  if (w < minValue || w > maxValue)
357  BERDecodeError();
358 }
359 
360 inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
361  {return lhs.m_values == rhs.m_values;}
362 inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
363  {return lhs.m_values != rhs.m_values;}
364 inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
365  {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
366 inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
367  {return ::CryptoPP::OID(lhs)+=rhs;}
368 
369 NAMESPACE_END
370 
371 #endif
virtual void DEREncode(BufferedTransformation &bt) const =0
encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules) ...
virtual size_t Get(byte &outByte)
try to retrieve a single byte
encodes/decodes privateKeyInfo
Definition: asn.h:264
virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)=0
upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
A BufferedTransformation that only contains pre-existing data as "output".
Definition: simple.h:167
BER Set Decoder.
Definition: asn.h:197
BER Sequence Decoder.
Definition: asn.h:177
interface for buffered transformations
Definition: cryptlib.h:770
size_t Put(byte inByte, bool blocking=true)
input a byte for processing
Definition: cryptlib.h:784
const std::string DEFAULT_CHANNEL
the default channel for BufferedTransformation, equal to the empty string
virtual void BERDecode(BufferedTransformation &bt)=0
decode this object from a BufferedTransformation, using BER (Basic Encoding Rules) ...
interface for encoding and decoding ASN1 objects
Definition: cryptlib.h:1633
DER Set Encoder.
Definition: asn.h:207
bool operator<(const ::PolynomialMod2 &a, const ::PolynomialMod2 &b)
compares degree
Definition: gf2n.h:252
virtual lword MaxRetrievable() const
returns number of bytes that is currently ready for retrieval
virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0
upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block
virtual size_t Peek(byte &outByte) const
peek at the next byte without removing it from the output buffer
Byte Queue.
Definition: queue.h:16
virtual void BEREncode(BufferedTransformation &bt) const
encode this object into a BufferedTransformation, using BER
Definition: cryptlib.h:1643
DER Sequence Encoder.
Definition: asn.h:187
DER General Encoder.
Definition: asn.h:159
Definition: asn.h:51
provides an implementation of BufferedTransformation's attachment interface
Definition: filters.h:17
encodes/decodes subjectPublicKeyInfo
Definition: asn.h:245
BER General Decoder.
Definition: asn.h:128
Object Identifier.
Definition: asn.h:82
interface for retrieving values given their names
Definition: cryptlib.h:224
BER Decode Exception Class, may be thrown during an ASN1 BER decode operation.
Definition: cryptlib.h:1625