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