Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / lib / asn1 / ASN1.h
1 /*
2  *
3  *    Copyright (c) 2020 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 #include <support/DLLUtil.h>
30
31 #include <asn1/ASN1Error.h>
32
33 namespace chip {
34 namespace TLV {
35 class TLVReader;
36 }
37 } // namespace chip
38
39 /**
40  *   @namespace chip::ASN1
41  *
42  *   @brief
43  *     This namespace includes all interfaces within CHIP for
44  *     working with Abstract Syntax Notation One (ASN.1).
45  */
46
47 namespace chip {
48 namespace ASN1 {
49
50 #ifndef DOXYGEN_SHOULD_SKIP_THIS
51 #include <asn1/ASN1OID.h>
52 #endif
53
54 enum ASN1TagClasses
55 {
56     kASN1TagClass_Universal       = 0x00,
57     kASN1TagClass_Application     = 0x40,
58     kASN1TagClass_ContextSpecific = 0x80,
59     kASN1TagClass_Private         = 0xC0
60 };
61
62 enum ASN1UniversalTags
63 {
64     kASN1UniversalTag_Boolean         = 1,
65     kASN1UniversalTag_Integer         = 2,
66     kASN1UniversalTag_BitString       = 3,
67     kASN1UniversalTag_OctetString     = 4,
68     kASN1UniversalTag_Null            = 5,
69     kASN1UniversalTag_ObjectId        = 6,
70     kASN1UniversalTag_ObjectDesc      = 7,
71     kASN1UniversalTag_External        = 8,
72     kASN1UniversalTag_Real            = 9,
73     kASN1UniversalTag_Enumerated      = 10,
74     kASN1UniversalTag_UTF8String      = 12,
75     kASN1UniversalTag_Sequence        = 16,
76     kASN1UniversalTag_Set             = 17,
77     kASN1UniversalTag_NumericString   = 18,
78     kASN1UniversalTag_PrintableString = 19,
79     kASN1UniversalTag_T61String       = 20,
80     kASN1UniversalTag_VideotexString  = 21,
81     kASN1UniversalTag_IA5String       = 22,
82     kASN1UniversalTag_UTCTime         = 23,
83     kASN1UniversalTag_GeneralizedTime = 24,
84     kASN1UniversalTag_GraphicString   = 25,
85     kASN1UniversalTag_VisibleString   = 26,
86     kASN1UniversalTag_GeneralString   = 27,
87     kASN1UniversalTag_UniversalString = 28
88 };
89
90 struct ASN1UniversalTime
91 {
92     uint16_t Year;
93     uint8_t Month;
94     uint8_t Day;
95     uint8_t Hour;
96     uint8_t Minute;
97     uint8_t Second;
98 };
99
100 class DLL_EXPORT ASN1Reader
101 {
102 public:
103     void Init(const uint8_t * buf, uint32_t len);
104
105     uint8_t GetClass(void) const { return Class; };
106     uint32_t GetTag(void) const { return Tag; };
107     const uint8_t * GetValue(void) const { return Value; };
108     uint32_t GetValueLen(void) const { return ValueLen; };
109     bool IsConstructed(void) const { return Constructed; };
110     bool IsIndefiniteLen(void) const { return IndefiniteLen; };
111     bool IsEndOfContents(void) const { return EndOfContents; };
112
113     ASN1_ERROR Next(void);
114     ASN1_ERROR EnterConstructedType(void);
115     ASN1_ERROR ExitConstructedType(void);
116     ASN1_ERROR EnterEncapsulatedType(void);
117     ASN1_ERROR ExitEncapsulatedType(void);
118     bool IsContained(void) const;
119     ASN1_ERROR GetInteger(int64_t & val);
120     ASN1_ERROR GetBoolean(bool & val);
121     ASN1_ERROR GetObjectId(OID & oid);
122     ASN1_ERROR GetUTCTime(ASN1UniversalTime & outTime);
123     ASN1_ERROR GetGeneralizedTime(ASN1UniversalTime & outTime);
124     ASN1_ERROR GetBitString(uint32_t & outVal);
125
126 private:
127     static constexpr size_t kMaxContextDepth = 32;
128
129     struct ASN1ParseContext
130     {
131         const uint8_t * ElemStart;
132         uint32_t HeadLen;
133         uint32_t ValueLen;
134         bool IndefiniteLen;
135         const uint8_t * ContainerEnd;
136     };
137
138     uint8_t Class;
139     uint32_t Tag;
140     const uint8_t * Value;
141     uint32_t ValueLen;
142     bool Constructed;
143     bool IndefiniteLen;
144     bool EndOfContents;
145
146     const uint8_t * mBuf;
147     const uint8_t * mBufEnd;
148     const uint8_t * mElemStart;
149     const uint8_t * mContainerEnd;
150     uint32_t mHeadLen;
151     ASN1ParseContext mSavedContexts[kMaxContextDepth];
152     uint32_t mNumSavedContexts;
153
154     ASN1_ERROR DecodeHead(void);
155     void ResetElementState(void);
156     ASN1_ERROR EnterContainer(uint32_t offset);
157     ASN1_ERROR ExitContainer(void);
158 };
159
160 class DLL_EXPORT ASN1Writer
161 {
162 public:
163     void Init(uint8_t * buf, uint32_t maxLen);
164     void InitNullWriter(void);
165     ASN1_ERROR Finalize(void);
166     uint16_t GetLengthWritten(void) const;
167
168     ASN1_ERROR PutInteger(int64_t val);
169     ASN1_ERROR PutBoolean(bool val);
170     ASN1_ERROR PutObjectId(const uint8_t * val, uint16_t valLen);
171     ASN1_ERROR PutObjectId(OID oid);
172     ASN1_ERROR PutString(uint32_t tag, const char * val, uint16_t valLen);
173     ASN1_ERROR PutOctetString(const uint8_t * val, uint16_t valLen);
174     ASN1_ERROR PutOctetString(uint8_t cls, uint32_t tag, const uint8_t * val, uint16_t valLen);
175     ASN1_ERROR PutOctetString(uint8_t cls, uint32_t tag, chip::TLV::TLVReader & val);
176     ASN1_ERROR PutBitString(uint32_t val);
177     ASN1_ERROR PutBitString(uint8_t unusedBits, const uint8_t * val, uint16_t valLen);
178     ASN1_ERROR PutBitString(uint8_t unusedBits, chip::TLV::TLVReader & val);
179     ASN1_ERROR PutTime(const ASN1UniversalTime & val);
180     ASN1_ERROR PutNull(void);
181     ASN1_ERROR StartConstructedType(uint8_t cls, uint32_t tag);
182     ASN1_ERROR EndConstructedType(void);
183     ASN1_ERROR StartEncapsulatedType(uint8_t cls, uint32_t tag, bool bitStringEncoding);
184     ASN1_ERROR EndEncapsulatedType(void);
185     ASN1_ERROR PutValue(uint8_t cls, uint32_t tag, bool isConstructed, const uint8_t * val, uint16_t valLen);
186     ASN1_ERROR PutValue(uint8_t cls, uint32_t tag, bool isConstructed, chip::TLV::TLVReader & val);
187
188 private:
189     uint8_t * mBuf;
190     uint8_t * mBufEnd;
191     uint8_t * mWritePoint;
192     uint8_t ** mDeferredLengthList;
193
194     ASN1_ERROR EncodeHead(uint8_t cls, uint32_t tag, bool isConstructed, int32_t len);
195     ASN1_ERROR WriteDeferredLength(void);
196     static uint8_t BytesForLength(int32_t len);
197     static void EncodeLength(uint8_t * buf, uint8_t bytesForLen, int32_t lenToEncode);
198 };
199
200 OID ParseObjectID(const uint8_t * encodedOID, uint16_t encodedOIDLen);
201 bool GetEncodedObjectID(OID oid, const uint8_t *& encodedOID, uint16_t & encodedOIDLen);
202
203 OIDCategory GetOIDCategory(OID oid);
204
205 const char * GetOIDName(OID oid);
206
207 ASN1_ERROR DumpASN1(ASN1Reader & reader, const char * prefix, const char * indent);
208
209 inline OID GetOID(OIDCategory category, uint8_t id)
210 {
211     return static_cast<OID>(category | id);
212 }
213
214 inline uint8_t GetOIDEnum(OID oid)
215 {
216     return static_cast<uint8_t>(oid & kOID_EnumMask);
217 }
218
219 } // namespace ASN1
220 } // namespace chip