Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / asn1 / ASN1Writer.cpp
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
5  *    All rights reserved.
6  *
7  *    Licensed under the Apache License, Version 2.0 (the "License");
8  *    you may not use this file except in compliance with the License.
9  *    You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing, software
14  *    distributed under the License is distributed on an "AS IS" BASIS,
15  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *    See the License for the specific language governing permissions and
17  *    limitations under the License.
18  */
19
20 /**
21  *    @file
22  *      This file implements an object for writing Abstract Syntax
23  *      Notation One (ASN.1) encoded data.
24  *
25  */
26
27 #ifndef __STDC_LIMIT_MACROS
28 #define __STDC_LIMIT_MACROS
29 #endif
30 #include <ctype.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include <asn1/ASN1.h>
37 #include <core/CHIPCore.h>
38 #include <core/CHIPEncoding.h>
39 #include <core/CHIPTLV.h>
40 #include <support/CodeUtils.h>
41
42 namespace chip {
43 namespace ASN1 {
44
45 using namespace chip::Encoding;
46
47 enum
48 {
49     kLengthFieldReserveSize = 5,
50     kMaxElementLength       = INT32_MAX,
51     kUnkownLength           = -1,
52     kUnknownLengthMarker    = 0xFF
53 };
54
55 void ASN1Writer::Init(uint8_t * buf, uint32_t maxLen)
56 {
57     mBuf                = buf;
58     mWritePoint         = buf;
59     mBufEnd             = buf + maxLen;
60     mBufEnd             = reinterpret_cast<uint8_t *>(reinterpret_cast<uintptr_t>(mBufEnd) & ~3); // align on 32bit boundary
61     mDeferredLengthList = reinterpret_cast<uint8_t **>(mBufEnd);
62 }
63
64 void ASN1Writer::InitNullWriter(void)
65 {
66     mBuf                = nullptr;
67     mWritePoint         = nullptr;
68     mBufEnd             = nullptr;
69     mDeferredLengthList = nullptr;
70 }
71
72 ASN1_ERROR ASN1Writer::Finalize()
73 {
74     if (mBuf != nullptr)
75     {
76         uint8_t * compactPoint = mBuf;
77         uint8_t * spanStart    = mBuf;
78
79         for (uint8_t ** listEntry = reinterpret_cast<uint8_t **>(mBufEnd); listEntry > mDeferredLengthList;)
80         {
81             uint8_t * lenField        = *--listEntry;
82             uint8_t lenFieldFirstByte = *lenField;
83
84             if (lenFieldFirstByte == kUnknownLengthMarker)
85                 return ASN1_ERROR_INVALID_STATE;
86
87             uint8_t lenOfLen = (lenFieldFirstByte < 128) ? 1 : (lenFieldFirstByte & 0x7f) + 1;
88
89             uint8_t * spanEnd = lenField + lenOfLen;
90
91             if (spanStart == compactPoint)
92                 compactPoint = spanEnd;
93             else
94             {
95                 uint32_t spanLen = spanEnd - spanStart;
96                 memmove(compactPoint, spanStart, spanLen);
97                 compactPoint += spanLen;
98             }
99
100             spanStart = lenField + kLengthFieldReserveSize;
101         }
102
103         if (spanStart > compactPoint)
104         {
105             uint32_t spanLen = mWritePoint - spanStart;
106             memmove(compactPoint, spanStart, spanLen);
107             compactPoint += spanLen;
108         }
109
110         mWritePoint = compactPoint;
111     }
112
113     return ASN1_NO_ERROR;
114 }
115
116 uint16_t ASN1Writer::GetLengthWritten() const
117 {
118     return (mBuf != nullptr) ? mWritePoint - mBuf : 0;
119 }
120
121 ASN1_ERROR ASN1Writer::PutInteger(int64_t val)
122 {
123     uint8_t encodedVal[8];
124     uint8_t valStart, valLen;
125
126     BigEndian::Put64(encodedVal, static_cast<uint64_t>(val));
127
128     for (valStart = 0; valStart < 7; valStart++)
129     {
130         if (encodedVal[valStart] == 0x00 && (encodedVal[valStart + 1] & 0x80) == 0)
131             continue;
132         if (encodedVal[valStart] == 0xFF && (encodedVal[valStart + 1] & 0x80) == 0x80)
133             continue;
134         break;
135     }
136     valLen = 8 - valStart;
137
138     return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false, encodedVal + valStart, valLen);
139 }
140
141 ASN1_ERROR ASN1Writer::PutBoolean(bool val)
142 {
143     // Do nothing for a null writer.
144     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
145
146     ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Boolean, false, 1));
147
148     *mWritePoint++ = (val) ? 0xFF : 0;
149
150     return ASN1_NO_ERROR;
151 }
152
153 ASN1_ERROR ASN1Writer::PutObjectId(const uint8_t * val, uint16_t valLen)
154 {
155     return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId, false, val, valLen);
156 }
157
158 ASN1_ERROR ASN1Writer::PutString(uint32_t tag, const char * val, uint16_t valLen)
159 {
160     return PutValue(kASN1TagClass_Universal, tag, false, (const uint8_t *) val, valLen);
161 }
162
163 ASN1_ERROR ASN1Writer::PutOctetString(const uint8_t * val, uint16_t valLen)
164 {
165     return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_OctetString, false, val, valLen);
166 }
167
168 ASN1_ERROR ASN1Writer::PutOctetString(uint8_t cls, uint32_t tag, const uint8_t * val, uint16_t valLen)
169 {
170     return PutValue(cls, tag, false, val, valLen);
171 }
172
173 ASN1_ERROR ASN1Writer::PutOctetString(uint8_t cls, uint32_t tag, chip::TLV::TLVReader & val)
174 {
175     return PutValue(cls, tag, false, val);
176 }
177
178 static uint8_t ReverseBits(uint8_t v)
179 {
180     // swap adjacent bits
181     v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
182     // swap adjacent bit pairs
183     v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
184     // swap nibbles
185     v = (v >> 4) | (v << 4);
186     return v;
187 }
188
189 static uint8_t HighestBit(uint32_t v)
190 {
191     uint32_t highestBit = 0;
192
193     if (v > 0xFFFF)
194     {
195         highestBit = 16;
196         v >>= 16;
197     }
198     if (v > 0xFF)
199     {
200         highestBit |= 8;
201         v >>= 8;
202     }
203     if (v > 0xF)
204     {
205         highestBit |= 4;
206         v >>= 4;
207     }
208     if (v > 0x3)
209     {
210         highestBit |= 2;
211         v >>= 2;
212     }
213     highestBit |= (v >> 1);
214
215     return highestBit;
216 }
217
218 ASN1_ERROR ASN1Writer::PutBitString(uint32_t val)
219 {
220     uint8_t len;
221
222     // Do nothing for a null writer.
223     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
224
225     if (val == 0)
226         len = 1;
227     else if (val < 256)
228         len = 2;
229     else if (val < 65536)
230         len = 3;
231     else if (val < (1 << 24))
232         len = 4;
233     else
234         len = 5;
235
236     ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, len));
237
238     if (val == 0)
239         mWritePoint[0] = 0;
240     else
241     {
242         mWritePoint[1] = ReverseBits(static_cast<uint8_t>(val));
243         if (len >= 3)
244         {
245             val >>= 8;
246             mWritePoint[2] = ReverseBits(static_cast<uint8_t>(val));
247             if (len >= 4)
248             {
249                 val >>= 8;
250                 mWritePoint[3] = ReverseBits(static_cast<uint8_t>(val));
251                 if (len == 5)
252                 {
253                     val >>= 8;
254                     mWritePoint[4] = ReverseBits(static_cast<uint8_t>(val));
255                 }
256             }
257         }
258         mWritePoint[0] = 7 - HighestBit(val);
259     }
260
261     mWritePoint += len;
262
263     return ASN1_NO_ERROR;
264 }
265
266 ASN1_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, const uint8_t * encodedBits, uint16_t encodedBitsLen)
267 {
268     // Do nothing for a null writer.
269     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
270
271     ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, encodedBitsLen + 1));
272
273     *mWritePoint++ = unusedBitCount;
274
275     memcpy(mWritePoint, encodedBits, encodedBitsLen);
276     mWritePoint += encodedBitsLen;
277
278     return ASN1_NO_ERROR;
279 }
280
281 ASN1_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, chip::TLV::TLVReader & encodedBits)
282 {
283     uint32_t encodedBitsLen;
284
285     // Do nothing for a null writer.
286     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
287
288     encodedBitsLen = encodedBits.GetLength();
289
290     ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, encodedBitsLen + 1));
291
292     *mWritePoint++ = unusedBitCount;
293
294     encodedBits.GetBytes(mWritePoint, encodedBitsLen);
295     mWritePoint += encodedBitsLen;
296
297     return ASN1_NO_ERROR;
298 }
299
300 static void itoa2(uint32_t val, uint8_t * buf)
301 {
302     buf[1] = '0' + (val % 10);
303     val /= 10;
304     buf[0] = '0' + (val % 10);
305 }
306
307 ASN1_ERROR ASN1Writer::PutTime(const ASN1UniversalTime & val)
308 {
309     uint8_t buf[15];
310
311     itoa2(val.Year / 100, buf);
312     itoa2(val.Year, buf + 2);
313     itoa2(val.Month, buf + 4);
314     itoa2(val.Day, buf + 6);
315     itoa2(val.Hour, buf + 8);
316     itoa2(val.Minute, buf + 10);
317     itoa2(val.Second, buf + 12);
318     buf[14] = 'Z';
319
320     // X.509/RFC5280 mandates that times before 2050 UTC must be encoded as ASN.1 UTCTime values, while
321     // times equal or greater than 2050 must be encoded as GeneralizedTime values.  The only difference
322     // (in the context of X.509 DER) is that GeneralizedTimes are encoded with a 4 digit year, while
323     // UTCTimes are encoded with a two-digit year.
324     //
325     if (val.Year >= 2050)
326         return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_GeneralizedTime, false, buf, 15);
327     else
328         return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_UTCTime, false, buf + 2, 13);
329 }
330
331 ASN1_ERROR ASN1Writer::PutNull()
332 {
333     return EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Null, false, 0);
334 }
335
336 ASN1_ERROR ASN1Writer::StartConstructedType(uint8_t cls, uint32_t tag)
337 {
338     return EncodeHead(cls, tag, true, kUnkownLength);
339 }
340
341 ASN1_ERROR ASN1Writer::EndConstructedType()
342 {
343     return WriteDeferredLength();
344 }
345
346 ASN1_ERROR ASN1Writer::StartEncapsulatedType(uint8_t cls, uint32_t tag, bool bitStringEncoding)
347 {
348     // Do nothing for a null writer.
349     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
350
351     ReturnErrorOnFailure(EncodeHead(cls, tag, false, kUnkownLength));
352
353     // If the encapsulating type is BIT STRING, encode the unused bit count field.  Since the BIT
354     // STRING contains an ASN.1 DER encoding, and ASN.1 DER encodings are always multiples of 8 bits,
355     // the unused bit count is always 0.
356     if (bitStringEncoding)
357     {
358         if (mWritePoint == reinterpret_cast<uint8_t *>(mDeferredLengthList))
359             return ASN1_ERROR_OVERFLOW;
360         *mWritePoint++ = 0;
361     }
362
363     return ASN1_NO_ERROR;
364 }
365
366 ASN1_ERROR ASN1Writer::EndEncapsulatedType()
367 {
368     return WriteDeferredLength();
369 }
370
371 ASN1_ERROR ASN1Writer::PutValue(uint8_t cls, uint32_t tag, bool isConstructed, const uint8_t * val, uint16_t valLen)
372 {
373     // Do nothing for a null writer.
374     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
375
376     ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, valLen));
377
378     memcpy(mWritePoint, val, valLen);
379     mWritePoint += valLen;
380
381     return ASN1_NO_ERROR;
382 }
383
384 ASN1_ERROR ASN1Writer::PutValue(uint8_t cls, uint32_t tag, bool isConstructed, chip::TLV::TLVReader & val)
385 {
386     uint32_t valLen;
387
388     // Do nothing for a null writer.
389     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
390
391     valLen = val.GetLength();
392
393     ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, valLen));
394
395     val.GetBytes(mWritePoint, valLen);
396     mWritePoint += valLen;
397
398     return ASN1_NO_ERROR;
399 }
400
401 ASN1_ERROR ASN1Writer::EncodeHead(uint8_t cls, uint32_t tag, bool isConstructed, int32_t len)
402 {
403     uint8_t bytesForLen;
404     uint32_t totalLen;
405
406     // Do nothing for a null writer.
407     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
408
409     // Only tags <= 31 supported. The implication of this is that encoded tags are exactly 1 byte long.
410     VerifyOrReturnError(tag <= 0x1F, ASN1_ERROR_UNSUPPORTED_ENCODING);
411
412     // Only positive and kUnkownLength values are supported for len input.
413     VerifyOrReturnError(len >= 0 || len == kUnkownLength, ASN1_ERROR_UNSUPPORTED_ENCODING);
414
415     // Compute the number of bytes required to encode the length.
416     bytesForLen = BytesForLength(len);
417
418     // If the element length is unknown, allocate a new entry in the deferred-length list.
419     //
420     // The deferred-length list is a list of "pointers" (represented as offsets into mBuf)
421     // to length fields for which the length of the element was unknown at the time the element
422     // head was written. Examples include constructed types such as SEQUENCE and SET, as well
423     // non-constructed types that encapsulate other ASN.1 types (e.g. OCTET STRINGS that contain
424     // BER/DER encodings). The final lengths are filled in later, at the time the encoding is
425     // complete (e.g. when EndConstructed() is called).
426     //
427     if (len == kUnkownLength)
428         mDeferredLengthList--;
429
430     // Make sure there's enough space to encode the entire value without bumping into the deferred length
431     // list at the end of the buffer.
432     totalLen = 1 + bytesForLen + (len != kUnkownLength ? len : 0);
433     VerifyOrReturnError((mWritePoint + totalLen) <= reinterpret_cast<uint8_t *>(mDeferredLengthList), ASN1_ERROR_OVERFLOW);
434
435     // Write the tag byte.
436     *mWritePoint++ = cls | (isConstructed ? 0x20 : 0) | tag;
437
438     // Encode the length if it is known.
439     if (len != kUnkownLength)
440         EncodeLength(mWritePoint, bytesForLen, len);
441
442     // ... otherwise place a marker in the first byte of the length to indicate that the length is unknown
443     // and save a pointer to the length field in the deferred-length list.
444     else
445     {
446         *mWritePoint         = kUnknownLengthMarker;
447         *mDeferredLengthList = mWritePoint;
448     }
449
450     mWritePoint += bytesForLen;
451
452     return ASN1_NO_ERROR;
453 }
454
455 ASN1_ERROR ASN1Writer::WriteDeferredLength()
456 {
457     uint8_t ** listEntry;
458     uint32_t lenAdj;
459
460     // Do nothing for a null writer.
461     VerifyOrReturnError(mBuf != nullptr, ASN1_NO_ERROR);
462
463     lenAdj = kLengthFieldReserveSize;
464
465     // Scan the deferred-length list in reverse order looking for the most recent entry where
466     // the length is still unknown. This entry represents the "container" element whose encoding
467     // is now complete.
468     for (listEntry = mDeferredLengthList; listEntry < reinterpret_cast<uint8_t **>(mBufEnd); listEntry++)
469     {
470         // Get a pointer to the deferred-length field.
471         uint8_t * lenField = *listEntry;
472
473         // Get the first byte of the length field.
474         uint8_t lenFieldFirstByte = *lenField;
475
476         // If the length is marked as unknown...
477         if (lenFieldFirstByte == kUnknownLengthMarker)
478         {
479             // Compute the final length of the element's value (3 = bytes reserved for length).
480             uint32_t elemLen = (mWritePoint - lenField) - lenAdj;
481
482             // Return an error if the length exceeds the maximum value that can be encoded in the
483             // space reserved for the length.
484             VerifyOrReturnError(elemLen <= kMaxElementLength, ASN1_ERROR_LENGTH_OVERFLOW);
485
486             // Encode the final length of the element, overwriting the unknown length marker
487             // in the process.  Note that the number of bytes consumed by the final length field
488             // may be smaller than the space that was reserved for the field.  This will be fixed
489             // up when the Finalize() method is called.
490             uint8_t bytesForLen = BytesForLength(static_cast<int32_t>(elemLen));
491             EncodeLength(lenField, bytesForLen, elemLen);
492
493             return ASN1_NO_ERROR;
494         }
495         else
496         {
497             uint8_t bytesForLen = (lenFieldFirstByte < 128) ? 1 : (lenFieldFirstByte & 0x7f) + 1;
498             lenAdj += (kLengthFieldReserveSize - bytesForLen);
499         }
500     }
501
502     return ASN1_ERROR_INVALID_STATE;
503 }
504
505 /**
506  * Returns the number of bytes required to encode the length value.
507  *
508  * @param[in]   len     Parameter, which encoding length to be calculated.
509  *
510  * @return number of bytes required to encode the length value.
511  */
512 uint8_t ASN1Writer::BytesForLength(int32_t len)
513 {
514     if (len == kUnkownLength)
515         return kLengthFieldReserveSize;
516     if (len < 128)
517         return 1;
518     if (len < 256)
519         return 2;
520     if (len < 65536)
521         return 3;
522     if (len < (1 << 24))
523         return 4;
524     return 5;
525 }
526
527 void ASN1Writer::EncodeLength(uint8_t * buf, uint8_t bytesForLen, int32_t lenToEncode)
528 {
529     if (bytesForLen == 1)
530         buf[0] = static_cast<uint8_t>(lenToEncode);
531     else
532     {
533         --bytesForLen;
534         buf[0] = 0x80 | bytesForLen;
535         do
536         {
537             buf[bytesForLen] = static_cast<uint8_t>(lenToEncode);
538             lenToEncode >>= 8;
539         } while (--bytesForLen);
540     }
541 }
542
543 } // namespace ASN1
544 } // namespace chip