Line data Source code
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 <lib/asn1/ASN1.h>
37 : #include <lib/core/CHIPCore.h>
38 : #include <lib/core/CHIPEncoding.h>
39 : #include <lib/core/TLV.h>
40 : #include <lib/support/CodeUtils.h>
41 : #include <lib/support/SafeInt.h>
42 :
43 : namespace chip {
44 : namespace ASN1 {
45 :
46 : using namespace chip::Encoding;
47 :
48 : enum
49 : {
50 : kLengthFieldReserveSize = 1,
51 : kUnknownLength = -1,
52 : kUnknownLengthMarker = 0xFF
53 : };
54 :
55 1698 : void ASN1Writer::Init(uint8_t * buf, size_t maxLen)
56 : {
57 1698 : mBuf = buf;
58 1698 : mWritePoint = buf;
59 1698 : mBufEnd = buf + maxLen;
60 1698 : mDeferredLengthCount = 0;
61 1698 : }
62 :
63 2600 : void ASN1Writer::InitNullWriter()
64 : {
65 2600 : mBuf = nullptr;
66 2600 : mWritePoint = nullptr;
67 2600 : mBufEnd = nullptr;
68 2600 : mDeferredLengthCount = 0;
69 2600 : }
70 :
71 1611 : size_t ASN1Writer::GetLengthWritten() const
72 : {
73 1611 : return (mBuf != nullptr) ? static_cast<size_t>(mWritePoint - mBuf) : 0;
74 : }
75 :
76 3030 : CHIP_ERROR ASN1Writer::PutInteger(int64_t val)
77 : {
78 3030 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
79 :
80 : uint8_t encodedVal[sizeof(int64_t)];
81 : uint8_t valStart, valLen;
82 :
83 1860 : BigEndian::Put64(encodedVal, static_cast<uint64_t>(val));
84 :
85 14816 : for (valStart = 0; valStart < 7; valStart++)
86 : {
87 12990 : if (encodedVal[valStart] == 0x00 && (encodedVal[valStart + 1] & 0x80) == 0)
88 12941 : continue;
89 49 : if (encodedVal[valStart] == 0xFF && (encodedVal[valStart + 1] & 0x80) == 0x80)
90 15 : continue;
91 34 : break;
92 : }
93 1860 : valLen = static_cast<uint8_t>(8 - valStart);
94 :
95 1860 : return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false, encodedVal + valStart, valLen);
96 : }
97 :
98 8104 : CHIP_ERROR ASN1Writer::PutBoolean(bool val)
99 : {
100 8104 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
101 :
102 4826 : ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Boolean, false, 1));
103 :
104 4826 : *mWritePoint++ = (val) ? 0xFF : 0;
105 :
106 4826 : return CHIP_NO_ERROR;
107 : }
108 :
109 33609 : CHIP_ERROR ASN1Writer::PutObjectId(const uint8_t * val, uint16_t valLen)
110 : {
111 33609 : return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId, false, val, valLen);
112 : }
113 :
114 8969 : CHIP_ERROR ASN1Writer::PutString(uint8_t tag, const char * val, uint16_t valLen)
115 : {
116 8969 : return PutValue(kASN1TagClass_Universal, tag, false, (const uint8_t *) val, valLen);
117 : }
118 :
119 2687 : CHIP_ERROR ASN1Writer::PutOctetString(const uint8_t * val, uint16_t valLen)
120 : {
121 2687 : return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_OctetString, false, val, valLen);
122 : }
123 :
124 2663 : CHIP_ERROR ASN1Writer::PutOctetString(uint8_t cls, uint8_t tag, const uint8_t * val, uint16_t valLen)
125 : {
126 2663 : return PutValue(cls, tag, false, val, valLen);
127 : }
128 :
129 2 : CHIP_ERROR ASN1Writer::PutOctetString(uint8_t cls, uint8_t tag, chip::TLV::TLVReader & tlvReader)
130 : {
131 2 : return PutValue(cls, tag, false, tlvReader);
132 : }
133 :
134 1616 : static uint8_t ReverseBits(uint8_t v)
135 : {
136 : // swap adjacent bits
137 1616 : v = static_cast<uint8_t>(static_cast<uint8_t>((v >> 1) & 0x55) | static_cast<uint8_t>((v & 0x55) << 1));
138 : // swap adjacent bit pairs
139 1616 : v = static_cast<uint8_t>(static_cast<uint8_t>((v >> 2) & 0x33) | static_cast<uint8_t>((v & 0x33) << 2));
140 : // swap nibbles
141 1616 : v = static_cast<uint8_t>(static_cast<uint8_t>(v >> 4) | static_cast<uint8_t>(v << 4));
142 1616 : return v;
143 : }
144 :
145 1613 : static uint8_t HighestBit(uint32_t v)
146 : {
147 1613 : uint32_t highestBit = 0;
148 :
149 1613 : if (v > 0xFFFF)
150 : {
151 0 : highestBit = 16;
152 0 : v >>= 16;
153 : }
154 1613 : if (v > 0xFF)
155 : {
156 0 : highestBit |= 8;
157 0 : v >>= 8;
158 : }
159 1613 : if (v > 0xF)
160 : {
161 814 : highestBit |= 4;
162 814 : v >>= 4;
163 : }
164 1613 : if (v > 0x3)
165 : {
166 811 : highestBit |= 2;
167 811 : v >>= 2;
168 : }
169 1613 : highestBit |= (v >> 1);
170 :
171 1613 : return static_cast<uint8_t>(highestBit);
172 : }
173 :
174 2712 : CHIP_ERROR ASN1Writer::PutBitString(uint32_t val)
175 : {
176 2712 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
177 :
178 : uint8_t len;
179 1614 : if (val == 0)
180 1 : len = 1;
181 1613 : else if (val < 256)
182 1610 : len = 2;
183 3 : else if (val < 65536)
184 3 : len = 3;
185 0 : else if (val < (1 << 24))
186 0 : len = 4;
187 : else
188 0 : len = 5;
189 :
190 1614 : ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, len));
191 :
192 1614 : if (val == 0)
193 : {
194 1 : mWritePoint[0] = 0;
195 : }
196 : else
197 : {
198 1613 : mWritePoint[1] = ReverseBits(static_cast<uint8_t>(val));
199 1613 : if (len >= 3)
200 : {
201 3 : val >>= 8;
202 3 : mWritePoint[2] = ReverseBits(static_cast<uint8_t>(val));
203 3 : if (len >= 4)
204 : {
205 0 : val >>= 8;
206 0 : mWritePoint[3] = ReverseBits(static_cast<uint8_t>(val));
207 0 : if (len == 5)
208 : {
209 0 : val >>= 8;
210 0 : mWritePoint[4] = ReverseBits(static_cast<uint8_t>(val));
211 : }
212 : }
213 : }
214 1613 : mWritePoint[0] = static_cast<uint8_t>(7 - HighestBit(val));
215 : }
216 :
217 1614 : mWritePoint += len;
218 :
219 1614 : return CHIP_NO_ERROR;
220 : }
221 :
222 2713 : CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, const uint8_t * encodedBits, uint16_t encodedBitsLen)
223 : {
224 2713 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
225 :
226 1619 : ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, encodedBitsLen + 1));
227 :
228 1619 : *mWritePoint++ = unusedBitCount;
229 :
230 1619 : WriteData(encodedBits, encodedBitsLen);
231 :
232 1619 : return CHIP_NO_ERROR;
233 : }
234 :
235 2 : CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, chip::TLV::TLVReader & tlvReader)
236 : {
237 2 : ByteSpan encodedBits;
238 2 : ReturnErrorOnFailure(tlvReader.Get(encodedBits));
239 :
240 1 : VerifyOrReturnError(CanCastTo<int32_t>(encodedBits.size() + 1), ASN1_ERROR_LENGTH_OVERFLOW);
241 :
242 1 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
243 :
244 1 : ReturnErrorOnFailure(
245 : EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, static_cast<int32_t>(encodedBits.size() + 1)));
246 :
247 1 : *mWritePoint++ = unusedBitCount;
248 :
249 1 : WriteData(encodedBits.data(), encodedBits.size());
250 :
251 1 : return CHIP_NO_ERROR;
252 : }
253 :
254 5517 : CHIP_ERROR ASN1Writer::PutTime(const ASN1UniversalTime & val)
255 : {
256 5517 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
257 :
258 : char buf[ASN1UniversalTime::kASN1TimeStringMaxLength];
259 3296 : MutableCharSpan bufSpan(buf);
260 : uint8_t tag;
261 :
262 3296 : ReturnErrorOnFailure(val.ExportTo_ASN1_TIME_string(bufSpan));
263 :
264 3296 : if (val.Year >= 2050)
265 : {
266 12 : tag = kASN1UniversalTag_GeneralizedTime;
267 : }
268 : else
269 : {
270 3284 : tag = kASN1UniversalTag_UTCTime;
271 : }
272 3296 : return PutValue(kASN1TagClass_Universal, tag, false, reinterpret_cast<uint8_t *>(buf), static_cast<uint16_t>(bufSpan.size()));
273 : }
274 :
275 0 : CHIP_ERROR ASN1Writer::PutNull()
276 : {
277 0 : return EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Null, false, 0);
278 : }
279 :
280 63 : CHIP_ERROR ASN1Writer::PutConstructedType(const uint8_t * val, uint16_t valLen)
281 : {
282 63 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
283 :
284 : // Make sure we have enough space to write
285 10 : VerifyOrReturnError((mWritePoint + valLen) <= mBufEnd, ASN1_ERROR_OVERFLOW);
286 :
287 10 : WriteData(val, valLen);
288 :
289 10 : return CHIP_NO_ERROR;
290 : }
291 :
292 69108 : CHIP_ERROR ASN1Writer::StartConstructedType(uint8_t cls, uint8_t tag)
293 : {
294 69108 : return EncodeHead(cls, tag, true, kUnknownLength);
295 : }
296 :
297 68703 : CHIP_ERROR ASN1Writer::EndConstructedType()
298 : {
299 68703 : return WriteDeferredLength();
300 : }
301 :
302 11872 : CHIP_ERROR ASN1Writer::StartEncapsulatedType(uint8_t cls, uint8_t tag, bool bitStringEncoding)
303 : {
304 11872 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
305 :
306 7299 : ReturnErrorOnFailure(EncodeHead(cls, tag, false, kUnknownLength));
307 :
308 : // If the encapsulating type is BIT STRING, encode the unused bit count field. Since the BIT
309 : // STRING contains an ASN.1 DER encoding, and ASN.1 DER encodings are always multiples of 8 bits,
310 : // the unused bit count is always 0.
311 7299 : if (bitStringEncoding)
312 : {
313 93 : VerifyOrReturnError(mWritePoint < mBufEnd, ASN1_ERROR_OVERFLOW);
314 93 : *mWritePoint++ = 0;
315 : }
316 :
317 7299 : return CHIP_NO_ERROR;
318 : }
319 :
320 11844 : CHIP_ERROR ASN1Writer::EndEncapsulatedType()
321 : {
322 11844 : return WriteDeferredLength();
323 : }
324 :
325 55922 : CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, const uint8_t * val, uint16_t valLen)
326 : {
327 55922 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
328 :
329 33889 : ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, valLen));
330 :
331 33883 : WriteData(val, valLen);
332 :
333 33883 : return CHIP_NO_ERROR;
334 : }
335 :
336 3 : CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, chip::TLV::TLVReader & tlvReader)
337 : {
338 3 : ByteSpan val;
339 3 : ReturnErrorOnFailure(tlvReader.Get(val));
340 :
341 2 : VerifyOrReturnError(CanCastTo<int32_t>(val.size()), ASN1_ERROR_LENGTH_OVERFLOW);
342 :
343 2 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
344 :
345 2 : ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, static_cast<int32_t>(val.size())));
346 :
347 2 : WriteData(val.data(), val.size());
348 :
349 2 : return CHIP_NO_ERROR;
350 : }
351 :
352 118358 : CHIP_ERROR ASN1Writer::EncodeHead(uint8_t cls, uint8_t tag, bool isConstructed, int32_t len)
353 : {
354 118358 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
355 :
356 : uint8_t bytesForLen;
357 : uint32_t totalLen;
358 :
359 : // Only tags < 31 supported. The implication of this is that encoded tags are exactly 1 byte long.
360 87283 : VerifyOrReturnError(tag < 0x1F, ASN1_ERROR_UNSUPPORTED_ENCODING);
361 :
362 : // Only positive and kUnknownLength values are supported for len input.
363 87283 : VerifyOrReturnError(len >= 0 || len == kUnknownLength, ASN1_ERROR_UNSUPPORTED_ENCODING);
364 :
365 : // Compute the number of bytes required to encode the length.
366 87283 : bytesForLen = BytesForLength(len);
367 :
368 : // Make sure there's enough space to encode the entire value.
369 : // Note that the calculated total length doesn't overflow because `len` is a signed value (int32_t).
370 : // Note that if `len` is not kUnknownLength then it is non-negative (`len` >= 0).
371 87283 : totalLen = 1 + bytesForLen + static_cast<uint32_t>(len != kUnknownLength ? len : 0);
372 87283 : VerifyOrReturnError((mWritePoint + totalLen) <= mBufEnd, ASN1_ERROR_OVERFLOW);
373 :
374 : // Write the tag byte.
375 87277 : *mWritePoint++ = cls | static_cast<uint8_t>(isConstructed ? 0x20 : 0) | tag;
376 :
377 : // Encode the length if it is known.
378 87277 : if (len != kUnknownLength)
379 : {
380 41945 : EncodeLength(mWritePoint, bytesForLen, len);
381 : }
382 : // ... otherwise place a marker in the first byte of the length to indicate that the length is unknown
383 : // and save a pointer to the length field in the deferred-length array.
384 : //
385 : // The deferred-length is an array of "pointers" to length fields for which the length of the
386 : // element was unknown at the time the element head was written. Examples include constructed
387 : // types such as SEQUENCE and SET, as well non-constructed types that encapsulate other ASN.1 types
388 : // (e.g. OCTET STRINGS that contain BER/DER encodings). The final lengths are filled in later,
389 : // at the time the encoding of the element is complete (e.g. when EndConstructed() is called).
390 : else
391 : {
392 45332 : VerifyOrReturnError(mDeferredLengthCount < kMaxDeferredLengthDepth, ASN1_ERROR_INVALID_STATE);
393 :
394 45332 : *mWritePoint = kUnknownLengthMarker;
395 45332 : mDeferredLengthLocations[mDeferredLengthCount++] = mWritePoint;
396 : }
397 :
398 87277 : mWritePoint += bytesForLen;
399 :
400 87277 : return CHIP_NO_ERROR;
401 : }
402 :
403 80547 : CHIP_ERROR ASN1Writer::WriteDeferredLength()
404 : {
405 80547 : ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR);
406 :
407 45077 : VerifyOrReturnError(mDeferredLengthCount > 0, ASN1_ERROR_INVALID_STATE);
408 :
409 45077 : uint8_t * lenField = mDeferredLengthLocations[mDeferredLengthCount - 1];
410 :
411 45077 : VerifyOrReturnError(*lenField == kUnknownLengthMarker, ASN1_ERROR_INVALID_STATE);
412 :
413 : // Compute the length of the element's value.
414 45077 : size_t elemLen = static_cast<size_t>((mWritePoint - lenField) - kLengthFieldReserveSize);
415 :
416 45077 : VerifyOrReturnError(CanCastTo<int32_t>(elemLen), ASN1_ERROR_LENGTH_OVERFLOW);
417 :
418 45077 : uint8_t bytesForLen = BytesForLength(static_cast<int32_t>(elemLen));
419 :
420 : // Move the element data if the number of bytes consumed by the final length field
421 : // is different than the space that was reserved for the field.
422 45077 : if (bytesForLen != kLengthFieldReserveSize)
423 : {
424 3258 : mWritePoint += (bytesForLen - kLengthFieldReserveSize);
425 :
426 3258 : VerifyOrReturnError(mWritePoint <= mBufEnd, ASN1_ERROR_OVERFLOW);
427 :
428 3258 : memmove(lenField + bytesForLen, lenField + kLengthFieldReserveSize, elemLen);
429 : }
430 :
431 : // Encode the final length of the element, overwriting the unknown length marker
432 : // in the process.
433 45077 : EncodeLength(lenField, bytesForLen, static_cast<int32_t>(elemLen));
434 :
435 45077 : mDeferredLengthCount--;
436 :
437 45077 : return CHIP_NO_ERROR;
438 : }
439 :
440 : /**
441 : * Returns the number of bytes required to encode the length value.
442 : *
443 : * @param[in] len Parameter, which encoding length to be calculated.
444 : *
445 : * @return number of bytes required to encode the length value.
446 : */
447 132360 : uint8_t ASN1Writer::BytesForLength(int32_t len)
448 : {
449 132360 : if (len == kUnknownLength)
450 45332 : return kLengthFieldReserveSize;
451 87028 : if (len < 128)
452 83770 : return 1;
453 3258 : if (len < 256)
454 1576 : return 2;
455 1682 : if (len < 65536)
456 1682 : return 3;
457 0 : if (len < (1 << 24))
458 0 : return 4;
459 0 : return 5;
460 : }
461 :
462 87022 : void ASN1Writer::EncodeLength(uint8_t * buf, uint8_t bytesForLen, int32_t lenToEncode)
463 : {
464 87022 : if (bytesForLen == 1)
465 : {
466 83764 : buf[0] = static_cast<uint8_t>(lenToEncode);
467 : }
468 : else
469 : {
470 3258 : --bytesForLen;
471 3258 : buf[0] = 0x80 | bytesForLen;
472 : do
473 : {
474 4940 : buf[bytesForLen] = static_cast<uint8_t>(lenToEncode);
475 4940 : lenToEncode >>= 8;
476 4940 : } while (--bytesForLen);
477 : }
478 87022 : }
479 :
480 35515 : void ASN1Writer::WriteData(const uint8_t * p, size_t len)
481 : {
482 35515 : memcpy(mWritePoint, p, len);
483 35515 : mWritePoint += len;
484 35515 : }
485 :
486 : } // namespace ASN1
487 : } // namespace chip
|