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