|
||||
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 ¶meters) 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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |