asn.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. // asn.h - originally written and placed in the public domain by Wei Dai
  2. /// \file asn.h
  3. /// \brief Classes and functions for working with ANS.1 objects
  4. #ifndef CRYPTOPP_ASN_H
  5. #define CRYPTOPP_ASN_H
  6. #include "cryptlib.h"
  7. #include "filters.h"
  8. #include "smartptr.h"
  9. #include "stdcpp.h"
  10. #include "queue.h"
  11. #include "misc.h"
  12. #include <iosfwd>
  13. // Issue 340
  14. #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
  15. # pragma GCC diagnostic push
  16. # pragma GCC diagnostic ignored "-Wconversion"
  17. # pragma GCC diagnostic ignored "-Wsign-conversion"
  18. #endif
  19. NAMESPACE_BEGIN(CryptoPP)
  20. /// \brief ASN.1 types
  21. /// \note These tags are not complete
  22. enum ASNTag
  23. {
  24. /// \brief ASN.1 Boolean
  25. BOOLEAN = 0x01,
  26. /// \brief ASN.1 Integer
  27. INTEGER = 0x02,
  28. /// \brief ASN.1 Bit string
  29. BIT_STRING = 0x03,
  30. /// \brief ASN.1 Octet string
  31. OCTET_STRING = 0x04,
  32. /// \brief ASN.1 Null
  33. TAG_NULL = 0x05,
  34. /// \brief ASN.1 Object identifier
  35. OBJECT_IDENTIFIER = 0x06,
  36. /// \brief ASN.1 Object descriptor
  37. OBJECT_DESCRIPTOR = 0x07,
  38. /// \brief ASN.1 External reference
  39. EXTERNAL = 0x08,
  40. /// \brief ASN.1 Real integer
  41. REAL = 0x09,
  42. /// \brief ASN.1 Enumerated value
  43. ENUMERATED = 0x0a,
  44. /// \brief ASN.1 UTF-8 string
  45. UTF8_STRING = 0x0c,
  46. /// \brief ASN.1 Sequence
  47. SEQUENCE = 0x10,
  48. /// \brief ASN.1 Set
  49. SET = 0x11,
  50. /// \brief ASN.1 Numeric string
  51. NUMERIC_STRING = 0x12,
  52. /// \brief ASN.1 Printable string
  53. PRINTABLE_STRING = 0x13,
  54. /// \brief ASN.1 T61 string
  55. T61_STRING = 0x14,
  56. /// \brief ASN.1 Videotext string
  57. VIDEOTEXT_STRING = 0x15,
  58. /// \brief ASN.1 IA5 string
  59. IA5_STRING = 0x16,
  60. /// \brief ASN.1 UTC time
  61. UTC_TIME = 0x17,
  62. /// \brief ASN.1 Generalized time
  63. GENERALIZED_TIME = 0x18,
  64. /// \brief ASN.1 Graphic string
  65. GRAPHIC_STRING = 0x19,
  66. /// \brief ASN.1 Visible string
  67. VISIBLE_STRING = 0x1a,
  68. /// \brief ASN.1 General string
  69. GENERAL_STRING = 0x1b,
  70. /// \brief ASN.1 Universal string
  71. UNIVERSAL_STRING = 0x1c,
  72. /// \brief ASN.1 BMP string
  73. BMP_STRING = 0x1e
  74. };
  75. /// \brief ASN.1 flags
  76. /// \note These flags are not complete
  77. enum ASNIdFlag
  78. {
  79. /// \brief ASN.1 Universal class
  80. UNIVERSAL = 0x00,
  81. // DATA = 0x01,
  82. // HEADER = 0x02,
  83. /// \brief ASN.1 Primitive flag
  84. PRIMITIVE = 0x00,
  85. /// \brief ASN.1 Constructed flag
  86. CONSTRUCTED = 0x20,
  87. /// \brief ASN.1 Application class
  88. APPLICATION = 0x40,
  89. /// \brief ASN.1 Context specific class
  90. CONTEXT_SPECIFIC = 0x80,
  91. /// \brief ASN.1 Private class
  92. PRIVATE = 0xc0
  93. };
  94. /// \brief Raises a BERDecodeErr
  95. inline void BERDecodeError() {throw BERDecodeErr();}
  96. /// \brief Exception thrown when an unknown object identifier is encountered
  97. class CRYPTOPP_DLL UnknownOID : public BERDecodeErr
  98. {
  99. public:
  100. /// \brief Construct an UnknownOID
  101. UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {}
  102. /// \brief Construct an UnknownOID
  103. /// \param err error message to use for the exception
  104. UnknownOID(const char *err) : BERDecodeErr(err) {}
  105. };
  106. /// \brief DER encode a length
  107. /// \param bt BufferedTransformation object for writing
  108. /// \param length the size to encode
  109. /// \return the number of octets used for the encoding
  110. CRYPTOPP_DLL size_t CRYPTOPP_API DERLengthEncode(BufferedTransformation &bt, lword length);
  111. /// \brief BER decode a length
  112. /// \param bt BufferedTransformation object for reading
  113. /// \param length the decoded size
  114. /// \return true if the value was decoded
  115. /// \throw BERDecodeError if the value fails to decode or is too large for size_t
  116. /// \details BERLengthDecode() returns false if the encoding is indefinite length.
  117. CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &bt, size_t &length);
  118. /// \brief DER encode NULL
  119. /// \param bt BufferedTransformation object for writing
  120. CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &bt);
  121. /// \brief BER decode NULL
  122. /// \param bt BufferedTransformation object for reading
  123. CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &bt);
  124. /// \brief DER encode octet string
  125. /// \param bt BufferedTransformation object for writing
  126. /// \param str the string to encode
  127. /// \param strLen the length of the string
  128. /// \return the number of octets used for the encoding
  129. CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen);
  130. /// \brief DER encode octet string
  131. /// \param bt BufferedTransformation object for reading
  132. /// \param str the string to encode
  133. /// \return the number of octets used for the encoding
  134. CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str);
  135. /// \brief BER decode octet string
  136. /// \param bt BufferedTransformation object for reading
  137. /// \param str the decoded string
  138. /// \return the number of octets used for the encoding
  139. CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str);
  140. /// \brief BER decode octet string
  141. /// \param bt BufferedTransformation object for reading
  142. /// \param str the decoded string
  143. /// \return the number of octets used for the encoding
  144. CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str);
  145. /// \brief DER encode text string
  146. /// \param bt BufferedTransformation object for writing
  147. /// \param str the string to encode
  148. /// \param strLen the length of the string, in bytes
  149. /// \param asnTag the ASN.1 identifier
  150. /// \return the number of octets used for the encoding
  151. /// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
  152. /// \since Crypto++ 8.3
  153. CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const byte* str, size_t strLen, byte asnTag);
  154. /// \brief DER encode text string
  155. /// \param bt BufferedTransformation object for writing
  156. /// \param str the string to encode
  157. /// \param asnTag the ASN.1 identifier
  158. /// \return the number of octets used for the encoding
  159. /// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
  160. /// \since Crypto++ 8.3
  161. CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag);
  162. /// \brief DER encode text string
  163. /// \param bt BufferedTransformation object for writing
  164. /// \param str the string to encode
  165. /// \param asnTag the ASN.1 identifier
  166. /// \return the number of octets used for the encoding
  167. /// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
  168. /// \since Crypto++ 6.0
  169. CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag);
  170. /// \brief BER decode text string
  171. /// \param bt BufferedTransformation object for reading
  172. /// \param str the string to decode
  173. /// \param asnTag the ASN.1 identifier
  174. /// \details BERDecodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
  175. /// \since Crypto++ 8.3
  176. CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &bt, SecByteBlock &str, byte asnTag);
  177. /// \brief BER decode text string
  178. /// \param bt BufferedTransformation object for reading
  179. /// \param str the string to decode
  180. /// \param asnTag the ASN.1 identifier
  181. /// \details BERDecodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
  182. /// \since Crypto++ 6.0
  183. CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag);
  184. /// \brief DER encode date
  185. /// \param bt BufferedTransformation object for writing
  186. /// \param str the date to encode
  187. /// \param asnTag the ASN.1 identifier
  188. /// \return the number of octets used for the encoding
  189. /// \details BERDecodeDate() can be used for UTC_TIME and GENERALIZED_TIME
  190. /// \since Crypto++ 8.3
  191. CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeDate(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag);
  192. /// \brief BER decode date
  193. /// \param bt BufferedTransformation object for reading
  194. /// \param str the date to decode
  195. /// \param asnTag the ASN.1 identifier
  196. /// \details BERDecodeDate() can be used for UTC_TIME and GENERALIZED_TIME
  197. /// \since Crypto++ 8.3
  198. CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeDate(BufferedTransformation &bt, SecByteBlock &str, byte asnTag);
  199. /// \brief DER encode bit string
  200. /// \param bt BufferedTransformation object for writing
  201. /// \param str the string to encode
  202. /// \param strLen the length of the string
  203. /// \param unusedBits the number of unused bits
  204. /// \return the number of octets used for the encoding
  205. /// \details The caller is responsible for shifting octets if unusedBits is
  206. /// not 0. For example, to DER encode a web server X.509 key usage, the 101b
  207. /// bit mask is often used (digitalSignature and keyEncipherment). In this
  208. /// case <tt>str</tt> is one octet with a value=0xa0 and unusedBits=5. The
  209. /// value 0xa0 is <tt>101b << 5</tt>.
  210. CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0);
  211. /// \brief DER decode bit string
  212. /// \param bt BufferedTransformation object for reading
  213. /// \param str the decoded string
  214. /// \param unusedBits the number of unused bits
  215. /// \details The caller is responsible for shifting octets if unusedBits is
  216. /// not 0. For example, to DER encode a web server X.509 key usage, the 101b
  217. /// bit mask is often used (digitalSignature and keyEncipherment). In this
  218. /// case <tt>str</tt> is one octet with a value=0xa0 and unusedBits=5. The
  219. /// value 0xa0 is <tt>101b << 5</tt>.
  220. CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits);
  221. /// \brief BER decode and DER re-encode
  222. /// \param bt BufferedTransformation object for writing
  223. /// \param dest BufferedTransformation object
  224. CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &bt, BufferedTransformation &dest);
  225. /// \brief BER decode size
  226. /// \param bt BufferedTransformation object for reading
  227. /// \return the length of the ASN.1 value, in bytes
  228. /// \details BERDecodePeekLength() determines the length of a value without
  229. /// consuming octets in the stream. The stream must use definite length encoding.
  230. /// If indefinite length encoding is used or an error occurs, then 0 is returned.
  231. /// \since Crypto++ 8.3
  232. CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodePeekLength(const BufferedTransformation &bt);
  233. /// \brief Object Identifier
  234. class CRYPTOPP_DLL OID
  235. {
  236. public:
  237. virtual ~OID() {}
  238. /// \brief Construct an OID
  239. OID() {}
  240. /// \brief Construct an OID
  241. /// \param v value to initialize the OID
  242. OID(word32 v) : m_values(1, v) {}
  243. /// \brief Construct an OID
  244. /// \param bt BufferedTransformation object
  245. OID(BufferedTransformation &bt) {
  246. BERDecode(bt);
  247. }
  248. /// \brief Append a value to an OID
  249. /// \param rhs the value to append
  250. inline OID & operator+=(word32 rhs) {
  251. m_values.push_back(rhs); return *this;
  252. }
  253. /// \brief DER encode this OID
  254. /// \param bt BufferedTransformation object
  255. void DEREncode(BufferedTransformation &bt) const;
  256. /// \brief BER decode an OID
  257. /// \param bt BufferedTransformation object
  258. void BERDecode(BufferedTransformation &bt);
  259. /// \brief BER decode an OID
  260. /// \param bt BufferedTransformation object
  261. /// \throw BERDecodeErr() if decoded value doesn't match an expected OID
  262. /// \details BERDecodeAndCheck() can be used to parse an OID and verify it matches an expected.
  263. /// <pre>
  264. /// BERSequenceDecoder key(bt);
  265. /// ...
  266. /// BERSequenceDecoder algorithm(key);
  267. /// GetAlgorithmID().BERDecodeAndCheck(algorithm);
  268. /// </pre>
  269. void BERDecodeAndCheck(BufferedTransformation &bt) const;
  270. /// \brief Determine if OID is empty
  271. /// \return true if OID has 0 elements, false otherwise
  272. /// \since Crypto++ 8.0
  273. bool Empty() const {
  274. return m_values.empty();
  275. }
  276. /// \brief Retrieve OID value array
  277. /// \return OID value vector
  278. /// \since Crypto++ 8.0
  279. const std::vector<word32>& GetValues() const {
  280. return m_values;
  281. }
  282. /// \brief Print an OID
  283. /// \param out ostream object
  284. /// \return ostream reference
  285. /// \details Print() writes the OID in a customary format, like
  286. /// 1.2.840.113549.1.1.11. The caller is reposnsible to convert the
  287. /// OID to a friendly name, like sha256WithRSAEncryption.
  288. /// \since Crypto++ 8.3
  289. std::ostream& Print(std::ostream& out) const;
  290. protected:
  291. friend bool operator==(const OID &lhs, const OID &rhs);
  292. friend bool operator!=(const OID &lhs, const OID &rhs);
  293. friend bool operator< (const OID &lhs, const OID &rhs);
  294. friend bool operator> (const OID &lhs, const OID &rhs);
  295. friend bool operator<=(const OID &lhs, const OID &rhs);
  296. friend bool operator>=(const OID &lhs, const OID &rhs);
  297. std::vector<word32> m_values;
  298. private:
  299. static void EncodeValue(BufferedTransformation &bt, word32 v);
  300. static size_t DecodeValue(BufferedTransformation &bt, word32 &v);
  301. };
  302. /// \brief ASN.1 encoded object filter
  303. class EncodedObjectFilter : public Filter
  304. {
  305. public:
  306. 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};
  307. enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state;
  308. virtual ~EncodedObjectFilter() {}
  309. /// \brief Construct an EncodedObjectFilter
  310. /// \param attachment a BufferedTrasformation to attach to this object
  311. /// \param nObjects the number of objects
  312. /// \param flags bitwise OR of EncodedObjectFilter::Flag
  313. EncodedObjectFilter(BufferedTransformation *attachment = NULLPTR, unsigned int nObjects = 1, word32 flags = 0);
  314. /// \brief Input a byte buffer for processing
  315. /// \param inString the byte buffer to process
  316. /// \param length the size of the string, in bytes
  317. void Put(const byte *inString, size_t length);
  318. unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;}
  319. unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];}
  320. private:
  321. BufferedTransformation & CurrentTarget();
  322. ByteQueue m_queue;
  323. std::vector<unsigned int> m_positions;
  324. lword m_lengthRemaining;
  325. word32 m_nObjects, m_nCurrentObject, m_level, m_flags;
  326. byte m_id;
  327. };
  328. /// \brief BER General Decoder
  329. class CRYPTOPP_DLL BERGeneralDecoder : public Store
  330. {
  331. public:
  332. /// \brief Default ASN.1 tag
  333. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  334. virtual ~BERGeneralDecoder();
  335. /// \brief Construct an ASN.1 decoder
  336. /// \param inQueue input byte queue
  337. /// \details BERGeneralDecoder uses DefaultTag
  338. explicit BERGeneralDecoder(BufferedTransformation &inQueue);
  339. /// \brief Construct an ASN.1 decoder
  340. /// \param inQueue input byte queue
  341. /// \param asnTag ASN.1 tag
  342. explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
  343. /// \brief Construct an ASN.1 decoder
  344. /// \param inQueue input byte queue
  345. /// \param asnTag ASN.1 tag
  346. explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
  347. /// \brief Determine length encoding
  348. /// \return true if the ASN.1 object is definite length encoded, false otherwise
  349. bool IsDefiniteLength() const {
  350. return m_definiteLength;
  351. }
  352. /// \brief Determine remaining length
  353. /// \return number of octets that remain to be consumed
  354. /// \details RemainingLength() is only valid if IsDefiniteLength()
  355. /// returns true.
  356. lword RemainingLength() const {
  357. CRYPTOPP_ASSERT(m_definiteLength);
  358. return IsDefiniteLength() ? m_length : 0;
  359. }
  360. /// \brief Determine end of stream
  361. /// \return true if all octets have been consumed, false otherwise
  362. bool EndReached() const;
  363. /// \brief Determine next octet
  364. /// \return next octet in the stream
  365. /// \details PeekByte does not consume the octet.
  366. /// \throw BERDecodeError if there are no octets remaining
  367. byte PeekByte() const;
  368. /// \brief Determine next octet
  369. /// \details CheckByte reads the next byte in the stream and verifies
  370. /// the octet matches b.
  371. /// \throw BERDecodeError if the next octet is not b
  372. void CheckByte(byte b);
  373. /// \brief Transfer bytes to another BufferedTransformation
  374. /// \param target the destination BufferedTransformation
  375. /// \param transferBytes the number of bytes to transfer
  376. /// \param channel the channel on which the transfer should occur
  377. /// \param blocking specifies whether the object should block when
  378. /// processing input
  379. /// \return the number of bytes that remain in the transfer block
  380. /// (i.e., bytes not transferred)
  381. /// \details TransferTo2() removes bytes and moves
  382. /// them to the destination. Transfer begins at the index position
  383. /// in the current stream, and not from an absolute position in the
  384. /// stream.
  385. /// \details transferBytes is an \a IN and \a OUT parameter. When
  386. /// the call is made, transferBytes is the requested size of the
  387. /// transfer. When the call returns, transferBytes is the number
  388. /// of bytes that were transferred.
  389. size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
  390. /// \brief Copy bytes to another BufferedTransformation
  391. /// \param target the destination BufferedTransformation
  392. /// \param begin the 0-based index of the first byte to copy in
  393. /// the stream
  394. /// \param end the 0-based index of the last byte to copy in
  395. /// the stream
  396. /// \param channel the channel on which the transfer should occur
  397. /// \param blocking specifies whether the object should block when
  398. /// processing input
  399. /// \return the number of bytes that remain in the copy block
  400. /// (i.e., bytes not copied)
  401. /// \details CopyRangeTo2 copies bytes to the
  402. /// destination. The bytes are not removed from this object. Copying
  403. /// begins at the index position in the current stream, and not from
  404. /// an absolute position in the stream.
  405. /// \details begin is an \a IN and \a OUT parameter. When the call is
  406. /// made, begin is the starting position of the copy. When the call
  407. /// returns, begin is the position of the first byte that was \a not
  408. /// copied (which may be different than end). begin can be used for
  409. /// subsequent calls to CopyRangeTo2().
  410. size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
  411. /// \brief Signals the end of messages to the object
  412. /// \details Call this to denote end of sequence
  413. void MessageEnd();
  414. protected:
  415. BufferedTransformation &m_inQueue;
  416. lword m_length;
  417. bool m_finished, m_definiteLength;
  418. private:
  419. void Init(byte asnTag);
  420. void StoreInitialize(const NameValuePairs &parameters)
  421. {CRYPTOPP_UNUSED(parameters); CRYPTOPP_ASSERT(false);}
  422. lword ReduceLength(lword delta);
  423. };
  424. /// \brief DER General Encoder
  425. class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
  426. {
  427. public:
  428. /// \brief Default ASN.1 tag
  429. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  430. virtual ~DERGeneralEncoder();
  431. /// \brief Construct an ASN.1 encoder
  432. /// \param outQueue output byte queue
  433. /// \details DERGeneralEncoder uses DefaultTag
  434. explicit DERGeneralEncoder(BufferedTransformation &outQueue);
  435. /// \brief Construct an ASN.1 encoder
  436. /// \param outQueue output byte queue
  437. /// \param asnTag ASN.1 tag
  438. explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag);
  439. /// \brief Construct an ASN.1 encoder
  440. /// \param outQueue output byte queue
  441. /// \param asnTag ASN.1 tag
  442. explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag);
  443. /// \brief Signals the end of messages to the object
  444. /// \details Call this to denote end of sequence
  445. void MessageEnd();
  446. private:
  447. BufferedTransformation &m_outQueue;
  448. byte m_asnTag;
  449. bool m_finished;
  450. };
  451. /// \brief BER Sequence Decoder
  452. class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
  453. {
  454. public:
  455. /// \brief Default ASN.1 tag
  456. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  457. /// \brief Construct an ASN.1 decoder
  458. /// \param inQueue input byte queue
  459. /// \details BERSequenceDecoder uses DefaultTag
  460. explicit BERSequenceDecoder(BufferedTransformation &inQueue)
  461. : BERGeneralDecoder(inQueue, DefaultTag) {}
  462. /// \brief Construct an ASN.1 decoder
  463. /// \param inQueue input byte queue
  464. /// \param asnTag ASN.1 tag
  465. explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag)
  466. : BERGeneralDecoder(inQueue, asnTag) {}
  467. /// \brief Construct an ASN.1 decoder
  468. /// \param inQueue input byte queue
  469. /// \details BERSequenceDecoder uses DefaultTag
  470. explicit BERSequenceDecoder(BERSequenceDecoder &inQueue)
  471. : BERGeneralDecoder(inQueue, DefaultTag) {}
  472. /// \brief Construct an ASN.1 decoder
  473. /// \param inQueue input byte queue
  474. /// \param asnTag ASN.1 tag
  475. explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag)
  476. : BERGeneralDecoder(inQueue, asnTag) {}
  477. };
  478. /// \brief DER Sequence Encoder
  479. class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
  480. {
  481. public:
  482. /// \brief Default ASN.1 tag
  483. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  484. /// \brief Construct an ASN.1 encoder
  485. /// \param outQueue output byte queue
  486. /// \details DERSequenceEncoder uses DefaultTag
  487. explicit DERSequenceEncoder(BufferedTransformation &outQueue)
  488. : DERGeneralEncoder(outQueue, DefaultTag) {}
  489. /// \brief Construct an ASN.1 encoder
  490. /// \param outQueue output byte queue
  491. /// \param asnTag ASN.1 tag
  492. explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag)
  493. : DERGeneralEncoder(outQueue, asnTag) {}
  494. /// \brief Construct an ASN.1 encoder
  495. /// \param outQueue output byte queue
  496. /// \details DERSequenceEncoder uses DefaultTag
  497. explicit DERSequenceEncoder(DERSequenceEncoder &outQueue)
  498. : DERGeneralEncoder(outQueue, DefaultTag) {}
  499. /// \brief Construct an ASN.1 encoder
  500. /// \param outQueue output byte queue
  501. /// \param asnTag ASN.1 tag
  502. explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag)
  503. : DERGeneralEncoder(outQueue, asnTag) {}
  504. };
  505. /// \brief BER Set Decoder
  506. class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
  507. {
  508. public:
  509. /// \brief Default ASN.1 tag
  510. enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)};
  511. /// \brief Construct an ASN.1 decoder
  512. /// \param inQueue input byte queue
  513. /// \details BERSetDecoder uses DefaultTag
  514. explicit BERSetDecoder(BufferedTransformation &inQueue)
  515. : BERGeneralDecoder(inQueue, DefaultTag) {}
  516. /// \brief Construct an ASN.1 decoder
  517. /// \param inQueue input byte queue
  518. /// \param asnTag ASN.1 tag
  519. explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag)
  520. : BERGeneralDecoder(inQueue, asnTag) {}
  521. /// \brief Construct an ASN.1 decoder
  522. /// \param inQueue input byte queue
  523. /// \details BERSetDecoder uses DefaultTag
  524. explicit BERSetDecoder(BERSetDecoder &inQueue)
  525. : BERGeneralDecoder(inQueue, DefaultTag) {}
  526. /// \brief Construct an ASN.1 decoder
  527. /// \param inQueue input byte queue
  528. /// \param asnTag ASN.1 tag
  529. explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag)
  530. : BERGeneralDecoder(inQueue, asnTag) {}
  531. };
  532. /// \brief DER Set Encoder
  533. class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
  534. {
  535. public:
  536. /// \brief Default ASN.1 tag
  537. enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)};
  538. /// \brief Construct an ASN.1 encoder
  539. /// \param outQueue output byte queue
  540. /// \details DERSetEncoder uses DefaultTag
  541. explicit DERSetEncoder(BufferedTransformation &outQueue)
  542. : DERGeneralEncoder(outQueue, DefaultTag) {}
  543. /// \brief Construct an ASN.1 encoder
  544. /// \param outQueue output byte queue
  545. /// \param asnTag ASN.1 tag
  546. explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag)
  547. : DERGeneralEncoder(outQueue, asnTag) {}
  548. /// \brief Construct an ASN.1 encoder
  549. /// \param outQueue output byte queue
  550. /// \details DERSetEncoder uses DefaultTag
  551. explicit DERSetEncoder(DERSetEncoder &outQueue)
  552. : DERGeneralEncoder(outQueue, DefaultTag) {}
  553. /// \brief Construct an ASN.1 encoder
  554. /// \param outQueue output byte queue
  555. /// \param asnTag ASN.1 tag
  556. explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag)
  557. : DERGeneralEncoder(outQueue, asnTag) {}
  558. };
  559. /// \brief Optional data encoder and decoder
  560. /// \tparam T class or type
  561. template <class T>
  562. class ASNOptional : public member_ptr<T>
  563. {
  564. public:
  565. /// \brief BER decode optional data
  566. /// \param seqDecoder sequence with the optional ASN.1 data
  567. /// \param tag ASN.1 tag to match as optional data
  568. /// \param mask the mask to apply when matching the tag
  569. /// \sa ASNTag and ASNIdFlag
  570. void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED)
  571. {
  572. byte b;
  573. if (seqDecoder.Peek(b) && (b & mask) == tag)
  574. reset(new T(seqDecoder));
  575. }
  576. /// \brief DER encode optional data
  577. /// \param out BufferedTransformation object
  578. void DEREncode(BufferedTransformation &out)
  579. {
  580. if (this->get() != NULLPTR)
  581. this->get()->DEREncode(out);
  582. }
  583. };
  584. /// \brief Encode and decode ASN.1 objects with additional information
  585. /// \tparam BASE base class or type
  586. /// \details Encodes and decodes public keys, private keys and group
  587. /// parameters with OID identifying the algorithm or scheme.
  588. template <class BASE>
  589. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE
  590. {
  591. public:
  592. /// \brief DER encode ASN.1 object
  593. /// \param bt BufferedTransformation object
  594. /// \details Save() will write the OID associated with algorithm or scheme.
  595. /// In the case of public and private keys, this function writes the
  596. /// subjectPublicKeyInfo and privateKeyInfo parts.
  597. void Save(BufferedTransformation &bt) const
  598. {BEREncode(bt);}
  599. /// \brief BER decode ASN.1 object
  600. /// \param bt BufferedTransformation object
  601. void Load(BufferedTransformation &bt)
  602. {BERDecode(bt);}
  603. };
  604. /// \brief Encodes and decodes subjectPublicKeyInfo
  605. class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial<PublicKey>
  606. {
  607. public:
  608. virtual ~X509PublicKey() {}
  609. void BERDecode(BufferedTransformation &bt);
  610. void DEREncode(BufferedTransformation &bt) const;
  611. /// \brief Retrieves the OID of the algorithm
  612. /// \return OID of the algorithm
  613. virtual OID GetAlgorithmID() const =0;
  614. /// \brief Decode algorithm parameters
  615. /// \param bt BufferedTransformation object
  616. /// \sa BERDecodePublicKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  617. /// 2459, section 7.3.1</A>
  618. virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
  619. {BERDecodeNull(bt); return false;}
  620. /// \brief Encode algorithm parameters
  621. /// \param bt BufferedTransformation object
  622. /// \sa DEREncodePublicKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  623. /// 2459, section 7.3.1</A>
  624. virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
  625. {DEREncodeNull(bt); return false;}
  626. /// \brief Decode subjectPublicKey part of subjectPublicKeyInfo
  627. /// \param bt BufferedTransformation object
  628. /// \param parametersPresent flag indicating if algorithm parameters are present
  629. /// \param size number of octets to read for the parameters, in bytes
  630. /// \details BERDecodePublicKey() the decodes subjectPublicKey part of
  631. /// subjectPublicKeyInfo, without the BIT STRING header.
  632. /// \details When <tt>parametersPresent = true</tt> then BERDecodePublicKey() calls
  633. /// BERDecodeAlgorithmParameters() to parse algorithm parameters.
  634. /// \sa BERDecodeAlgorithmParameters
  635. virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
  636. /// \brief Encode subjectPublicKey part of subjectPublicKeyInfo
  637. /// \param bt BufferedTransformation object
  638. /// \details DEREncodePublicKey() encodes the subjectPublicKey part of
  639. /// subjectPublicKeyInfo, without the BIT STRING header.
  640. /// \sa DEREncodeAlgorithmParameters
  641. virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0;
  642. };
  643. /// \brief Encodes and Decodes privateKeyInfo
  644. class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial<PrivateKey>
  645. {
  646. public:
  647. virtual ~PKCS8PrivateKey() {}
  648. void BERDecode(BufferedTransformation &bt);
  649. void DEREncode(BufferedTransformation &bt) const;
  650. /// \brief Retrieves the OID of the algorithm
  651. /// \return OID of the algorithm
  652. virtual OID GetAlgorithmID() const =0;
  653. /// \brief Decode optional parameters
  654. /// \param bt BufferedTransformation object
  655. /// \sa BERDecodePrivateKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  656. /// 2459, section 7.3.1</A>
  657. virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
  658. {BERDecodeNull(bt); return false;}
  659. /// \brief Encode optional parameters
  660. /// \param bt BufferedTransformation object
  661. /// \sa DEREncodePrivateKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  662. /// 2459, section 7.3.1</A>
  663. virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
  664. {DEREncodeNull(bt); return false;}
  665. /// \brief Decode privateKey part of privateKeyInfo
  666. /// \param bt BufferedTransformation object
  667. /// \param parametersPresent flag indicating if algorithm parameters are present
  668. /// \param size number of octets to read for the parameters, in bytes
  669. /// \details BERDecodePrivateKey() the decodes privateKey part of privateKeyInfo,
  670. /// without the OCTET STRING header.
  671. /// \details When <tt>parametersPresent = true</tt> then BERDecodePrivateKey() calls
  672. /// BERDecodeAlgorithmParameters() to parse algorithm parameters.
  673. /// \sa BERDecodeAlgorithmParameters
  674. virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
  675. /// \brief Encode privateKey part of privateKeyInfo
  676. /// \param bt BufferedTransformation object
  677. /// \details DEREncodePrivateKey() encodes the privateKey part of privateKeyInfo,
  678. /// without the OCTET STRING header.
  679. /// \sa DEREncodeAlgorithmParameters
  680. virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0;
  681. /// \brief Decode optional attributes
  682. /// \param bt BufferedTransformation object
  683. /// \details BERDecodeOptionalAttributes() decodes optional attributes including
  684. /// context-specific tag.
  685. /// \sa BERDecodeAlgorithmParameters, DEREncodeOptionalAttributes
  686. /// \note default implementation stores attributes to be output using
  687. /// DEREncodeOptionalAttributes
  688. virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt);
  689. /// \brief Encode optional attributes
  690. /// \param bt BufferedTransformation object
  691. /// \details DEREncodeOptionalAttributes() encodes optional attributes including
  692. /// context-specific tag.
  693. /// \sa BERDecodeAlgorithmParameters
  694. virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const;
  695. protected:
  696. ByteQueue m_optionalAttributes;
  697. };
  698. // ********************************************************
  699. /// \brief DER Encode unsigned value
  700. /// \tparam T class or type
  701. /// \param out BufferedTransformation object
  702. /// \param w unsigned value to encode
  703. /// \param asnTag the ASN.1 identifier
  704. /// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM
  705. template <class T>
  706. size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
  707. {
  708. byte buf[sizeof(w)+1];
  709. unsigned int bc;
  710. if (asnTag == BOOLEAN)
  711. {
  712. buf[sizeof(w)] = w ? 0xff : 0;
  713. bc = 1;
  714. }
  715. else
  716. {
  717. buf[0] = 0;
  718. for (unsigned int i=0; i<sizeof(w); i++)
  719. buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
  720. bc = sizeof(w);
  721. while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
  722. --bc;
  723. if (buf[sizeof(w)+1-bc] & 0x80)
  724. ++bc;
  725. }
  726. out.Put(asnTag);
  727. size_t lengthBytes = DERLengthEncode(out, bc);
  728. out.Put(buf+sizeof(w)+1-bc, bc);
  729. return 1+lengthBytes+bc;
  730. }
  731. /// \brief BER Decode unsigned value
  732. /// \tparam T fundamental C++ type
  733. /// \param in BufferedTransformation object
  734. /// \param w the decoded value
  735. /// \param asnTag the ASN.1 identifier
  736. /// \param minValue the minimum expected value
  737. /// \param maxValue the maximum expected value
  738. /// \throw BERDecodeErr() if the value cannot be parsed or the decoded value is not within range.
  739. /// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM
  740. template <class T>
  741. void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
  742. T minValue = 0, T maxValue = T(0xffffffff))
  743. {
  744. byte b;
  745. if (!in.Get(b) || b != asnTag)
  746. BERDecodeError();
  747. size_t bc;
  748. bool definite = BERLengthDecode(in, bc);
  749. if (!definite)
  750. BERDecodeError();
  751. if (bc > in.MaxRetrievable()) // Issue 346
  752. BERDecodeError();
  753. if (asnTag == BOOLEAN && bc != 1) // X.690, 8.2.1
  754. BERDecodeError();
  755. if ((asnTag == INTEGER || asnTag == ENUMERATED) && bc == 0) // X.690, 8.3.1 and 8.4
  756. BERDecodeError();
  757. SecByteBlock buf(bc);
  758. if (bc != in.Get(buf, bc))
  759. BERDecodeError();
  760. // This consumes leading 0 octets. According to X.690, 8.3.2, it could be non-conforming behavior.
  761. // X.690, 8.3.2 says "the bits of the first octet and bit 8 of the second octet ... (a) shall
  762. // not all be ones and (b) shall not all be zeros ... These rules ensure that an integer value
  763. // is always encoded in the smallest possible number of octet".
  764. // We invented AER (Alternate Encoding Rules), which is more relaxed than BER, CER, and DER.
  765. const byte *ptr = buf;
  766. while (bc > sizeof(w) && *ptr == 0)
  767. {
  768. bc--;
  769. ptr++;
  770. }
  771. if (bc > sizeof(w))
  772. BERDecodeError();
  773. w = 0;
  774. for (unsigned int i=0; i<bc; i++)
  775. w = (w << 8) | ptr[i];
  776. if (w < minValue || w > maxValue)
  777. BERDecodeError();
  778. }
  779. #ifdef CRYPTOPP_DOXYGEN_PROCESSING
  780. /// \brief Compare two OIDs for equality
  781. /// \param lhs the first OID
  782. /// \param rhs the second OID
  783. /// \return true if the OIDs are equal, false otherwise
  784. inline bool operator==(const OID &lhs, const OID &rhs);
  785. /// \brief Compare two OIDs for inequality
  786. /// \param lhs the first OID
  787. /// \param rhs the second OID
  788. /// \return true if the OIDs are not equal, false otherwise
  789. inline bool operator!=(const OID &lhs, const OID &rhs);
  790. /// \brief Compare two OIDs for ordering
  791. /// \param lhs the first OID
  792. /// \param rhs the second OID
  793. /// \return true if the first OID is less than the second OID, false otherwise
  794. /// \details operator<() calls std::lexicographical_compare() on the values.
  795. inline bool operator<(const OID &lhs, const OID &rhs);
  796. /// \brief Compare two OIDs for ordering
  797. /// \param lhs the first OID
  798. /// \param rhs the second OID
  799. /// \return true if the first OID is greater than the second OID, false otherwise
  800. /// \details operator>() is implemented in terms of operator==() and operator<().
  801. /// \since Crypto++ 8.3
  802. inline bool operator>(const OID &lhs, const OID &rhs);
  803. /// \brief Compare two OIDs for ordering
  804. /// \param lhs the first OID
  805. /// \param rhs the second OID
  806. /// \return true if the first OID is less than or equal to the second OID, false otherwise
  807. /// \details operator<=() is implemented in terms of operator==() and operator<().
  808. /// \since Crypto++ 8.3
  809. inline bool operator<=(const OID &lhs, const OID &rhs);
  810. /// \brief Compare two OIDs for ordering
  811. /// \param lhs the first OID
  812. /// \param rhs the second OID
  813. /// \return true if the first OID is greater than or equal to the second OID, false otherwise
  814. /// \details operator>=() is implemented in terms of operator<().
  815. /// \since Crypto++ 8.3
  816. inline bool operator>=(const OID &lhs, const OID &rhs);
  817. /// \brief Append a value to an OID
  818. /// \param lhs the OID
  819. /// \param rhs the value to append
  820. inline OID operator+(const OID &lhs, unsigned long rhs);
  821. /// \brief Print a OID value
  822. /// \param out the output stream
  823. /// \param oid the OID
  824. inline std::ostream& operator<<(std::ostream& out, const OID &oid);
  825. #else
  826. inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  827. {return lhs.m_values == rhs.m_values;}
  828. inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  829. {return lhs.m_values != rhs.m_values;}
  830. inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  831. {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
  832. inline bool operator>(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  833. {return ! (lhs<rhs || lhs==rhs);}
  834. inline bool operator<=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  835. {return lhs<rhs || lhs==rhs;}
  836. inline bool operator>=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  837. {return ! (lhs<rhs);}
  838. inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
  839. {return ::CryptoPP::OID(lhs)+=rhs;}
  840. inline std::ostream& operator<<(std::ostream& out, const OID &oid)
  841. { return oid.Print(out); }
  842. #endif
  843. NAMESPACE_END
  844. // Issue 340
  845. #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
  846. # pragma GCC diagnostic pop
  847. #endif
  848. #endif