asn.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  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. std::vector<word32> m_values;
  297. private:
  298. static void EncodeValue(BufferedTransformation &bt, word32 v);
  299. static size_t DecodeValue(BufferedTransformation &bt, word32 &v);
  300. };
  301. /// \brief ASN.1 encoded object filter
  302. class EncodedObjectFilter : public Filter
  303. {
  304. public:
  305. 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};
  306. enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state;
  307. virtual ~EncodedObjectFilter() {}
  308. /// \brief Construct an EncodedObjectFilter
  309. /// \param attachment a BufferedTrasformation to attach to this object
  310. /// \param nObjects the number of objects
  311. /// \param flags bitwise OR of EncodedObjectFilter::Flag
  312. EncodedObjectFilter(BufferedTransformation *attachment = NULLPTR, unsigned int nObjects = 1, word32 flags = 0);
  313. /// \brief Input a byte buffer for processing
  314. /// \param inString the byte buffer to process
  315. /// \param length the size of the string, in bytes
  316. void Put(const byte *inString, size_t length);
  317. unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;}
  318. unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];}
  319. private:
  320. BufferedTransformation & CurrentTarget();
  321. ByteQueue m_queue;
  322. std::vector<unsigned int> m_positions;
  323. lword m_lengthRemaining;
  324. word32 m_nObjects, m_nCurrentObject, m_level, m_flags;
  325. byte m_id;
  326. };
  327. /// \brief BER General Decoder
  328. class CRYPTOPP_DLL BERGeneralDecoder : public Store
  329. {
  330. public:
  331. /// \brief Default ASN.1 tag
  332. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  333. virtual ~BERGeneralDecoder();
  334. /// \brief Construct an ASN.1 decoder
  335. /// \param inQueue input byte queue
  336. /// \details BERGeneralDecoder uses DefaultTag
  337. explicit BERGeneralDecoder(BufferedTransformation &inQueue);
  338. /// \brief Construct an ASN.1 decoder
  339. /// \param inQueue input byte queue
  340. /// \param asnTag ASN.1 tag
  341. explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
  342. /// \brief Construct an ASN.1 decoder
  343. /// \param inQueue input byte queue
  344. /// \param asnTag ASN.1 tag
  345. explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
  346. /// \brief Determine length encoding
  347. /// \return true if the ASN.1 object is definite length encoded, false otherwise
  348. bool IsDefiniteLength() const {
  349. return m_definiteLength;
  350. }
  351. /// \brief Determine remaining length
  352. /// \return number of octets that remain to be consumed
  353. /// \details RemainingLength() is only valid if IsDefiniteLength()
  354. /// returns true.
  355. lword RemainingLength() const {
  356. CRYPTOPP_ASSERT(m_definiteLength);
  357. return IsDefiniteLength() ? m_length : 0;
  358. }
  359. /// \brief Determine end of stream
  360. /// \return true if all octets have been consumed, false otherwise
  361. bool EndReached() const;
  362. /// \brief Determine next octet
  363. /// \return next octet in the stream
  364. /// \details PeekByte does not consume the octet.
  365. /// \throw BERDecodeError if there are no octets remaining
  366. byte PeekByte() const;
  367. /// \brief Determine next octet
  368. /// \details CheckByte reads the next byte in the stream and verifies
  369. /// the octet matches b.
  370. /// \throw BERDecodeError if the next octet is not b
  371. void CheckByte(byte b);
  372. /// \brief Transfer bytes to another BufferedTransformation
  373. /// \param target the destination BufferedTransformation
  374. /// \param transferBytes the number of bytes to transfer
  375. /// \param channel the channel on which the transfer should occur
  376. /// \param blocking specifies whether the object should block when
  377. /// processing input
  378. /// \return the number of bytes that remain in the transfer block
  379. /// (i.e., bytes not transferred)
  380. /// \details TransferTo2() removes bytes and moves
  381. /// them to the destination. Transfer begins at the index position
  382. /// in the current stream, and not from an absolute position in the
  383. /// stream.
  384. /// \details transferBytes is an \a IN and \a OUT parameter. When
  385. /// the call is made, transferBytes is the requested size of the
  386. /// transfer. When the call returns, transferBytes is the number
  387. /// of bytes that were transferred.
  388. size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
  389. /// \brief Copy bytes to another BufferedTransformation
  390. /// \param target the destination BufferedTransformation
  391. /// \param begin the 0-based index of the first byte to copy in
  392. /// the stream
  393. /// \param end the 0-based index of the last byte to copy in
  394. /// the stream
  395. /// \param channel the channel on which the transfer should occur
  396. /// \param blocking specifies whether the object should block when
  397. /// processing input
  398. /// \return the number of bytes that remain in the copy block
  399. /// (i.e., bytes not copied)
  400. /// \details CopyRangeTo2 copies bytes to the
  401. /// destination. The bytes are not removed from this object. Copying
  402. /// begins at the index position in the current stream, and not from
  403. /// an absolute position in the stream.
  404. /// \details begin is an \a IN and \a OUT parameter. When the call is
  405. /// made, begin is the starting position of the copy. When the call
  406. /// returns, begin is the position of the first byte that was \a not
  407. /// copied (which may be different than end). begin can be used for
  408. /// subsequent calls to CopyRangeTo2().
  409. size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
  410. /// \brief Signals the end of messages to the object
  411. /// \details Call this to denote end of sequence
  412. void MessageEnd();
  413. protected:
  414. BufferedTransformation &m_inQueue;
  415. lword m_length;
  416. bool m_finished, m_definiteLength;
  417. private:
  418. void Init(byte asnTag);
  419. void StoreInitialize(const NameValuePairs &parameters)
  420. {CRYPTOPP_UNUSED(parameters); CRYPTOPP_ASSERT(false);}
  421. lword ReduceLength(lword delta);
  422. };
  423. /// \brief DER General Encoder
  424. class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
  425. {
  426. public:
  427. /// \brief Default ASN.1 tag
  428. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  429. virtual ~DERGeneralEncoder();
  430. /// \brief Construct an ASN.1 encoder
  431. /// \param outQueue output byte queue
  432. /// \details DERGeneralEncoder uses DefaultTag
  433. explicit DERGeneralEncoder(BufferedTransformation &outQueue);
  434. /// \brief Construct an ASN.1 encoder
  435. /// \param outQueue output byte queue
  436. /// \param asnTag ASN.1 tag
  437. explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag);
  438. /// \brief Construct an ASN.1 encoder
  439. /// \param outQueue output byte queue
  440. /// \param asnTag ASN.1 tag
  441. explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag);
  442. /// \brief Signals the end of messages to the object
  443. /// \details Call this to denote end of sequence
  444. void MessageEnd();
  445. private:
  446. BufferedTransformation &m_outQueue;
  447. byte m_asnTag;
  448. bool m_finished;
  449. };
  450. /// \brief BER Sequence Decoder
  451. class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
  452. {
  453. public:
  454. /// \brief Default ASN.1 tag
  455. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  456. /// \brief Construct an ASN.1 decoder
  457. /// \param inQueue input byte queue
  458. /// \details BERSequenceDecoder uses DefaultTag
  459. explicit BERSequenceDecoder(BufferedTransformation &inQueue)
  460. : BERGeneralDecoder(inQueue, DefaultTag) {}
  461. /// \brief Construct an ASN.1 decoder
  462. /// \param inQueue input byte queue
  463. /// \param asnTag ASN.1 tag
  464. explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag)
  465. : BERGeneralDecoder(inQueue, asnTag) {}
  466. /// \brief Construct an ASN.1 decoder
  467. /// \param inQueue input byte queue
  468. /// \details BERSequenceDecoder uses DefaultTag
  469. explicit BERSequenceDecoder(BERSequenceDecoder &inQueue)
  470. : BERGeneralDecoder(inQueue, DefaultTag) {}
  471. /// \brief Construct an ASN.1 decoder
  472. /// \param inQueue input byte queue
  473. /// \param asnTag ASN.1 tag
  474. explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag)
  475. : BERGeneralDecoder(inQueue, asnTag) {}
  476. };
  477. /// \brief DER Sequence Encoder
  478. class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
  479. {
  480. public:
  481. /// \brief Default ASN.1 tag
  482. enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
  483. /// \brief Construct an ASN.1 encoder
  484. /// \param outQueue output byte queue
  485. /// \details DERSequenceEncoder uses DefaultTag
  486. explicit DERSequenceEncoder(BufferedTransformation &outQueue)
  487. : DERGeneralEncoder(outQueue, DefaultTag) {}
  488. /// \brief Construct an ASN.1 encoder
  489. /// \param outQueue output byte queue
  490. /// \param asnTag ASN.1 tag
  491. explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag)
  492. : DERGeneralEncoder(outQueue, asnTag) {}
  493. /// \brief Construct an ASN.1 encoder
  494. /// \param outQueue output byte queue
  495. /// \details DERSequenceEncoder uses DefaultTag
  496. explicit DERSequenceEncoder(DERSequenceEncoder &outQueue)
  497. : DERGeneralEncoder(outQueue, DefaultTag) {}
  498. /// \brief Construct an ASN.1 encoder
  499. /// \param outQueue output byte queue
  500. /// \param asnTag ASN.1 tag
  501. explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag)
  502. : DERGeneralEncoder(outQueue, asnTag) {}
  503. };
  504. /// \brief BER Set Decoder
  505. class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
  506. {
  507. public:
  508. /// \brief Default ASN.1 tag
  509. enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)};
  510. /// \brief Construct an ASN.1 decoder
  511. /// \param inQueue input byte queue
  512. /// \details BERSetDecoder uses DefaultTag
  513. explicit BERSetDecoder(BufferedTransformation &inQueue)
  514. : BERGeneralDecoder(inQueue, DefaultTag) {}
  515. /// \brief Construct an ASN.1 decoder
  516. /// \param inQueue input byte queue
  517. /// \param asnTag ASN.1 tag
  518. explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag)
  519. : BERGeneralDecoder(inQueue, asnTag) {}
  520. /// \brief Construct an ASN.1 decoder
  521. /// \param inQueue input byte queue
  522. /// \details BERSetDecoder uses DefaultTag
  523. explicit BERSetDecoder(BERSetDecoder &inQueue)
  524. : BERGeneralDecoder(inQueue, DefaultTag) {}
  525. /// \brief Construct an ASN.1 decoder
  526. /// \param inQueue input byte queue
  527. /// \param asnTag ASN.1 tag
  528. explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag)
  529. : BERGeneralDecoder(inQueue, asnTag) {}
  530. };
  531. /// \brief DER Set Encoder
  532. class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
  533. {
  534. public:
  535. /// \brief Default ASN.1 tag
  536. enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)};
  537. /// \brief Construct an ASN.1 encoder
  538. /// \param outQueue output byte queue
  539. /// \details DERSetEncoder uses DefaultTag
  540. explicit DERSetEncoder(BufferedTransformation &outQueue)
  541. : DERGeneralEncoder(outQueue, DefaultTag) {}
  542. /// \brief Construct an ASN.1 encoder
  543. /// \param outQueue output byte queue
  544. /// \param asnTag ASN.1 tag
  545. explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag)
  546. : DERGeneralEncoder(outQueue, asnTag) {}
  547. /// \brief Construct an ASN.1 encoder
  548. /// \param outQueue output byte queue
  549. /// \details DERSetEncoder uses DefaultTag
  550. explicit DERSetEncoder(DERSetEncoder &outQueue)
  551. : DERGeneralEncoder(outQueue, DefaultTag) {}
  552. /// \brief Construct an ASN.1 encoder
  553. /// \param outQueue output byte queue
  554. /// \param asnTag ASN.1 tag
  555. explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag)
  556. : DERGeneralEncoder(outQueue, asnTag) {}
  557. };
  558. /// \brief Optional data encoder and decoder
  559. /// \tparam T class or type
  560. template <class T>
  561. class ASNOptional : public member_ptr<T>
  562. {
  563. public:
  564. /// \brief BER decode optional data
  565. /// \param seqDecoder sequence with the optional ASN.1 data
  566. /// \param tag ASN.1 tag to match as optional data
  567. /// \param mask the mask to apply when matching the tag
  568. /// \sa ASNTag and ASNIdFlag
  569. void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED)
  570. {
  571. byte b;
  572. if (seqDecoder.Peek(b) && (b & mask) == tag)
  573. reset(new T(seqDecoder));
  574. }
  575. /// \brief DER encode optional data
  576. /// \param out BufferedTransformation object
  577. void DEREncode(BufferedTransformation &out)
  578. {
  579. if (this->get() != NULLPTR)
  580. this->get()->DEREncode(out);
  581. }
  582. };
  583. /// \brief Encode and decode ASN.1 objects with additional information
  584. /// \tparam BASE base class or type
  585. /// \details Encodes and decodes public keys, private keys and group
  586. /// parameters with OID identifying the algorithm or scheme.
  587. template <class BASE>
  588. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE
  589. {
  590. public:
  591. /// \brief DER encode ASN.1 object
  592. /// \param bt BufferedTransformation object
  593. /// \details Save() will write the OID associated with algorithm or scheme.
  594. /// In the case of public and private keys, this function writes the
  595. /// subjectPublicKeyInfo and privateKeyInfo parts.
  596. void Save(BufferedTransformation &bt) const
  597. {BEREncode(bt);}
  598. /// \brief BER decode ASN.1 object
  599. /// \param bt BufferedTransformation object
  600. void Load(BufferedTransformation &bt)
  601. {BERDecode(bt);}
  602. };
  603. /// \brief Encodes and decodes subjectPublicKeyInfo
  604. class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial<PublicKey>
  605. {
  606. public:
  607. virtual ~X509PublicKey() {}
  608. void BERDecode(BufferedTransformation &bt);
  609. void DEREncode(BufferedTransformation &bt) const;
  610. /// \brief Retrieves the OID of the algorithm
  611. /// \return OID of the algorithm
  612. virtual OID GetAlgorithmID() const =0;
  613. /// \brief Decode algorithm parameters
  614. /// \param bt BufferedTransformation object
  615. /// \sa BERDecodePublicKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  616. /// 2459, section 7.3.1</A>
  617. virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
  618. {BERDecodeNull(bt); return false;}
  619. /// \brief Encode algorithm parameters
  620. /// \param bt BufferedTransformation object
  621. /// \sa DEREncodePublicKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  622. /// 2459, section 7.3.1</A>
  623. virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
  624. {DEREncodeNull(bt); return false;}
  625. /// \brief Decode subjectPublicKey part of subjectPublicKeyInfo
  626. /// \param bt BufferedTransformation object
  627. /// \param parametersPresent flag indicating if algorithm parameters are present
  628. /// \param size number of octets to read for the parameters, in bytes
  629. /// \details BERDecodePublicKey() the decodes subjectPublicKey part of
  630. /// subjectPublicKeyInfo, without the BIT STRING header.
  631. /// \details When <tt>parametersPresent = true</tt> then BERDecodePublicKey() calls
  632. /// BERDecodeAlgorithmParameters() to parse algorithm parameters.
  633. /// \sa BERDecodeAlgorithmParameters
  634. virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
  635. /// \brief Encode subjectPublicKey part of subjectPublicKeyInfo
  636. /// \param bt BufferedTransformation object
  637. /// \details DEREncodePublicKey() encodes the subjectPublicKey part of
  638. /// subjectPublicKeyInfo, without the BIT STRING header.
  639. /// \sa DEREncodeAlgorithmParameters
  640. virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0;
  641. };
  642. /// \brief Encodes and Decodes privateKeyInfo
  643. class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial<PrivateKey>
  644. {
  645. public:
  646. virtual ~PKCS8PrivateKey() {}
  647. void BERDecode(BufferedTransformation &bt);
  648. void DEREncode(BufferedTransformation &bt) const;
  649. /// \brief Retrieves the OID of the algorithm
  650. /// \return OID of the algorithm
  651. virtual OID GetAlgorithmID() const =0;
  652. /// \brief Decode optional parameters
  653. /// \param bt BufferedTransformation object
  654. /// \sa BERDecodePrivateKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  655. /// 2459, section 7.3.1</A>
  656. virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
  657. {BERDecodeNull(bt); return false;}
  658. /// \brief Encode optional parameters
  659. /// \param bt BufferedTransformation object
  660. /// \sa DEREncodePrivateKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC
  661. /// 2459, section 7.3.1</A>
  662. virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
  663. {DEREncodeNull(bt); return false;}
  664. /// \brief Decode privateKey part of privateKeyInfo
  665. /// \param bt BufferedTransformation object
  666. /// \param parametersPresent flag indicating if algorithm parameters are present
  667. /// \param size number of octets to read for the parameters, in bytes
  668. /// \details BERDecodePrivateKey() the decodes privateKey part of privateKeyInfo,
  669. /// without the OCTET STRING header.
  670. /// \details When <tt>parametersPresent = true</tt> then BERDecodePrivateKey() calls
  671. /// BERDecodeAlgorithmParameters() to parse algorithm parameters.
  672. /// \sa BERDecodeAlgorithmParameters
  673. virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
  674. /// \brief Encode privateKey part of privateKeyInfo
  675. /// \param bt BufferedTransformation object
  676. /// \details DEREncodePrivateKey() encodes the privateKey part of privateKeyInfo,
  677. /// without the OCTET STRING header.
  678. /// \sa DEREncodeAlgorithmParameters
  679. virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0;
  680. /// \brief Decode optional attributes
  681. /// \param bt BufferedTransformation object
  682. /// \details BERDecodeOptionalAttributes() decodes optional attributes including
  683. /// context-specific tag.
  684. /// \sa BERDecodeAlgorithmParameters, DEREncodeOptionalAttributes
  685. /// \note default implementation stores attributes to be output using
  686. /// DEREncodeOptionalAttributes
  687. virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt);
  688. /// \brief Encode optional attributes
  689. /// \param bt BufferedTransformation object
  690. /// \details DEREncodeOptionalAttributes() encodes optional attributes including
  691. /// context-specific tag.
  692. /// \sa BERDecodeAlgorithmParameters
  693. virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const;
  694. protected:
  695. ByteQueue m_optionalAttributes;
  696. };
  697. // ********************************************************
  698. /// \brief DER Encode unsigned value
  699. /// \tparam T class or type
  700. /// \param out BufferedTransformation object
  701. /// \param w unsigned value to encode
  702. /// \param asnTag the ASN.1 identifier
  703. /// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM
  704. template <class T>
  705. size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
  706. {
  707. byte buf[sizeof(w)+1];
  708. unsigned int bc;
  709. if (asnTag == BOOLEAN)
  710. {
  711. buf[sizeof(w)] = w ? 0xff : 0;
  712. bc = 1;
  713. }
  714. else
  715. {
  716. buf[0] = 0;
  717. for (unsigned int i=0; i<sizeof(w); i++)
  718. buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
  719. bc = sizeof(w);
  720. while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
  721. --bc;
  722. if (buf[sizeof(w)+1-bc] & 0x80)
  723. ++bc;
  724. }
  725. out.Put(asnTag);
  726. size_t lengthBytes = DERLengthEncode(out, bc);
  727. out.Put(buf+sizeof(w)+1-bc, bc);
  728. return 1+lengthBytes+bc;
  729. }
  730. /// \brief BER Decode unsigned value
  731. /// \tparam T fundamental C++ type
  732. /// \param in BufferedTransformation object
  733. /// \param w the decoded value
  734. /// \param asnTag the ASN.1 identifier
  735. /// \param minValue the minimum expected value
  736. /// \param maxValue the maximum expected value
  737. /// \throw BERDecodeErr() if the value cannot be parsed or the decoded value is not within range.
  738. /// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM
  739. template <class T>
  740. void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
  741. T minValue = 0, T maxValue = T(0xffffffff))
  742. {
  743. byte b;
  744. if (!in.Get(b) || b != asnTag)
  745. BERDecodeError();
  746. size_t bc;
  747. bool definite = BERLengthDecode(in, bc);
  748. if (!definite)
  749. BERDecodeError();
  750. if (bc > in.MaxRetrievable()) // Issue 346
  751. BERDecodeError();
  752. if (asnTag == BOOLEAN && bc != 1) // X.690, 8.2.1
  753. BERDecodeError();
  754. if ((asnTag == INTEGER || asnTag == ENUMERATED) && bc == 0) // X.690, 8.3.1 and 8.4
  755. BERDecodeError();
  756. SecByteBlock buf(bc);
  757. if (bc != in.Get(buf, bc))
  758. BERDecodeError();
  759. // This consumes leading 0 octets. According to X.690, 8.3.2, it could be non-conforming behavior.
  760. // X.690, 8.3.2 says "the bits of the first octet and bit 8 of the second octet ... (a) shall
  761. // not all be ones and (b) shall not all be zeros ... These rules ensure that an integer value
  762. // is always encoded in the smallest possible number of octet".
  763. // We invented AER (Alternate Encoding Rules), which is more relaxed than BER, CER, and DER.
  764. const byte *ptr = buf;
  765. while (bc > sizeof(w) && *ptr == 0)
  766. {
  767. bc--;
  768. ptr++;
  769. }
  770. if (bc > sizeof(w))
  771. BERDecodeError();
  772. w = 0;
  773. for (unsigned int i=0; i<bc; i++)
  774. w = (w << 8) | ptr[i];
  775. if (w < minValue || w > maxValue)
  776. BERDecodeError();
  777. }
  778. #ifdef CRYPTOPP_DOXYGEN_PROCESSING
  779. /// \brief Compare two OIDs for equality
  780. /// \param lhs the first OID
  781. /// \param rhs the second OID
  782. /// \return true if the OIDs are equal, false otherwise
  783. inline bool operator==(const OID &lhs, const OID &rhs);
  784. /// \brief Compare two OIDs for inequality
  785. /// \param lhs the first OID
  786. /// \param rhs the second OID
  787. /// \return true if the OIDs are not equal, false otherwise
  788. inline bool operator!=(const OID &lhs, const OID &rhs);
  789. /// \brief Compare two OIDs for ordering
  790. /// \param lhs the first OID
  791. /// \param rhs the second OID
  792. /// \return true if the first OID is less than the second OID, false otherwise
  793. /// \details operator<() calls std::lexicographical_compare() on each element in the array of values.
  794. inline bool operator<(const OID &lhs, const OID &rhs);
  795. /// \brief Compare two OIDs for ordering
  796. /// \param lhs the first OID
  797. /// \param rhs the second OID
  798. /// \return true if the first OID is less than or equal to the second OID, false otherwise
  799. /// \details operator<=() is implemented in terms of operator==() and operator<().
  800. /// \since Crypto++ 8.3
  801. inline bool operator<=(const OID &lhs, const OID &rhs);
  802. /// \brief Compare two OIDs for ordering
  803. /// \param lhs the first OID
  804. /// \param rhs the second OID
  805. /// \return true if the first OID is greater than or equal to the second OID, false otherwise
  806. /// \details operator>=() is implemented in terms of operator<().
  807. /// \since Crypto++ 8.3
  808. inline bool operator>=(const OID &lhs, const OID &rhs);
  809. /// \brief Append a value to an OID
  810. /// \param lhs the OID
  811. /// \param rhs the value to append
  812. inline OID operator+(const OID &lhs, unsigned long rhs);
  813. /// \brief Print a OID value
  814. /// \param out the output stream
  815. /// \param oid the OID
  816. inline std::ostream& operator<<(std::ostream& out, const OID &oid)
  817. { return oid.Print(out); }
  818. #else
  819. inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  820. {return lhs.m_values == rhs.m_values;}
  821. inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  822. {return lhs.m_values != rhs.m_values;}
  823. inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  824. {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
  825. inline bool operator<=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  826. {return lhs<rhs || lhs==rhs;}
  827. inline bool operator>=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
  828. {return ! (lhs<rhs);}
  829. inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
  830. {return ::CryptoPP::OID(lhs)+=rhs;}
  831. inline std::ostream& operator<<(std::ostream& out, const OID &oid)
  832. { return oid.Print(out); }
  833. #endif
  834. NAMESPACE_END
  835. // Issue 340
  836. #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
  837. # pragma GCC diagnostic pop
  838. #endif
  839. #endif