Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:54

0001 // asn.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file asn.h

0004 /// \brief Classes and functions for working with ANS.1 objects

0005 
0006 #ifndef CRYPTOPP_ASN_H
0007 #define CRYPTOPP_ASN_H
0008 
0009 #include "cryptlib.h"
0010 #include "filters.h"
0011 #include "smartptr.h"
0012 #include "stdcpp.h"
0013 #include "queue.h"
0014 #include "misc.h"
0015 
0016 #include <iosfwd>
0017 
0018 // Issue 340

0019 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
0020 # pragma GCC diagnostic push
0021 # pragma GCC diagnostic ignored "-Wconversion"
0022 # pragma GCC diagnostic ignored "-Wsign-conversion"
0023 #endif
0024 
0025 NAMESPACE_BEGIN(CryptoPP)
0026 
0027 /// \brief ASN.1 types

0028 /// \note These tags are not complete

0029 enum ASNTag
0030 {
0031     /// \brief ASN.1 Boolean

0032     BOOLEAN             = 0x01,
0033     /// \brief ASN.1 Integer

0034     INTEGER             = 0x02,
0035     /// \brief ASN.1 Bit string

0036     BIT_STRING          = 0x03,
0037     /// \brief ASN.1 Octet string

0038     OCTET_STRING        = 0x04,
0039     /// \brief ASN.1 Null

0040     TAG_NULL            = 0x05,
0041     /// \brief ASN.1 Object identifier

0042     OBJECT_IDENTIFIER   = 0x06,
0043     /// \brief ASN.1 Object descriptor

0044     OBJECT_DESCRIPTOR   = 0x07,
0045     /// \brief ASN.1 External reference

0046     EXTERNAL            = 0x08,
0047     /// \brief ASN.1 Real integer

0048     REAL                = 0x09,
0049     /// \brief ASN.1 Enumerated value

0050     ENUMERATED          = 0x0a,
0051     /// \brief ASN.1 UTF-8 string

0052     UTF8_STRING         = 0x0c,
0053     /// \brief ASN.1 Sequence

0054     SEQUENCE            = 0x10,
0055     /// \brief ASN.1 Set

0056     SET                 = 0x11,
0057     /// \brief ASN.1 Numeric string

0058     NUMERIC_STRING      = 0x12,
0059     /// \brief ASN.1 Printable string

0060     PRINTABLE_STRING    = 0x13,
0061     /// \brief ASN.1 T61 string

0062     T61_STRING          = 0x14,
0063     /// \brief ASN.1 Videotext string

0064     VIDEOTEXT_STRING    = 0x15,
0065     /// \brief ASN.1 IA5 string

0066     IA5_STRING          = 0x16,
0067     /// \brief ASN.1 UTC time

0068     UTC_TIME            = 0x17,
0069     /// \brief ASN.1 Generalized time

0070     GENERALIZED_TIME    = 0x18,
0071     /// \brief ASN.1 Graphic string

0072     GRAPHIC_STRING      = 0x19,
0073     /// \brief ASN.1 Visible string

0074     VISIBLE_STRING      = 0x1a,
0075     /// \brief ASN.1 General string

0076     GENERAL_STRING      = 0x1b,
0077     /// \brief ASN.1 Universal string

0078     UNIVERSAL_STRING    = 0x1c,
0079     /// \brief ASN.1 BMP string

0080     BMP_STRING          = 0x1e
0081 };
0082 
0083 /// \brief ASN.1 flags

0084 /// \note These flags are not complete

0085 enum ASNIdFlag
0086 {
0087     /// \brief ASN.1 Universal class

0088     UNIVERSAL           = 0x00,
0089     // DATA           = 0x01,

0090     // HEADER           = 0x02,

0091     /// \brief ASN.1 Primitive flag

0092     PRIMITIVE           = 0x00,
0093     /// \brief ASN.1 Constructed flag

0094     CONSTRUCTED         = 0x20,
0095     /// \brief ASN.1 Application class

0096     APPLICATION         = 0x40,
0097     /// \brief ASN.1 Context specific class

0098     CONTEXT_SPECIFIC    = 0x80,
0099     /// \brief ASN.1 Private class

0100     PRIVATE             = 0xc0
0101 };
0102 
0103 /// \brief Raises a BERDecodeErr

0104 inline void BERDecodeError() {throw BERDecodeErr();}
0105 
0106 /// \brief Exception thrown when an unknown object identifier is encountered

0107 class CRYPTOPP_DLL UnknownOID : public BERDecodeErr
0108 {
0109 public:
0110     /// \brief Construct an UnknownOID

0111     UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {}
0112     /// \brief Construct an UnknownOID

0113     /// \param err error message to use for the exception

0114     UnknownOID(const char *err) : BERDecodeErr(err) {}
0115 };
0116 
0117 /// \brief DER encode a length

0118 /// \param bt BufferedTransformation object for writing

0119 /// \param length the size to encode

0120 /// \return the number of octets used for the encoding

0121 CRYPTOPP_DLL size_t CRYPTOPP_API DERLengthEncode(BufferedTransformation &bt, lword length);
0122 
0123 /// \brief BER decode a length

0124 /// \param bt BufferedTransformation object for reading

0125 /// \param length the decoded size

0126 /// \return true if the value was decoded

0127 /// \throw BERDecodeError if the value fails to decode or is too large for size_t

0128 /// \details BERLengthDecode() returns false if the encoding is indefinite length.

0129 CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &bt, size_t &length);
0130 
0131 /// \brief DER encode NULL

0132 /// \param bt BufferedTransformation object for writing

0133 CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &bt);
0134 
0135 /// \brief BER decode NULL

0136 /// \param bt BufferedTransformation object for reading

0137 CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &bt);
0138 
0139 /// \brief DER encode octet string

0140 /// \param bt BufferedTransformation object for writing

0141 /// \param str the string to encode

0142 /// \param strLen the length of the string

0143 /// \return the number of octets used for the encoding

0144 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen);
0145 
0146 /// \brief DER encode octet string

0147 /// \param bt BufferedTransformation object for reading

0148 /// \param str the string to encode

0149 /// \return the number of octets used for the encoding

0150 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str);
0151 
0152 /// \brief BER decode octet string

0153 /// \param bt BufferedTransformation object for reading

0154 /// \param str the decoded string

0155 /// \return the number of octets used for the encoding

0156 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str);
0157 
0158 /// \brief BER decode octet string

0159 /// \param bt BufferedTransformation object for reading

0160 /// \param str the decoded string

0161 /// \return the number of octets used for the encoding

0162 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str);
0163 
0164 /// \brief DER encode text string

0165 /// \param bt BufferedTransformation object for writing

0166 /// \param str the string to encode

0167 /// \param strLen the length of the string, in bytes

0168 /// \param asnTag the ASN.1 identifier

0169 /// \return the number of octets used for the encoding

0170 /// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING

0171 /// \since Crypto++ 8.3

0172 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const byte* str, size_t strLen, byte asnTag);
0173 
0174 /// \brief DER encode text string

0175 /// \param bt BufferedTransformation object for writing

0176 /// \param str the string to encode

0177 /// \param asnTag the ASN.1 identifier

0178 /// \return the number of octets used for the encoding

0179 /// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING

0180 /// \since Crypto++ 8.3

0181 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag);
0182 
0183 /// \brief DER encode text string

0184 /// \param bt BufferedTransformation object for writing

0185 /// \param str the string to encode

0186 /// \param asnTag the ASN.1 identifier

0187 /// \return the number of octets used for the encoding

0188 /// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING

0189 /// \since Crypto++ 6.0

0190 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag);
0191 
0192 /// \brief BER decode text string

0193 /// \param bt BufferedTransformation object for reading

0194 /// \param str the string to decode

0195 /// \param asnTag the ASN.1 identifier

0196 /// \details BERDecodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING

0197 /// \since Crypto++ 8.3

0198 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &bt, SecByteBlock &str, byte asnTag);
0199 
0200 /// \brief BER decode text string

0201 /// \param bt BufferedTransformation object for reading

0202 /// \param str the string to decode

0203 /// \param asnTag the ASN.1 identifier

0204 /// \details BERDecodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING

0205 /// \since Crypto++ 6.0

0206 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag);
0207 
0208 /// \brief DER encode date

0209 /// \param bt BufferedTransformation object for writing

0210 /// \param str the date to encode

0211 /// \param asnTag the ASN.1 identifier

0212 /// \return the number of octets used for the encoding

0213 /// \details BERDecodeDate() can be used for UTC_TIME and GENERALIZED_TIME

0214 /// \since Crypto++ 8.3

0215 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeDate(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag);
0216 
0217 /// \brief BER decode date

0218 /// \param bt BufferedTransformation object for reading

0219 /// \param str the date to decode

0220 /// \param asnTag the ASN.1 identifier

0221 /// \details BERDecodeDate() can be used for UTC_TIME and GENERALIZED_TIME

0222 /// \since Crypto++ 8.3

0223 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeDate(BufferedTransformation &bt, SecByteBlock &str, byte asnTag);
0224 
0225 /// \brief DER encode bit string

0226 /// \param bt BufferedTransformation object for writing

0227 /// \param str the string to encode

0228 /// \param strLen the length of the string

0229 /// \param unusedBits the number of unused bits

0230 /// \return the number of octets used for the encoding

0231 /// \details The caller is responsible for shifting octets if unusedBits is

0232 ///  not 0. For example, to DER encode a web server X.509 key usage, the 101b

0233 ///  bit mask is often used (digitalSignature and keyEncipherment). In this

0234 ///  case <tt>str</tt> is one octet with a value=0xa0 and unusedBits=5. The

0235 ///  value 0xa0 is <tt>101b << 5</tt>.

0236 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0);
0237 
0238 /// \brief DER decode bit string

0239 /// \param bt BufferedTransformation object for reading

0240 /// \param str the decoded string

0241 /// \param unusedBits the number of unused bits

0242 /// \details The caller is responsible for shifting octets if unusedBits is

0243 ///  not 0. For example, to DER encode a web server X.509 key usage, the 101b

0244 ///  bit mask is often used (digitalSignature and keyEncipherment). In this

0245 ///  case <tt>str</tt> is one octet with a value=0xa0 and unusedBits=5. The

0246 ///  value 0xa0 is <tt>101b << 5</tt>.

0247 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits);
0248 
0249 /// \brief BER decode and DER re-encode

0250 /// \param bt BufferedTransformation object for writing

0251 /// \param dest BufferedTransformation object

0252 CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &bt, BufferedTransformation &dest);
0253 
0254 /// \brief BER decode size

0255 /// \param bt BufferedTransformation object for reading

0256 /// \return the length of the ASN.1 value, in bytes

0257 /// \details BERDecodePeekLength() determines the length of a value without

0258 ///  consuming octets in the stream. The stream must use definite length encoding.

0259 ///  If indefinite length encoding is used or an error occurs, then 0 is returned.

0260 /// \since Crypto++ 8.3

0261 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodePeekLength(const BufferedTransformation &bt);
0262 
0263 /// \brief Object Identifier

0264 class CRYPTOPP_DLL OID
0265 {
0266 public:
0267     virtual ~OID() {}
0268 
0269     /// \brief Construct an OID

0270     OID() {}
0271 
0272     /// \brief Construct an OID

0273     /// \param v value to initialize the OID

0274     OID(word32 v) : m_values(1, v) {}
0275 
0276     /// \brief Construct an OID

0277     /// \param bt BufferedTransformation object

0278     OID(BufferedTransformation &bt) {
0279         BERDecode(bt);
0280     }
0281 
0282     /// \brief Append a value to an OID

0283     /// \param rhs the value to append

0284     inline OID & operator+=(word32 rhs) {
0285         m_values.push_back(rhs); return *this;
0286     }
0287 
0288     /// \brief DER encode this OID

0289     /// \param bt BufferedTransformation object

0290     void DEREncode(BufferedTransformation &bt) const;
0291 
0292     /// \brief BER decode an OID

0293     /// \param bt BufferedTransformation object

0294     void BERDecode(BufferedTransformation &bt);
0295 
0296     /// \brief BER decode an OID

0297     /// \param bt BufferedTransformation object

0298     /// \throw BERDecodeErr() if decoded value doesn't match an expected OID

0299     /// \details BERDecodeAndCheck() can be used to parse an OID and verify it matches an expected.

0300     /// <pre>

0301     ///   BERSequenceDecoder key(bt);

0302     ///   ...

0303     ///   BERSequenceDecoder algorithm(key);

0304     ///   GetAlgorithmID().BERDecodeAndCheck(algorithm);

0305     /// </pre>

0306     void BERDecodeAndCheck(BufferedTransformation &bt) const;
0307 
0308     /// \brief Determine if OID is empty

0309     /// \return true if OID has 0 elements, false otherwise

0310     /// \since Crypto++ 8.0

0311     bool Empty() const {
0312         return m_values.empty();
0313     }
0314 
0315     /// \brief Retrieve OID value array

0316     /// \return OID value vector

0317     /// \since Crypto++ 8.0

0318     const std::vector<word32>& GetValues() const {
0319         return m_values;
0320     }
0321 
0322     /// \brief Print an OID

0323     /// \param out ostream object

0324     /// \return ostream reference

0325     /// \details Print() writes the OID in a customary format, like

0326     ///  1.2.840.113549.1.1.11. The caller is reposnsible to convert the

0327     ///  OID to a friendly name, like sha256WithRSAEncryption.

0328     /// \since Crypto++ 8.3

0329     std::ostream& Print(std::ostream& out) const;
0330 
0331 protected:
0332     friend bool operator==(const OID &lhs, const OID &rhs);
0333     friend bool operator!=(const OID &lhs, const OID &rhs);
0334     friend bool operator<(const OID &lhs, const OID &rhs);
0335     friend bool operator<=(const OID &lhs, const OID &rhs);
0336     friend bool operator>=(const OID &lhs, const OID &rhs);
0337 
0338     std::vector<word32> m_values;
0339 
0340 private:
0341     static void EncodeValue(BufferedTransformation &bt, word32 v);
0342     static size_t DecodeValue(BufferedTransformation &bt, word32 &v);
0343 };
0344 
0345 /// \brief ASN.1 encoded object filter

0346 class EncodedObjectFilter : public Filter
0347 {
0348 public:
0349     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};
0350     enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state;
0351 
0352     virtual ~EncodedObjectFilter() {}
0353 
0354     /// \brief Construct an EncodedObjectFilter

0355     /// \param attachment a BufferedTrasformation to attach to this object

0356     /// \param nObjects the number of objects

0357     /// \param flags bitwise OR of EncodedObjectFilter::Flag

0358     EncodedObjectFilter(BufferedTransformation *attachment = NULLPTR, unsigned int nObjects = 1, word32 flags = 0);
0359 
0360     /// \brief Input a byte buffer for processing

0361     /// \param inString the byte buffer to process

0362     /// \param length the size of the string, in bytes

0363     void Put(const byte *inString, size_t length);
0364 
0365     unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;}
0366     unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];}
0367 
0368 private:
0369     BufferedTransformation & CurrentTarget();
0370 
0371     ByteQueue m_queue;
0372     std::vector<unsigned int> m_positions;
0373     lword m_lengthRemaining;
0374     word32 m_nObjects, m_nCurrentObject, m_level, m_flags;
0375     byte m_id;
0376 };
0377 
0378 /// \brief BER General Decoder

0379 class CRYPTOPP_DLL BERGeneralDecoder : public Store
0380 {
0381 public:
0382     /// \brief Default ASN.1 tag

0383     enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
0384 
0385     virtual ~BERGeneralDecoder();
0386 
0387     /// \brief Construct an ASN.1 decoder

0388     /// \param inQueue input byte queue

0389     /// \details BERGeneralDecoder uses DefaultTag

0390     explicit BERGeneralDecoder(BufferedTransformation &inQueue);
0391 
0392     /// \brief Construct an ASN.1 decoder

0393     /// \param inQueue input byte queue

0394     /// \param asnTag ASN.1 tag

0395     explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
0396 
0397     /// \brief Construct an ASN.1 decoder

0398     /// \param inQueue input byte queue

0399     /// \param asnTag ASN.1 tag

0400     explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
0401 
0402     /// \brief Determine length encoding

0403     /// \return true if the ASN.1 object is definite length encoded, false otherwise

0404     bool IsDefiniteLength() const {
0405         return m_definiteLength;
0406     }
0407 
0408     /// \brief Determine remaining length

0409     /// \return number of octets that remain to be consumed

0410     /// \details RemainingLength() is only valid if IsDefiniteLength()

0411     ///  returns true.

0412     lword RemainingLength() const {
0413         CRYPTOPP_ASSERT(m_definiteLength);
0414         return IsDefiniteLength() ? m_length : 0;
0415     }
0416 
0417     /// \brief Determine end of stream

0418     /// \return true if all octets have been consumed, false otherwise

0419     bool EndReached() const;
0420 
0421     /// \brief Determine next octet

0422     /// \return next octet in the stream

0423     /// \details PeekByte does not consume the octet.

0424     /// \throw BERDecodeError if there are no octets remaining

0425     byte PeekByte() const;
0426 
0427     /// \brief Determine next octet

0428     /// \details CheckByte reads the next byte in the stream and verifies

0429     ///  the octet matches b.

0430     /// \throw BERDecodeError if the next octet is not b

0431     void CheckByte(byte b);
0432 
0433     /// \brief Transfer bytes to another BufferedTransformation

0434     /// \param target the destination BufferedTransformation

0435     /// \param transferBytes the number of bytes to transfer

0436     /// \param channel the channel on which the transfer should occur

0437     /// \param blocking specifies whether the object should block when

0438     ///  processing input

0439     /// \return the number of bytes that remain in the transfer block

0440     ///  (i.e., bytes not transferred)

0441     /// \details TransferTo2() removes bytes and moves

0442     ///  them to the destination. Transfer begins at the index position

0443     ///  in the current stream, and not from an absolute position in the

0444     ///  stream.

0445     /// \details transferBytes is an \a IN and \a OUT parameter. When

0446     ///  the call is made, transferBytes is the requested size of the

0447     ///  transfer. When the call returns, transferBytes is the number

0448     ///  of bytes that were transferred.

0449     size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
0450 
0451     /// \brief Copy bytes to another BufferedTransformation

0452     /// \param target the destination BufferedTransformation

0453     /// \param begin the 0-based index of the first byte to copy in

0454     ///  the stream

0455     /// \param end the 0-based index of the last byte to copy in

0456     ///  the stream

0457     /// \param channel the channel on which the transfer should occur

0458     /// \param blocking specifies whether the object should block when

0459     ///  processing input

0460     /// \return the number of bytes that remain in the copy block

0461     ///  (i.e., bytes not copied)

0462     /// \details CopyRangeTo2 copies bytes to the

0463     ///  destination. The bytes are not removed from this object. Copying

0464     ///  begins at the index position in the current stream, and not from

0465     ///  an absolute position in the stream.

0466     /// \details begin is an \a IN and \a OUT parameter. When the call is

0467     ///  made, begin is the starting position of the copy. When the call

0468     ///  returns, begin is the position of the first byte that was \a not

0469     ///  copied (which may be different than end). begin can be used for

0470     ///  subsequent calls to CopyRangeTo2().

0471     size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
0472 
0473     /// \brief Signals the end of messages to the object

0474     /// \details Call this to denote end of sequence

0475     void MessageEnd();
0476 
0477 protected:
0478     BufferedTransformation &m_inQueue;
0479     lword m_length;
0480     bool m_finished, m_definiteLength;
0481 
0482 private:
0483     void Init(byte asnTag);
0484     void StoreInitialize(const NameValuePairs &parameters)
0485         {CRYPTOPP_UNUSED(parameters); CRYPTOPP_ASSERT(false);}
0486     lword ReduceLength(lword delta);
0487 };
0488 
0489 /// \brief DER General Encoder

0490 class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
0491 {
0492 public:
0493     /// \brief Default ASN.1 tag

0494     enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
0495 
0496     virtual ~DERGeneralEncoder();
0497 
0498     /// \brief Construct an ASN.1 encoder

0499     /// \param outQueue output byte queue

0500     /// \details DERGeneralEncoder uses DefaultTag

0501     explicit DERGeneralEncoder(BufferedTransformation &outQueue);
0502 
0503     /// \brief Construct an ASN.1 encoder

0504     /// \param outQueue output byte queue

0505     /// \param asnTag ASN.1 tag

0506     explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag);
0507 
0508     /// \brief Construct an ASN.1 encoder

0509     /// \param outQueue output byte queue

0510     /// \param asnTag ASN.1 tag

0511     explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag);
0512 
0513     /// \brief Signals the end of messages to the object

0514     /// \details Call this to denote end of sequence

0515     void MessageEnd();
0516 
0517 private:
0518     BufferedTransformation &m_outQueue;
0519     byte m_asnTag;
0520     bool m_finished;
0521 };
0522 
0523 /// \brief BER Sequence Decoder

0524 class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
0525 {
0526 public:
0527     /// \brief Default ASN.1 tag

0528     enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
0529 
0530     /// \brief Construct an ASN.1 decoder

0531     /// \param inQueue input byte queue

0532     /// \details BERSequenceDecoder uses DefaultTag

0533     explicit BERSequenceDecoder(BufferedTransformation &inQueue)
0534         : BERGeneralDecoder(inQueue, DefaultTag) {}
0535 
0536     /// \brief Construct an ASN.1 decoder

0537     /// \param inQueue input byte queue

0538     /// \param asnTag ASN.1 tag

0539     explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag)
0540         : BERGeneralDecoder(inQueue, asnTag) {}
0541 
0542     /// \brief Construct an ASN.1 decoder

0543     /// \param inQueue input byte queue

0544     /// \details BERSequenceDecoder uses DefaultTag

0545     explicit BERSequenceDecoder(BERSequenceDecoder &inQueue)
0546         : BERGeneralDecoder(inQueue, DefaultTag) {}
0547 
0548     /// \brief Construct an ASN.1 decoder

0549     /// \param inQueue input byte queue

0550     /// \param asnTag ASN.1 tag

0551     explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag)
0552         : BERGeneralDecoder(inQueue, asnTag) {}
0553 };
0554 
0555 /// \brief DER Sequence Encoder

0556 class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
0557 {
0558 public:
0559     /// \brief Default ASN.1 tag

0560     enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)};
0561 
0562     /// \brief Construct an ASN.1 encoder

0563     /// \param outQueue output byte queue

0564     /// \details DERSequenceEncoder uses DefaultTag

0565     explicit DERSequenceEncoder(BufferedTransformation &outQueue)
0566         : DERGeneralEncoder(outQueue, DefaultTag) {}
0567 
0568     /// \brief Construct an ASN.1 encoder

0569     /// \param outQueue output byte queue

0570     /// \param asnTag ASN.1 tag

0571     explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag)
0572         : DERGeneralEncoder(outQueue, asnTag) {}
0573 
0574     /// \brief Construct an ASN.1 encoder

0575     /// \param outQueue output byte queue

0576     /// \details DERSequenceEncoder uses DefaultTag

0577     explicit DERSequenceEncoder(DERSequenceEncoder &outQueue)
0578         : DERGeneralEncoder(outQueue, DefaultTag) {}
0579 
0580     /// \brief Construct an ASN.1 encoder

0581     /// \param outQueue output byte queue

0582     /// \param asnTag ASN.1 tag

0583     explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag)
0584         : DERGeneralEncoder(outQueue, asnTag) {}
0585 };
0586 
0587 /// \brief BER Set Decoder

0588 class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
0589 {
0590 public:
0591     /// \brief Default ASN.1 tag

0592     enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)};
0593 
0594     /// \brief Construct an ASN.1 decoder

0595     /// \param inQueue input byte queue

0596     /// \details BERSetDecoder uses DefaultTag

0597     explicit BERSetDecoder(BufferedTransformation &inQueue)
0598         : BERGeneralDecoder(inQueue, DefaultTag) {}
0599 
0600     /// \brief Construct an ASN.1 decoder

0601     /// \param inQueue input byte queue

0602     /// \param asnTag ASN.1 tag

0603     explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag)
0604         : BERGeneralDecoder(inQueue, asnTag) {}
0605 
0606     /// \brief Construct an ASN.1 decoder

0607     /// \param inQueue input byte queue

0608     /// \details BERSetDecoder uses DefaultTag

0609     explicit BERSetDecoder(BERSetDecoder &inQueue)
0610         : BERGeneralDecoder(inQueue, DefaultTag) {}
0611 
0612     /// \brief Construct an ASN.1 decoder

0613     /// \param inQueue input byte queue

0614     /// \param asnTag ASN.1 tag

0615     explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag)
0616         : BERGeneralDecoder(inQueue, asnTag) {}
0617 };
0618 
0619 /// \brief DER Set Encoder

0620 class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
0621 {
0622 public:
0623     /// \brief Default ASN.1 tag

0624     enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)};
0625 
0626     /// \brief Construct an ASN.1 encoder

0627     /// \param outQueue output byte queue

0628     /// \details DERSetEncoder uses DefaultTag

0629     explicit DERSetEncoder(BufferedTransformation &outQueue)
0630         : DERGeneralEncoder(outQueue, DefaultTag) {}
0631 
0632     /// \brief Construct an ASN.1 encoder

0633     /// \param outQueue output byte queue

0634     /// \param asnTag ASN.1 tag

0635     explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag)
0636         : DERGeneralEncoder(outQueue, asnTag) {}
0637 
0638     /// \brief Construct an ASN.1 encoder

0639     /// \param outQueue output byte queue

0640     /// \details DERSetEncoder uses DefaultTag

0641     explicit DERSetEncoder(DERSetEncoder &outQueue)
0642         : DERGeneralEncoder(outQueue, DefaultTag) {}
0643 
0644     /// \brief Construct an ASN.1 encoder

0645     /// \param outQueue output byte queue

0646     /// \param asnTag ASN.1 tag

0647     explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag)
0648         : DERGeneralEncoder(outQueue, asnTag) {}
0649 };
0650 
0651 /// \brief Optional data encoder and decoder

0652 /// \tparam T class or type

0653 template <class T>
0654 class ASNOptional : public member_ptr<T>
0655 {
0656 public:
0657     /// \brief BER decode optional data

0658     /// \param seqDecoder sequence with the optional ASN.1 data

0659     /// \param tag ASN.1 tag to match as optional data

0660     /// \param mask the mask to apply when matching the tag

0661     /// \sa ASNTag and ASNIdFlag

0662     void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED)
0663     {
0664         byte b;
0665         if (seqDecoder.Peek(b) && (b & mask) == tag)
0666             reset(new T(seqDecoder));
0667     }
0668 
0669     /// \brief DER encode optional data

0670     /// \param out BufferedTransformation object

0671     void DEREncode(BufferedTransformation &out)
0672     {
0673         if (this->get() != NULLPTR)
0674             this->get()->DEREncode(out);
0675     }
0676 };
0677 
0678 /// \brief Encode and decode ASN.1 objects with additional information

0679 /// \tparam BASE base class or type

0680 /// \details Encodes and decodes public keys, private keys and group

0681 ///   parameters with OID identifying the algorithm or scheme.

0682 template <class BASE>
0683 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE
0684 {
0685 public:
0686     /// \brief DER encode ASN.1 object

0687     /// \param bt BufferedTransformation object

0688     /// \details Save() will write the OID associated with algorithm or scheme.

0689     ///   In the case of public and private keys, this function writes the

0690     ///   subjectPublicKeyInfo and privateKeyInfo parts.

0691     void Save(BufferedTransformation &bt) const
0692         {BEREncode(bt);}
0693 
0694     /// \brief BER decode ASN.1 object

0695     /// \param bt BufferedTransformation object

0696     void Load(BufferedTransformation &bt)
0697         {BERDecode(bt);}
0698 };
0699 
0700 /// \brief Encodes and decodes subjectPublicKeyInfo

0701 class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial<PublicKey>
0702 {
0703 public:
0704     virtual ~X509PublicKey() {}
0705 
0706     void BERDecode(BufferedTransformation &bt);
0707     void DEREncode(BufferedTransformation &bt) const;
0708 
0709     /// \brief Retrieves the OID of the algorithm

0710     /// \return OID of the algorithm

0711     virtual OID GetAlgorithmID() const =0;
0712 
0713     /// \brief Decode algorithm parameters

0714     /// \param bt BufferedTransformation object

0715     /// \sa BERDecodePublicKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC

0716     ///  2459, section 7.3.1</A>

0717     virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
0718         {BERDecodeNull(bt); return false;}
0719 
0720     /// \brief Encode algorithm parameters

0721     /// \param bt BufferedTransformation object

0722     /// \sa DEREncodePublicKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC

0723     ///  2459, section 7.3.1</A>

0724     virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
0725         {DEREncodeNull(bt); return false;}
0726 
0727     /// \brief Decode subjectPublicKey part of subjectPublicKeyInfo

0728     /// \param bt BufferedTransformation object

0729     /// \param parametersPresent flag indicating if algorithm parameters are present

0730     /// \param size number of octets to read for the parameters, in bytes

0731     /// \details BERDecodePublicKey() the decodes subjectPublicKey part of

0732     ///  subjectPublicKeyInfo, without the BIT STRING header.

0733     /// \details When <tt>parametersPresent = true</tt> then BERDecodePublicKey() calls

0734     ///  BERDecodeAlgorithmParameters() to parse algorithm parameters.

0735     /// \sa BERDecodeAlgorithmParameters

0736     virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
0737 
0738     /// \brief Encode subjectPublicKey part of subjectPublicKeyInfo

0739     /// \param bt BufferedTransformation object

0740     /// \details DEREncodePublicKey() encodes the subjectPublicKey part of

0741     ///  subjectPublicKeyInfo, without the BIT STRING header.

0742     /// \sa DEREncodeAlgorithmParameters

0743     virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0;
0744 };
0745 
0746 /// \brief Encodes and Decodes privateKeyInfo

0747 class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial<PrivateKey>
0748 {
0749 public:
0750     virtual ~PKCS8PrivateKey() {}
0751 
0752     void BERDecode(BufferedTransformation &bt);
0753     void DEREncode(BufferedTransformation &bt) const;
0754 
0755     /// \brief Retrieves the OID of the algorithm

0756     /// \return OID of the algorithm

0757     virtual OID GetAlgorithmID() const =0;
0758 
0759     /// \brief Decode optional parameters

0760     /// \param bt BufferedTransformation object

0761     /// \sa BERDecodePrivateKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC

0762     ///  2459, section 7.3.1</A>

0763     virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
0764         {BERDecodeNull(bt); return false;}
0765 
0766     /// \brief Encode optional parameters

0767     /// \param bt BufferedTransformation object

0768     /// \sa DEREncodePrivateKey, <A HREF="http://www.ietf.org/rfc/rfc2459.txt">RFC

0769     ///  2459, section 7.3.1</A>

0770     virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
0771         {DEREncodeNull(bt); return false;}
0772 
0773     /// \brief Decode privateKey part of privateKeyInfo

0774     /// \param bt BufferedTransformation object

0775     /// \param parametersPresent flag indicating if algorithm parameters are present

0776     /// \param size number of octets to read for the parameters, in bytes

0777     /// \details BERDecodePrivateKey() the decodes privateKey part of privateKeyInfo,

0778     ///  without the OCTET STRING header.

0779     /// \details When <tt>parametersPresent = true</tt> then BERDecodePrivateKey() calls

0780     ///  BERDecodeAlgorithmParameters() to parse algorithm parameters.

0781     /// \sa BERDecodeAlgorithmParameters

0782     virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
0783 
0784     /// \brief Encode privateKey part of privateKeyInfo

0785     /// \param bt BufferedTransformation object

0786     /// \details DEREncodePrivateKey() encodes the privateKey part of privateKeyInfo,

0787     ///  without the OCTET STRING header.

0788     /// \sa DEREncodeAlgorithmParameters

0789     virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0;
0790 
0791     /// \brief Decode optional attributes

0792     /// \param bt BufferedTransformation object

0793     /// \details BERDecodeOptionalAttributes() decodes optional attributes including

0794     ///  context-specific tag.

0795     /// \sa BERDecodeAlgorithmParameters, DEREncodeOptionalAttributes

0796     /// \note default implementation stores attributes to be output using

0797     ///  DEREncodeOptionalAttributes

0798     virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt);
0799 
0800     /// \brief Encode optional attributes

0801     /// \param bt BufferedTransformation object

0802     /// \details DEREncodeOptionalAttributes() encodes optional attributes including

0803     ///  context-specific tag.

0804     /// \sa BERDecodeAlgorithmParameters

0805     virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const;
0806 
0807 protected:
0808     ByteQueue m_optionalAttributes;
0809 };
0810 
0811 // ********************************************************

0812 
0813 /// \brief DER Encode unsigned value

0814 /// \tparam T class or type

0815 /// \param out BufferedTransformation object

0816 /// \param w unsigned value to encode

0817 /// \param asnTag the ASN.1 identifier

0818 /// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM

0819 template <class T>
0820 size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
0821 {
0822     byte buf[sizeof(w)+1];
0823     unsigned int bc;
0824     if (asnTag == BOOLEAN)
0825     {
0826         buf[sizeof(w)] = w ? 0xff : 0;
0827         bc = 1;
0828     }
0829     else
0830     {
0831         buf[0] = 0;
0832         for (unsigned int i=0; i<sizeof(w); i++)
0833             buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
0834         bc = sizeof(w);
0835         while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
0836             --bc;
0837         if (buf[sizeof(w)+1-bc] & 0x80)
0838             ++bc;
0839     }
0840     out.Put(asnTag);
0841     size_t lengthBytes = DERLengthEncode(out, bc);
0842     out.Put(buf+sizeof(w)+1-bc, bc);
0843     return 1+lengthBytes+bc;
0844 }
0845 
0846 /// \brief BER Decode unsigned value

0847 /// \tparam T fundamental C++ type

0848 /// \param in BufferedTransformation object

0849 /// \param w the decoded value

0850 /// \param asnTag the ASN.1 identifier

0851 /// \param minValue the minimum expected value

0852 /// \param maxValue the maximum expected value

0853 /// \throw BERDecodeErr() if the value cannot be parsed or the decoded value is not within range.

0854 /// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM

0855 template <class T>
0856 void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
0857                        T minValue = 0, T maxValue = T(0xffffffff))
0858 {
0859     byte b;
0860     if (!in.Get(b) || b != asnTag)
0861         BERDecodeError();
0862 
0863     size_t bc;
0864     bool definite = BERLengthDecode(in, bc);
0865     if (!definite)
0866         BERDecodeError();
0867     if (bc > in.MaxRetrievable())  // Issue 346

0868         BERDecodeError();
0869     if (asnTag == BOOLEAN && bc != 1) // X.690, 8.2.1

0870         BERDecodeError();
0871     if ((asnTag == INTEGER || asnTag == ENUMERATED) && bc == 0) // X.690, 8.3.1 and 8.4

0872         BERDecodeError();
0873 
0874     SecByteBlock buf(bc);
0875 
0876     if (bc != in.Get(buf, bc))
0877         BERDecodeError();
0878 
0879     // This consumes leading 0 octets. According to X.690, 8.3.2, it could be non-conforming behavior.

0880     //  X.690, 8.3.2 says "the bits of the first octet and bit 8 of the second octet ... (a) shall

0881     //  not all be ones and (b) shall not all be zeros ... These rules ensure that an integer value

0882     //  is always encoded in the smallest possible number of octet".

0883     // We invented AER (Alternate Encoding Rules), which is more relaxed than BER, CER, and DER.

0884     const byte *ptr = buf;
0885     while (bc > sizeof(w) && *ptr == 0)
0886     {
0887         bc--;
0888         ptr++;
0889     }
0890     if (bc > sizeof(w))
0891         BERDecodeError();
0892 
0893     w = 0;
0894     for (unsigned int i=0; i<bc; i++)
0895         w = (w << 8) | ptr[i];
0896 
0897     if (w < minValue || w > maxValue)
0898         BERDecodeError();
0899 }
0900 
0901 #ifdef CRYPTOPP_DOXYGEN_PROCESSING
0902 /// \brief Compare two OIDs for equality

0903 /// \param lhs the first OID

0904 /// \param rhs the second OID

0905 /// \return true if the OIDs are equal, false otherwise

0906 inline bool operator==(const OID &lhs, const OID &rhs);
0907 /// \brief Compare two OIDs for inequality

0908 /// \param lhs the first OID

0909 /// \param rhs the second OID

0910 /// \return true if the OIDs are not equal, false otherwise

0911 inline bool operator!=(const OID &lhs, const OID &rhs);
0912 /// \brief Compare two OIDs for ordering

0913 /// \param lhs the first OID

0914 /// \param rhs the second OID

0915 /// \return true if the first OID is less than the second OID, false otherwise

0916 /// \details operator<() calls std::lexicographical_compare() on each element in the array of values.

0917 inline bool operator<(const OID &lhs, const OID &rhs);
0918 /// \brief Compare two OIDs for ordering

0919 /// \param lhs the first OID

0920 /// \param rhs the second OID

0921 /// \return true if the first OID is less than or equal to the second OID, false otherwise

0922 /// \details operator<=() is implemented in terms of operator==() and operator<().

0923 /// \since Crypto++ 8.3

0924 inline bool operator<=(const OID &lhs, const OID &rhs);
0925 /// \brief Compare two OIDs for ordering

0926 /// \param lhs the first OID

0927 /// \param rhs the second OID

0928 /// \return true if the first OID is greater than or equal to the second OID, false otherwise

0929 /// \details operator>=() is implemented in terms of operator<().

0930 /// \since Crypto++ 8.3

0931 inline bool operator>=(const OID &lhs, const OID &rhs);
0932 /// \brief Append a value to an OID

0933 /// \param lhs the OID

0934 /// \param rhs the value to append

0935 inline OID operator+(const OID &lhs, unsigned long rhs);
0936 /// \brief Print a OID value

0937 /// \param out the output stream

0938 /// \param oid the OID

0939 inline std::ostream& operator<<(std::ostream& out, const OID &oid)
0940     { return oid.Print(out); }
0941 #else
0942 inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
0943     {return lhs.m_values == rhs.m_values;}
0944 inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
0945     {return lhs.m_values != rhs.m_values;}
0946 inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
0947     {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
0948 inline bool operator<=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
0949     {return lhs<rhs || lhs==rhs;}
0950 inline bool operator>=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
0951     {return ! (lhs<rhs);}
0952 inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
0953     {return ::CryptoPP::OID(lhs)+=rhs;}
0954 inline std::ostream& operator<<(std::ostream& out, const OID &oid)
0955     { return oid.Print(out); }
0956 #endif
0957 
0958 NAMESPACE_END
0959 
0960 // Issue 340

0961 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
0962 # pragma GCC diagnostic pop
0963 #endif
0964 
0965 #endif