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 1856 : void ASN1Writer::Init(uint8_t * buf, size_t maxLen)
53 : {
54 1856 : mBuf = buf;
55 1856 : mWritePoint = buf;
56 1856 : mBufEnd = buf + maxLen;
57 1856 : mDeferredLengthCount = 0;
58 1856 : }
59 :
60 2843 : void ASN1Writer::InitNullWriter()
61 : {
62 2843 : mBuf = nullptr;
63 2843 : mWritePoint = nullptr;
64 2843 : mBufEnd = nullptr;
65 2843 : mDeferredLengthCount = 0;
66 2843 : }
67 :
68 1769 : size_t ASN1Writer::GetLengthWritten() const
69 : {
70 1769 : return (mBuf != nullptr) ? static_cast<size_t>(mWritePoint - mBuf) : 0;
71 : }
72 :
73 3276 : CHIP_ERROR ASN1Writer::PutInteger(int64_t val)
74 : {
75 3276 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
76 :
77 : uint8_t encodedVal[sizeof(int64_t)];
78 : uint8_t valStart, valLen;
79 :
80 2019 : BigEndian::Put64(encodedVal, static_cast<uint64_t>(val));
81 :
82 16088 : for (valStart = 0; valStart < 7; valStart++)
83 : {
84 14103 : if (encodedVal[valStart] == 0x00 && (encodedVal[valStart + 1] & 0x80) == 0)
85 14054 : continue;
86 49 : if (encodedVal[valStart] == 0xFF && (encodedVal[valStart + 1] & 0x80) == 0x80)
87 15 : continue;
88 34 : break;
89 : }
90 2019 : valLen = static_cast<uint8_t>(8 - valStart);
91 :
92 2019 : return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false, encodedVal + valStart, valLen);
93 : }
94 :
95 8833 : CHIP_ERROR ASN1Writer::PutBoolean(bool val)
96 : {
97 8833 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
98 :
99 5300 : ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Boolean, false, 1));
100 :
101 5300 : *mWritePoint++ = (val) ? 0xFF : 0;
102 :
103 5300 : return CHIP_NO_ERROR;
104 : }
105 :
106 36603 : CHIP_ERROR ASN1Writer::PutObjectId(const uint8_t * val, uint16_t valLen)
107 : {
108 36603 : return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId, false, val, valLen);
109 : }
110 :
111 9773 : CHIP_ERROR ASN1Writer::PutString(uint8_t tag, const char * val, uint16_t valLen)
112 : {
113 9773 : return PutValue(kASN1TagClass_Universal, tag, false, (const uint8_t *) val, valLen);
114 : }
115 :
116 2930 : CHIP_ERROR ASN1Writer::PutOctetString(const uint8_t * val, uint16_t valLen)
117 : {
118 2930 : return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_OctetString, false, val, valLen);
119 : }
120 :
121 2906 : CHIP_ERROR ASN1Writer::PutOctetString(uint8_t cls, uint8_t tag, const uint8_t * val, uint16_t valLen)
122 : {
123 2906 : 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 1774 : static uint8_t ReverseBits(uint8_t v)
132 : {
133 : // swap adjacent bits
134 1774 : 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 1774 : v = static_cast<uint8_t>(static_cast<uint8_t>((v >> 2) & 0x33) | static_cast<uint8_t>((v & 0x33) << 2));
137 : // swap nibbles
138 1774 : v = static_cast<uint8_t>(static_cast<uint8_t>(v >> 4) | static_cast<uint8_t>(v << 4));
139 1774 : return v;
140 : }
141 :
142 1771 : static uint8_t HighestBit(uint32_t v)
143 : {
144 1771 : uint32_t highestBit = 0;
145 :
146 1771 : if (v > 0xFFFF)
147 : {
148 0 : highestBit = 16;
149 0 : v >>= 16;
150 : }
151 1771 : if (v > 0xFF)
152 : {
153 0 : highestBit |= 8;
154 0 : v >>= 8;
155 : }
156 1771 : if (v > 0xF)
157 : {
158 893 : highestBit |= 4;
159 893 : v >>= 4;
160 : }
161 1771 : if (v > 0x3)
162 : {
163 890 : highestBit |= 2;
164 890 : v >>= 2;
165 : }
166 1771 : highestBit |= (v >> 1);
167 :
168 1771 : return static_cast<uint8_t>(highestBit);
169 : }
170 :
171 2955 : CHIP_ERROR ASN1Writer::PutBitString(uint32_t val)
172 : {
173 2955 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
174 :
175 : uint8_t len;
176 1772 : if (val == 0)
177 1 : len = 1;
178 1771 : else if (val < 256)
179 1768 : 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 1772 : ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, len));
188 :
189 1772 : if (val == 0)
190 : {
191 1 : mWritePoint[0] = 0;
192 : }
193 : else
194 : {
195 1771 : mWritePoint[1] = ReverseBits(static_cast<uint8_t>(val));
196 1771 : 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 1771 : mWritePoint[0] = static_cast<uint8_t>(7 - HighestBit(val));
212 : }
213 :
214 1772 : mWritePoint += len;
215 :
216 1772 : return CHIP_NO_ERROR;
217 : }
218 :
219 2956 : CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, const uint8_t * encodedBits, uint16_t encodedBitsLen)
220 : {
221 2956 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
222 :
223 1777 : ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, encodedBitsLen + 1));
224 :
225 1777 : *mWritePoint++ = unusedBitCount;
226 :
227 1777 : WriteData(encodedBits, encodedBitsLen);
228 :
229 1777 : 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 6003 : CHIP_ERROR ASN1Writer::PutTime(const ASN1UniversalTime & val)
252 : {
253 6003 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
254 :
255 : char buf[ASN1UniversalTime::kASN1TimeStringMaxLength];
256 3612 : MutableCharSpan bufSpan(buf);
257 : uint8_t tag;
258 :
259 3612 : ReturnErrorOnFailure(val.ExportTo_ASN1_TIME_string(bufSpan));
260 :
261 3612 : if (val.Year >= 2050)
262 : {
263 12 : tag = kASN1UniversalTag_GeneralizedTime;
264 : }
265 : else
266 : {
267 3600 : tag = kASN1UniversalTag_UTCTime;
268 : }
269 3612 : 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 75254 : CHIP_ERROR ASN1Writer::StartConstructedType(uint8_t cls, uint8_t tag)
290 : {
291 75254 : return EncodeHead(cls, tag, true, kUnknownLength);
292 : }
293 :
294 74849 : CHIP_ERROR ASN1Writer::EndConstructedType()
295 : {
296 74849 : return WriteDeferredLength();
297 : }
298 :
299 12926 : CHIP_ERROR ASN1Writer::StartEncapsulatedType(uint8_t cls, uint8_t tag, bool bitStringEncoding)
300 : {
301 12926 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
302 :
303 8010 : 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 8010 : if (bitStringEncoding)
309 : {
310 93 : VerifyOrReturnError(mWritePoint < mBufEnd, ASN1_ERROR_OVERFLOW);
311 93 : *mWritePoint++ = 0;
312 : }
313 :
314 8010 : return CHIP_NO_ERROR;
315 : }
316 :
317 12898 : CHIP_ERROR ASN1Writer::EndEncapsulatedType()
318 : {
319 12898 : return WriteDeferredLength();
320 : }
321 :
322 60924 : CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, const uint8_t * val, uint16_t valLen)
323 : {
324 60924 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
325 :
326 37129 : ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, valLen));
327 :
328 37123 : WriteData(val, valLen);
329 :
330 37123 : 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 129245 : CHIP_ERROR ASN1Writer::EncodeHead(uint8_t cls, uint8_t tag, bool isConstructed, int32_t len)
350 : {
351 129245 : 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 95658 : VerifyOrReturnError(tag < 0x1F, ASN1_ERROR_UNSUPPORTED_ENCODING);
358 :
359 : // Only positive and kUnknownLength values are supported for len input.
360 95658 : VerifyOrReturnError(len >= 0 || len == kUnknownLength, ASN1_ERROR_UNSUPPORTED_ENCODING);
361 :
362 : // Compute the number of bytes required to encode the length.
363 95658 : 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 95658 : totalLen = 1 + bytesForLen + static_cast<uint32_t>(len != kUnknownLength ? len : 0);
369 95658 : VerifyOrReturnError((mWritePoint + totalLen) <= mBufEnd, ASN1_ERROR_OVERFLOW);
370 :
371 : // Write the tag byte.
372 95652 : *mWritePoint++ = cls | static_cast<uint8_t>(isConstructed ? 0x20 : 0) | tag;
373 :
374 : // Encode the length if it is known.
375 95652 : if (len != kUnknownLength)
376 : {
377 45975 : 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 49677 : VerifyOrReturnError(mDeferredLengthCount < kMaxDeferredLengthDepth, ASN1_ERROR_INVALID_STATE);
390 :
391 49677 : *mWritePoint = kUnknownLengthMarker;
392 49677 : mDeferredLengthLocations[mDeferredLengthCount++] = mWritePoint;
393 : }
394 :
395 95652 : mWritePoint += bytesForLen;
396 :
397 95652 : return CHIP_NO_ERROR;
398 : }
399 :
400 87747 : CHIP_ERROR ASN1Writer::WriteDeferredLength()
401 : {
402 87747 : VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR);
403 :
404 49422 : VerifyOrReturnError(mDeferredLengthCount > 0, ASN1_ERROR_INVALID_STATE);
405 :
406 49422 : uint8_t * lenField = mDeferredLengthLocations[mDeferredLengthCount - 1];
407 :
408 49422 : VerifyOrReturnError(*lenField == kUnknownLengthMarker, ASN1_ERROR_INVALID_STATE);
409 :
410 : // Compute the length of the element's value.
411 49422 : size_t elemLen = static_cast<size_t>((mWritePoint - lenField) - kLengthFieldReserveSize);
412 :
413 49422 : VerifyOrReturnError(CanCastTo<int32_t>(elemLen), ASN1_ERROR_LENGTH_OVERFLOW);
414 :
415 49422 : 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 49422 : if (bytesForLen != kLengthFieldReserveSize)
420 : {
421 3574 : mWritePoint += (bytesForLen - kLengthFieldReserveSize);
422 :
423 3574 : VerifyOrReturnError(mWritePoint <= mBufEnd, ASN1_ERROR_OVERFLOW);
424 :
425 3574 : 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 49422 : EncodeLength(lenField, bytesForLen, static_cast<int32_t>(elemLen));
431 :
432 49422 : mDeferredLengthCount--;
433 :
434 49422 : 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 145080 : uint8_t ASN1Writer::BytesForLength(int32_t len)
445 : {
446 145080 : if (len == kUnknownLength)
447 49677 : return kLengthFieldReserveSize;
448 95403 : if (len < 128)
449 91829 : return 1;
450 3574 : if (len < 256)
451 1734 : return 2;
452 1840 : if (len < 65536)
453 1840 : return 3;
454 0 : if (len < (1 << 24))
455 0 : return 4;
456 0 : return 5;
457 : }
458 :
459 95397 : void ASN1Writer::EncodeLength(uint8_t * buf, uint8_t bytesForLen, int32_t lenToEncode)
460 : {
461 95397 : if (bytesForLen == 1)
462 : {
463 91823 : buf[0] = static_cast<uint8_t>(lenToEncode);
464 : }
465 : else
466 : {
467 3574 : --bytesForLen;
468 3574 : buf[0] = 0x80 | bytesForLen;
469 : do
470 : {
471 5414 : buf[bytesForLen] = static_cast<uint8_t>(lenToEncode);
472 5414 : lenToEncode >>= 8;
473 5414 : } while (--bytesForLen);
474 : }
475 95397 : }
476 :
477 38913 : void ASN1Writer::WriteData(const uint8_t * p, size_t len)
478 : {
479 38913 : memcpy(mWritePoint, p, len);
480 38913 : mWritePoint += len;
481 38913 : }
482 :
483 : } // namespace ASN1
484 : } // namespace chip
|