Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2022 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 defines types and objects for reading and writing
23 : * Abstract Syntax Notation One (ASN.1) encoded data.
24 : *
25 : */
26 :
27 : #pragma once
28 :
29 : #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 : #include <asn1/ASN1OID.h>
31 : #endif
32 :
33 : #include <lib/asn1/ASN1Error.h>
34 : #include <lib/support/DLLUtil.h>
35 : #include <lib/support/Span.h>
36 :
37 : namespace chip {
38 : namespace TLV {
39 : class TLVReader;
40 : }
41 : } // namespace chip
42 :
43 : /**
44 : * @namespace chip::ASN1
45 : *
46 : * @brief
47 : * This namespace includes all interfaces within CHIP for
48 : * working with Abstract Syntax Notation One (ASN.1).
49 : */
50 :
51 : namespace chip {
52 : namespace ASN1 {
53 :
54 : static constexpr size_t kMaxConstructedAndEncapsulatedTypesDepth = 10;
55 :
56 : enum ASN1TagClasses
57 : {
58 : kASN1TagClass_Universal = 0x00,
59 : kASN1TagClass_Application = 0x40,
60 : kASN1TagClass_ContextSpecific = 0x80,
61 : kASN1TagClass_Private = 0xC0
62 : };
63 :
64 : enum ASN1UniversalTags : uint8_t
65 : {
66 : kASN1UniversalTag_Boolean = 1,
67 : kASN1UniversalTag_Integer = 2,
68 : kASN1UniversalTag_BitString = 3,
69 : kASN1UniversalTag_OctetString = 4,
70 : kASN1UniversalTag_Null = 5,
71 : kASN1UniversalTag_ObjectId = 6,
72 : kASN1UniversalTag_ObjectDesc = 7,
73 : kASN1UniversalTag_External = 8,
74 : kASN1UniversalTag_Real = 9,
75 : kASN1UniversalTag_Enumerated = 10,
76 : kASN1UniversalTag_UTF8String = 12,
77 : kASN1UniversalTag_Sequence = 16,
78 : kASN1UniversalTag_Set = 17,
79 : kASN1UniversalTag_NumericString = 18,
80 : kASN1UniversalTag_PrintableString = 19,
81 : kASN1UniversalTag_T61String = 20,
82 : kASN1UniversalTag_VideotexString = 21,
83 : kASN1UniversalTag_IA5String = 22,
84 : kASN1UniversalTag_UTCTime = 23,
85 : kASN1UniversalTag_GeneralizedTime = 24,
86 : kASN1UniversalTag_GraphicString = 25,
87 : kASN1UniversalTag_VisibleString = 26,
88 : kASN1UniversalTag_GeneralString = 27,
89 : kASN1UniversalTag_UniversalString = 28
90 : };
91 :
92 : /**
93 : * @struct ASN1UniversalTime
94 : *
95 : * @brief
96 : * A data structure representing ASN1 universal time in a calendar format.
97 : */
98 : struct ASN1UniversalTime
99 : {
100 : uint16_t Year; /**< Year component. Legal interval is 0..9999. */
101 : uint8_t Month; /**< Month component. Legal interval is 1..12. */
102 : uint8_t Day; /**< Day of month component. Legal interval is 1..31. */
103 : uint8_t Hour; /**< Hour component. Legal interval is 0..23. */
104 : uint8_t Minute; /**< Minute component. Legal interval is 0..59. */
105 : uint8_t Second; /**< Second component. Legal interval is 0..59. */
106 :
107 : static constexpr size_t kASN1UTCTimeStringLength = 13;
108 : static constexpr size_t kASN1GeneralizedTimeStringLength = 15;
109 : static constexpr size_t kASN1TimeStringMaxLength = 15;
110 :
111 : /**
112 : * @brief Set time from ASN1_TIME string.
113 : * Two string formats are supported:
114 : * YYMMDDHHMMSSZ - for years in the range 1950 - 2049
115 : * YYYYMMDDHHMMSSZ - other years
116 : **/
117 : CHIP_ERROR ImportFrom_ASN1_TIME_string(const CharSpan & asn1_time);
118 :
119 : /**
120 : * @brief Encode time as an ASN1_TIME string.
121 : * Two string formats are supported:
122 : * YYMMDDHHMMSSZ - for years in the range 1950 - 2049
123 : * YYYYMMDDHHMMSSZ - other years
124 : **/
125 : CHIP_ERROR ExportTo_ASN1_TIME_string(MutableCharSpan & asn1_time) const;
126 :
127 : /**
128 : * @brief Encode time as Unix epoch time.
129 : **/
130 : bool ExportTo_UnixTime(uint32_t & unixEpoch);
131 : };
132 :
133 : class DLL_EXPORT ASN1Reader
134 : {
135 : public:
136 : void Init(const uint8_t * buf, size_t len);
137 209 : void Init(const ByteSpan & data) { Init(data.data(), data.size()); }
138 : template <size_t N>
139 : void Init(const uint8_t (&data)[N])
140 : {
141 : Init(data, N);
142 : }
143 :
144 11030 : uint8_t GetClass(void) const { return Class; };
145 11030 : uint8_t GetTag(void) const { return Tag; };
146 2233 : const uint8_t * GetValue(void) const { return Value; };
147 2422 : uint32_t GetValueLen(void) const { return ValueLen; };
148 93 : bool IsConstructed(void) const { return Constructed; };
149 0 : bool IsIndefiniteLen(void) const { return IndefiniteLen; };
150 0 : bool IsEndOfContents(void) const { return EndOfContents; };
151 :
152 : CHIP_ERROR Next(void);
153 : CHIP_ERROR EnterConstructedType(void);
154 : CHIP_ERROR ExitConstructedType(void);
155 : CHIP_ERROR GetConstructedType(const uint8_t *& val, uint32_t & valLen);
156 : CHIP_ERROR EnterEncapsulatedType(void);
157 : CHIP_ERROR ExitEncapsulatedType(void);
158 : bool IsContained(void) const;
159 : CHIP_ERROR GetInteger(int64_t & val);
160 : CHIP_ERROR GetBoolean(bool & val);
161 : CHIP_ERROR GetObjectId(OID & oid);
162 : CHIP_ERROR GetUTCTime(ASN1UniversalTime & outTime);
163 : CHIP_ERROR GetGeneralizedTime(ASN1UniversalTime & outTime);
164 : CHIP_ERROR GetBitString(uint32_t & outVal);
165 :
166 : private:
167 : static constexpr size_t kMaxContextDepth = kMaxConstructedAndEncapsulatedTypesDepth;
168 :
169 : struct ASN1ParseContext
170 : {
171 : const uint8_t * ElemStart;
172 : uint32_t HeadLen;
173 : uint32_t ValueLen;
174 : bool IndefiniteLen;
175 : const uint8_t * ContainerEnd;
176 : };
177 :
178 : uint8_t Class;
179 : uint8_t Tag;
180 : const uint8_t * Value;
181 : uint32_t ValueLen;
182 : bool Constructed;
183 : bool IndefiniteLen;
184 : bool EndOfContents;
185 :
186 : const uint8_t * mBuf;
187 : const uint8_t * mBufEnd;
188 : const uint8_t * mElemStart;
189 : const uint8_t * mContainerEnd;
190 : uint32_t mHeadLen;
191 : ASN1ParseContext mSavedContexts[kMaxContextDepth];
192 : uint32_t mNumSavedContexts;
193 :
194 : CHIP_ERROR DecodeHead(void);
195 : void ResetElementState(void);
196 : CHIP_ERROR EnterContainer(uint32_t offset);
197 : CHIP_ERROR ExitContainer(void);
198 : };
199 :
200 : class DLL_EXPORT ASN1Writer
201 : {
202 : public:
203 : void Init(uint8_t * buf, size_t maxLen);
204 211 : void Init(const MutableByteSpan & data) { Init(data.data(), data.size()); }
205 : template <size_t N>
206 : void Init(uint8_t (&data)[N])
207 : {
208 : Init(data, N);
209 : }
210 : void InitNullWriter(void);
211 : size_t GetLengthWritten(void) const;
212 :
213 291382 : bool IsNullWriter() const { return mBuf == nullptr; }
214 :
215 : CHIP_ERROR PutInteger(int64_t val);
216 : CHIP_ERROR PutBoolean(bool val);
217 : CHIP_ERROR PutObjectId(const uint8_t * val, uint16_t valLen);
218 : CHIP_ERROR PutObjectId(OID oid);
219 : CHIP_ERROR PutString(uint8_t tag, const char * val, uint16_t valLen);
220 : CHIP_ERROR PutOctetString(const uint8_t * val, uint16_t valLen);
221 : CHIP_ERROR PutOctetString(uint8_t cls, uint8_t tag, const uint8_t * val, uint16_t valLen);
222 : CHIP_ERROR PutOctetString(uint8_t cls, uint8_t tag, chip::TLV::TLVReader & tlvReader);
223 : CHIP_ERROR PutBitString(uint32_t val);
224 : CHIP_ERROR PutBitString(uint8_t unusedBits, const uint8_t * val, uint16_t valLen);
225 : CHIP_ERROR PutBitString(uint8_t unusedBits, chip::TLV::TLVReader & tlvReader);
226 : CHIP_ERROR PutTime(const ASN1UniversalTime & val);
227 : CHIP_ERROR PutNull(void);
228 : CHIP_ERROR PutConstructedType(const uint8_t * val, uint16_t valLen);
229 : CHIP_ERROR StartConstructedType(uint8_t cls, uint8_t tag);
230 : CHIP_ERROR EndConstructedType(void);
231 : CHIP_ERROR StartEncapsulatedType(uint8_t cls, uint8_t tag, bool bitStringEncoding);
232 : CHIP_ERROR EndEncapsulatedType(void);
233 : CHIP_ERROR PutValue(uint8_t cls, uint8_t tag, bool isConstructed, const uint8_t * val, uint16_t valLen);
234 : CHIP_ERROR PutValue(uint8_t cls, uint8_t tag, bool isConstructed, chip::TLV::TLVReader & tlvReader);
235 :
236 : private:
237 : static constexpr size_t kMaxDeferredLengthDepth = kMaxConstructedAndEncapsulatedTypesDepth;
238 :
239 : uint8_t * mBuf;
240 : uint8_t * mBufEnd;
241 : uint8_t * mWritePoint;
242 : uint8_t * mDeferredLengthLocations[kMaxDeferredLengthDepth];
243 : uint8_t mDeferredLengthCount;
244 :
245 : CHIP_ERROR EncodeHead(uint8_t cls, uint8_t tag, bool isConstructed, int32_t len);
246 : CHIP_ERROR WriteDeferredLength(void);
247 : static uint8_t BytesForLength(int32_t len);
248 : static void EncodeLength(uint8_t * buf, uint8_t bytesForLen, int32_t lenToEncode);
249 : void WriteData(const uint8_t * p, size_t len);
250 : };
251 :
252 : OID ParseObjectID(const uint8_t * encodedOID, uint16_t encodedOIDLen);
253 : bool GetEncodedObjectID(OID oid, const uint8_t *& encodedOID, uint16_t & encodedOIDLen);
254 :
255 : OIDCategory GetOIDCategory(OID oid);
256 :
257 : const char * GetOIDName(OID oid);
258 :
259 : CHIP_ERROR DumpASN1(ASN1Reader & reader, const char * prefix, const char * indent);
260 :
261 29347 : inline OID GetOID(OIDCategory category, uint8_t id)
262 : {
263 29347 : return static_cast<OID>(category | id);
264 : }
265 :
266 870 : inline uint8_t GetOIDEnum(OID oid)
267 : {
268 870 : return static_cast<uint8_t>(oid & kOID_EnumMask);
269 : }
270 :
271 : } // namespace ASN1
272 : } // namespace chip
|