• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #ifdef HITLS_BSL_OBJ
18 #include <stddef.h>
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "bsl_obj.h"
22 #include "bsl_obj_internal.h"
23 #include "bsl_err_internal.h"
24 #ifdef HITLS_BSL_HASH
25 #include "bsl_hash.h"
26 
27 #define BSL_OBJ_HASH_BKT_SIZE 256u
28 
29 BSL_HASH_Hash *g_oidHashTable = NULL;
30 
31 static BSL_SAL_ThreadLockHandle g_oidHashRwLock = NULL;
32 
33 static uint32_t g_oidHashInitOnce = BSL_SAL_ONCE_INIT;
34 #endif // HITLS_BSL_HASH
35 
36 BslOidInfo g_oidTable[] = {
37     {{9, "\140\206\110\1\145\3\4\1\2", BSL_OID_GLOBAL}, "AES128-CBC", BSL_CID_AES128_CBC},
38     {{9, "\140\206\110\1\145\3\4\1\26", BSL_OID_GLOBAL}, "AES192-CBC", BSL_CID_AES192_CBC},
39     {{9, "\140\206\110\1\145\3\4\1\52", BSL_OID_GLOBAL}, "AES256-CBC", BSL_CID_AES256_CBC},
40     {{9, "\52\206\110\206\367\15\1\1\1", BSL_OID_GLOBAL}, "RSAENCRYPTION", BSL_CID_RSA}, // rsa subkey
41     {{7, "\52\206\110\316\70\4\1", BSL_OID_GLOBAL}, "DSAENCRYPTION", BSL_CID_DSA}, // dsa subkey
42     {{8, "\52\206\110\206\367\15\2\5", BSL_OID_GLOBAL}, "MD5", BSL_CID_MD5},
43     {{5, "\53\16\3\2\32", BSL_OID_GLOBAL}, "SHA1", BSL_CID_SHA1},
44     {{9, "\140\206\110\1\145\3\4\2\4", BSL_OID_GLOBAL}, "SHA224", BSL_CID_SHA224},
45     {{9, "\140\206\110\1\145\3\4\2\1", BSL_OID_GLOBAL}, "SHA256", BSL_CID_SHA256},
46     {{9, "\140\206\110\1\145\3\4\2\2", BSL_OID_GLOBAL}, "SHA384", BSL_CID_SHA384},
47     {{9, "\140\206\110\1\145\3\4\2\3", BSL_OID_GLOBAL}, "SHA512", BSL_CID_SHA512},
48     {{8, "\53\6\1\5\5\10\1\1", BSL_OID_GLOBAL}, "HMAC-MD5", BSL_CID_HMAC_MD5},
49     {{8, "\52\206\110\206\367\15\2\7", BSL_OID_GLOBAL}, "HMAC-SHA1", BSL_CID_HMAC_SHA1},
50     {{8, "\52\206\110\206\367\15\2\10", BSL_OID_GLOBAL}, "HMAC-SHA224", BSL_CID_HMAC_SHA224},
51     {{8, "\52\206\110\206\367\15\2\11", BSL_OID_GLOBAL}, "HMAC-SHA256", BSL_CID_HMAC_SHA256},
52     {{8, "\52\206\110\206\367\15\2\12", BSL_OID_GLOBAL}, "HMAC-SHA384", BSL_CID_HMAC_SHA384},
53     {{8, "\52\206\110\206\367\15\2\13", BSL_OID_GLOBAL}, "HMAC-SHA512", BSL_CID_HMAC_SHA512},
54     {{9, "\52\206\110\206\367\15\1\1\4", BSL_OID_GLOBAL}, "MD5WITHRSA", BSL_CID_MD5WITHRSA},
55     {{9, "\52\206\110\206\367\15\1\1\5", BSL_OID_GLOBAL}, "SHA1WITHRSA", BSL_CID_SHA1WITHRSA},
56     {{7, "\52\206\110\316\70\4\3", BSL_OID_GLOBAL}, "DSAWITHSHA1", BSL_CID_DSAWITHSHA1},
57     {{7, "\52\206\110\316\75\4\1", BSL_OID_GLOBAL}, "ECDSAWITHSHA1", BSL_CID_ECDSAWITHSHA1},
58     {{8, "\52\206\110\316\75\4\3\1", BSL_OID_GLOBAL}, "ECDSAWITHSHA224", BSL_CID_ECDSAWITHSHA224},
59     {{8, "\52\206\110\316\75\4\3\2", BSL_OID_GLOBAL}, "ECDSAWITHSHA256", BSL_CID_ECDSAWITHSHA256},
60     {{8, "\52\206\110\316\75\4\3\3", BSL_OID_GLOBAL}, "ECDSAWITHSHA384", BSL_CID_ECDSAWITHSHA384},
61     {{8, "\52\206\110\316\75\4\3\4", BSL_OID_GLOBAL}, "ECDSAWITHSHA512", BSL_CID_ECDSAWITHSHA512},
62     {{9, "\52\206\110\206\367\15\1\1\13", BSL_OID_GLOBAL}, "SHA256WITHRSA", BSL_CID_SHA256WITHRSAENCRYPTION},
63     {{9, "\52\206\110\206\367\15\1\1\14", BSL_OID_GLOBAL}, "SHA384WITHRSA", BSL_CID_SHA384WITHRSAENCRYPTION},
64     {{9, "\52\206\110\206\367\15\1\1\15", BSL_OID_GLOBAL}, "SHA512WITHRSA", BSL_CID_SHA512WITHRSAENCRYPTION},
65     {{8, "\52\206\110\316\75\3\1\7", BSL_OID_GLOBAL}, "PRIME256V1", BSL_CID_PRIME256V1},
66     {{9, "\52\206\110\206\367\15\1\5\14", BSL_OID_GLOBAL}, "PBKDF2", BSL_CID_PBKDF2},
67     {{9, "\52\206\110\206\367\15\1\5\15", BSL_OID_GLOBAL}, "PBES2", BSL_CID_PBES2},
68     {{9, "\52\206\110\206\367\15\1\11\16", BSL_OID_GLOBAL}, "Requested Extensions", BSL_CID_EXTENSIONREQUEST},
69     {{3, "\125\4\4", BSL_OID_GLOBAL}, "SN", BSL_CID_AT_SURNAME},
70     {{3, "\125\4\52", BSL_OID_GLOBAL}, "GN", BSL_CID_AT_GIVENNAME},
71     {{3, "\125\4\53", BSL_OID_GLOBAL}, "initials", BSL_CID_AT_INITIALS},
72     {{3, "\125\4\54", BSL_OID_GLOBAL}, "generationQualifier", BSL_CID_AT_GENERATIONQUALIFIER},
73     {{3, "\125\4\3", BSL_OID_GLOBAL}, "CN", BSL_CID_AT_COMMONNAME},
74     {{3, "\125\4\7", BSL_OID_GLOBAL}, "L", BSL_CID_AT_LOCALITYNAME},
75     {{3, "\125\4\10", BSL_OID_GLOBAL}, "ST", BSL_CID_AT_STATEORPROVINCENAME},
76     {{3, "\125\4\12", BSL_OID_GLOBAL}, "O", BSL_CID_AT_ORGANIZATIONNAME},
77     {{3, "\125\4\13", BSL_OID_GLOBAL}, "OU", BSL_CID_AT_ORGANIZATIONALUNITNAME},
78     {{3, "\125\4\14", BSL_OID_GLOBAL}, "title", BSL_CID_AT_TITLE},
79     {{3, "\125\4\56", BSL_OID_GLOBAL}, "dnQualifier", BSL_CID_AT_DNQUALIFIER},
80     {{3, "\125\4\6", BSL_OID_GLOBAL}, "C", BSL_CID_AT_COUNTRYNAME},
81     {{3, "\125\4\5", BSL_OID_GLOBAL}, "serialNumber", BSL_CID_AT_SERIALNUMBER},
82     {{3, "\125\4\101", BSL_OID_GLOBAL}, "pseudonym", BSL_CID_AT_PSEUDONYM},
83     {{10, "\11\222\46\211\223\362\54\144\1\31", BSL_OID_GLOBAL}, "DC", BSL_CID_DOMAINCOMPONENT},
84     {{9, "\52\206\110\206\367\15\1\11\1", BSL_OID_GLOBAL}, "emailAddress", BSL_CID_EMAILADDRESS},
85     {{3, "\125\35\43", BSL_OID_GLOBAL}, "AuthorityKeyIdentifier", BSL_CID_CE_AUTHORITYKEYIDENTIFIER},
86     {{3, "\125\35\16", BSL_OID_GLOBAL}, "SubjectKeyIdentifier", BSL_CID_CE_SUBJECTKEYIDENTIFIER},
87     {{3, "\125\35\17", BSL_OID_GLOBAL}, "KeyUsage", BSL_CID_CE_KEYUSAGE},
88     {{3, "\125\35\21", BSL_OID_GLOBAL}, "SubjectAltName", BSL_CID_CE_SUBJECTALTNAME},
89     {{3, "\125\35\23", BSL_OID_GLOBAL}, "BasicConstraints", BSL_CID_CE_BASICCONSTRAINTS},
90     {{3, "\125\35\45", BSL_OID_GLOBAL}, "ExtendedKeyUsage", BSL_CID_CE_EXTKEYUSAGE},
91     {{8, "\53\6\1\5\5\7\3\1", BSL_OID_GLOBAL}, "ServerAuth", BSL_CID_KP_SERVERAUTH},
92     {{8, "\53\6\1\5\5\7\3\2", BSL_OID_GLOBAL}, "ClientAuth", BSL_CID_KP_CLIENTAUTH},
93     {{8, "\53\6\1\5\5\7\3\3", BSL_OID_GLOBAL}, "CodeSigning", BSL_CID_KP_CODESIGNING},
94     {{8, "\53\6\1\5\5\7\3\4", BSL_OID_GLOBAL}, "EmailProtection", BSL_CID_KP_EMAILPROTECTION},
95     {{8, "\53\6\1\5\5\7\3\10", BSL_OID_GLOBAL}, "TimeStamping", BSL_CID_KP_TIMESTAMPING},
96     {{8, "\53\6\1\5\5\7\3\11", BSL_OID_GLOBAL}, "OSCPSigning", BSL_CID_KP_OCSPSIGNING},
97     {{3, "\125\35\56", BSL_OID_GLOBAL}, "FreshestCRL", BSL_CID_CE_FRESHESTCRL},
98     {{3, "\125\35\24", BSL_OID_GLOBAL}, "CrlNumber", BSL_CID_CE_CRLNUMBER},
99     {{3, "\125\35\34", BSL_OID_GLOBAL}, "IssuingDistributionPoint", BSL_CID_CE_ISSUINGDISTRIBUTIONPOINT},
100     {{3, "\125\35\33", BSL_OID_GLOBAL}, "DeltaCrlIndicator", BSL_CID_CE_DELTACRLINDICATOR},
101     {{3, "\125\35\25", BSL_OID_GLOBAL}, "CrlReason", BSL_CID_CE_CRLREASONS},
102     {{3, "\125\35\35", BSL_OID_GLOBAL}, "CertificateIssuer", BSL_CID_CE_CERTIFICATEISSUER},
103     {{3, "\125\35\30", BSL_OID_GLOBAL}, "InvalidityDate", BSL_CID_CE_INVALIDITYDATE},
104     {{11, "\52\206\110\206\367\15\1\14\12\1\1", BSL_OID_GLOBAL}, "keyBag", BSL_CID_KEYBAG},
105     {{11, "\52\206\110\206\367\15\1\14\12\1\2", BSL_OID_GLOBAL}, "pkcs8shroudedkeyBag", BSL_CID_PKCS8SHROUDEDKEYBAG},
106     {{11, "\52\206\110\206\367\15\1\14\12\1\3", BSL_OID_GLOBAL}, "certBag", BSL_CID_CERTBAG},
107     {{11, "\52\206\110\206\367\15\1\14\12\1\4", BSL_OID_GLOBAL}, "crlBag", BSL_CID_CRLBAG},
108     {{11, "\52\206\110\206\367\15\1\14\12\1\5", BSL_OID_GLOBAL}, "secretBag", BSL_CID_SECRETBAG},
109     {{11, "\52\206\110\206\367\15\1\14\12\1\6", BSL_OID_GLOBAL}, "safeContent", BSL_CID_SAFECONTENTSBAG},
110     {{10, "\52\206\110\206\367\15\1\11\26\1", BSL_OID_GLOBAL}, "x509Certificate", BSL_CID_X509CERTIFICATE},
111     {{9, "\52\206\110\206\367\15\1\11\24", BSL_OID_GLOBAL}, "friendlyName", BSL_CID_FRIENDLYNAME},
112     {{9, "\52\206\110\206\367\15\1\11\25", BSL_OID_GLOBAL}, "localKeyId", BSL_CID_LOCALKEYID},
113     {{9, "\52\206\110\206\367\15\1\7\1", BSL_OID_GLOBAL}, "data", BSL_CID_PKCS7_SIMPLEDATA},
114     {{9, "\52\206\110\206\367\15\1\7\6", BSL_OID_GLOBAL}, "encryptedData", BSL_CID_PKCS7_ENCRYPTEDDATA},
115     {{5, "\53\201\4\0\42", BSL_OID_GLOBAL}, "SECP384R1", BSL_CID_SECP384R1},
116     {{5, "\53\201\4\0\43", BSL_OID_GLOBAL}, "SECP521R1", BSL_CID_SECP521R1},
117     {{8, "\52\201\34\317\125\1\203\21", BSL_OID_GLOBAL}, "SM3", BSL_CID_SM3},
118     {{8, "\52\201\34\317\125\1\203\165", BSL_OID_GLOBAL}, "SM2DSAWITHSM3", BSL_CID_SM2DSAWITHSM3},
119     {{8, "\52\201\34\317\125\1\203\166", BSL_OID_GLOBAL}, "SM2DSAWITHSHA1", BSL_CID_SM2DSAWITHSHA1},
120     {{8, "\52\201\34\317\125\1\203\167", BSL_OID_GLOBAL}, "SM2DSAWITHSHA256", BSL_CID_SM2DSAWITHSHA256},
121     {{8, "\52\201\34\317\125\1\202\55", BSL_OID_GLOBAL}, "SM2PRIME256", BSL_CID_SM2PRIME256},
122     {{3, "\125\4\11", BSL_OID_GLOBAL}, "STREET", BSL_CID_AT_STREETADDRESS},
123     {{5, "\53\201\4\0\41", BSL_OID_GLOBAL}, "PRIME224", BSL_CID_NIST_PRIME224},
124     {{3, "\53\145\160", BSL_OID_GLOBAL}, "ED25519", BSL_CID_ED25519},
125     {{9, "\52\206\110\206\367\15\1\1\12", BSL_OID_GLOBAL}, "RSASSAPSS", BSL_CID_RSASSAPSS},
126     {{9, "\52\206\110\206\367\15\1\1\10", BSL_OID_GLOBAL}, "MGF1", BSL_CID_MGF1},
127     {{8, "\52\201\34\317\125\1\150\2", BSL_OID_GLOBAL}, "SM4-CBC", BSL_CID_SM4_CBC},
128     {{8, "\52\201\34\317\125\1\203\170", BSL_OID_GLOBAL}, "SM3WITHRSA", BSL_CID_SM3WITHRSAENCRYPTION},
129     {{9, "\140\206\110\1\145\3\4\3\2", BSL_OID_GLOBAL}, "DSAWITHSHA256", BSL_CID_DSAWITHSHA256},
130     {{9, "\140\206\110\1\145\3\4\3\1", BSL_OID_GLOBAL}, "DSAWITHSHA224", BSL_CID_DSAWITHSHA224},
131     {{9, "\140\206\110\1\145\3\4\3\3", BSL_OID_GLOBAL}, "DSAWITHSHA384", BSL_CID_DSAWITHSHA384},
132     {{9, "\140\206\110\1\145\3\4\3\4", BSL_OID_GLOBAL}, "DSAWITHSHA512", BSL_CID_DSAWITHSHA512},
133     {{9, "\52\206\110\206\367\15\1\1\16", BSL_OID_GLOBAL}, "SHA224WITHRSA", BSL_CID_SHA224WITHRSAENCRYPTION},
134     {{9, "\140\206\110\1\145\3\4\2\7", BSL_OID_GLOBAL}, "SHA3-224", BSL_CID_SHA3_224},
135     {{9, "\140\206\110\1\145\3\4\2\10", BSL_OID_GLOBAL}, "SHA3-256", BSL_CID_SHA3_256},
136     {{9, "\140\206\110\1\145\3\4\2\11", BSL_OID_GLOBAL}, "SHA3-384", BSL_CID_SHA3_384},
137     {{9, "\140\206\110\1\145\3\4\2\12", BSL_OID_GLOBAL}, "SHA3-512", BSL_CID_SHA3_512},
138     {{9, "\140\206\110\1\145\3\4\2\13", BSL_OID_GLOBAL}, "SHAKE128", BSL_CID_SHAKE128},
139     {{9, "\140\206\110\1\145\3\4\2\14", BSL_OID_GLOBAL}, "SHAKE256", BSL_CID_SHAKE256},
140     {{9, "\53\44\3\3\2\10\1\1\7", BSL_OID_GLOBAL}, "BRAINPOOLP256R1", BSL_CID_ECC_BRAINPOOLP256R1},
141     {{9, "\53\44\3\3\2\10\1\1\13", BSL_OID_GLOBAL}, "BRAINPOOLP384R1", BSL_CID_ECC_BRAINPOOLP384R1},
142     {{9, "\53\44\3\3\2\10\1\1\15", BSL_OID_GLOBAL}, "BRAINPOOLP512R1", BSL_CID_ECC_BRAINPOOLP512R1},
143     {{7, "\52\206\110\316\75\2\1", BSL_OID_GLOBAL}, "EC-PUBLICKEY", BSL_CID_EC_PUBLICKEY}, // ecc subkey
144     {{10, "\11\222\46\211\223\362\54\144\1\1", BSL_OID_GLOBAL}, "UID", BSL_CID_AT_USERID},
145 };
146 
147 
148 /**
149  * RFC 5280: A.1. Explicitly Tagged Module, 1988 Syntax
150  * -- Upper Bounds
151 */
152 
153 static const BslAsn1DnInfo g_asn1StrTab[] = {
154     {BSL_CID_AT_COMMONNAME, 1, 64}, // ub-common-name INTEGER ::= 64
155     {BSL_CID_AT_SURNAME, 1, 40}, // ub-surname-length INTEGER ::= 40
156     {BSL_CID_AT_SERIALNUMBER, 1, 64}, // ub-serial-number INTEGER ::= 64
157     {BSL_CID_AT_COUNTRYNAME, 2, 2}, // ub-country-name-alpha-length INTEGER ::= 2
158     {BSL_CID_AT_LOCALITYNAME, 1, 128}, // ub-locality-name INTEGER ::= 128
159     {BSL_CID_AT_STATEORPROVINCENAME, 1, 128}, // ub-state-name INTEGER ::= 128
160     {BSL_CID_AT_STREETADDRESS, 1, -1}, // no limited
161     {BSL_CID_AT_ORGANIZATIONNAME, 1, 64}, // ub-organization-name INTEGER ::= 64
162     {BSL_CID_AT_ORGANIZATIONALUNITNAME, 1, 64}, // ub-organizational-unit-name INTEGER ::= 64
163     {BSL_CID_AT_TITLE, 1, 64}, // ub-title INTEGER ::= 64
164     {BSL_CID_AT_GIVENNAME, 1, 32768}, // ub-name INTEGER ::= 32768
165     {BSL_CID_AT_INITIALS, 1, 32768}, // ub-name INTEGER ::= 32768
166     {BSL_CID_AT_GENERATIONQUALIFIER, 1, 32768}, // ub-name INTEGER ::= 32768
167     {BSL_CID_AT_DNQUALIFIER, 1, -1}, // no limited
168     {BSL_CID_AT_PSEUDONYM, 1, 128}, // ub-pseudonym INTEGER ::= 128
169     {BSL_CID_DOMAINCOMPONENT, 1, -1, }, // no limited
170     {BSL_CID_AT_USERID, 1, 256}, // RFC1274
171 };
172 
173 uint32_t g_tableSize = (uint32_t)sizeof(g_oidTable)/sizeof(g_oidTable[0]);
174 
175 #ifdef HITLS_BSL_HASH
FreeBslOidInfo(void * data)176 static void FreeBslOidInfo(void *data)
177 {
178     if (data == NULL) {
179         return;
180     }
181     BslOidInfo *oidInfo = (BslOidInfo *)data;
182     BSL_SAL_Free(oidInfo->strOid.octs);
183     BSL_SAL_Free((char *)(uintptr_t)oidInfo->oidName);
184     BSL_SAL_Free(oidInfo);
185 }
186 
InitOidHashTableOnce(void)187 static void InitOidHashTableOnce(void)
188 {
189     int32_t ret = BSL_SAL_ThreadLockNew(&g_oidHashRwLock);
190     if (ret != BSL_SUCCESS) {
191         BSL_ERR_PUSH_ERROR(ret);
192         return;
193     }
194 
195     ListDupFreeFuncPair valueFunc = {NULL, FreeBslOidInfo};
196     g_oidHashTable = BSL_HASH_Create(BSL_OBJ_HASH_BKT_SIZE, NULL, NULL, NULL, &valueFunc);
197     if (g_oidHashTable == NULL) {
198         (void)BSL_SAL_ThreadLockFree(g_oidHashRwLock);
199         g_oidHashRwLock = NULL;
200         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
201     }
202 }
203 #endif // HITLS_BSL_HASH
204 
GetOidIndex(int32_t inputCid)205 static int32_t GetOidIndex(int32_t inputCid)
206 {
207     int32_t left = 0;
208     int32_t right = g_tableSize - 1;
209     while (left <= right) {
210         int32_t mid = (right - left) / 2 + left;
211         int32_t cid = g_oidTable[mid].cid;
212         if (cid == inputCid) {
213             return mid;
214         } else if (cid > inputCid) {
215             right = mid - 1;
216         } else {
217             left = mid + 1;
218         }
219     }
220     return -1;
221 }
222 
BSL_OBJ_GetCID(const BslOidString * oidstr)223 BslCid BSL_OBJ_GetCID(const BslOidString *oidstr)
224 {
225     if (oidstr == NULL || oidstr->octs == NULL) {
226         return BSL_CID_UNKNOWN;
227     }
228 
229     /* First, search in the g_oidTable */
230     for (uint32_t i = 0; i < g_tableSize; i++) {
231         if (g_oidTable[i].strOid.octetLen == oidstr->octetLen) {
232             if (memcmp(g_oidTable[i].strOid.octs, oidstr->octs, oidstr->octetLen) == 0) {
233                 return g_oidTable[i].cid;
234             }
235         }
236     }
237 #ifndef HITLS_BSL_HASH
238     return BSL_CID_UNKNOWN;
239 #else
240     if (g_oidHashTable == NULL) {
241         BSL_ERR_PUSH_ERROR(BSL_OBJ_INVALID_HASH_TABLE);
242         return BSL_CID_UNKNOWN;
243     }
244 
245     /* Second, search in the g_oidHashTable with read lock */
246     BslCid cid = BSL_CID_UNKNOWN;
247     int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
248     if (ret != BSL_SUCCESS) {
249         BSL_ERR_PUSH_ERROR(ret);
250         return BSL_CID_UNKNOWN;
251     }
252 
253     /* Since g_oidHashTable is keyed by cid, we need to iterate through all entries */
254     BSL_HASH_Iterator iter = BSL_HASH_IterBegin(g_oidHashTable);
255     BSL_HASH_Iterator end = BSL_HASH_IterEnd(g_oidHashTable);
256 
257     while (iter != end) {
258         BslOidInfo *oidInfo = (BslOidInfo *)BSL_HASH_IterValue(g_oidHashTable, iter);
259         if (oidInfo != NULL && oidInfo->strOid.octetLen == oidstr->octetLen &&
260             memcmp(oidInfo->strOid.octs, oidstr->octs, oidstr->octetLen) == 0) {
261             cid = oidInfo->cid;
262             break;
263         }
264         iter = BSL_HASH_IterNext(g_oidHashTable, iter);
265     }
266 
267     (void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
268     return cid;
269 #endif // HITLS_BSL_HASH
270 }
271 
BSL_OBJ_GetOID(BslCid ulCID)272 BslOidString *BSL_OBJ_GetOID(BslCid ulCID)
273 {
274     if (ulCID == BSL_CID_UNKNOWN) {
275         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
276         return NULL;
277     }
278 
279     /* First, search in the g_oidTable */
280     int32_t index = GetOidIndex(ulCID);
281     if (index != -1) {
282         return &g_oidTable[index].strOid;
283     }
284 #ifndef HITLS_BSL_HASH
285     return NULL;
286 #else
287 
288     /* Initialize hash table if needed */
289     if (g_oidHashTable == NULL) {
290         BSL_ERR_PUSH_ERROR(BSL_OBJ_INVALID_HASH_TABLE);
291         return NULL;
292     }
293 
294     /* Second, search in the g_oidHashTable with read lock */
295     BslOidInfo *oidInfo = NULL;
296     int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
297     if (ret != BSL_SUCCESS) {
298         BSL_ERR_PUSH_ERROR(ret);
299         return NULL;
300     }
301 
302     /* Since g_oidHashTable is keyed by cid, we can directly look up the entry */
303     ret = BSL_HASH_At(g_oidHashTable, (uintptr_t)ulCID, (uintptr_t *)&oidInfo);
304     (void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
305     BslOidString *oidString = (ret == BSL_SUCCESS && oidInfo != NULL) ? &oidInfo->strOid : NULL;
306     if (ret != BSL_SUCCESS) {
307         BSL_ERR_PUSH_ERROR(BSL_OBJ_ERR_FIND_HASH_TABLE);
308     }
309 
310     return oidString;
311 #endif // HITLS_BSL_HASH
312 }
313 
BSL_OBJ_GetOidNameFromOid(const BslOidString * oid)314 const char *BSL_OBJ_GetOidNameFromOid(const BslOidString *oid)
315 {
316     if (oid == NULL || oid->octs == NULL) {
317         return NULL;
318     }
319 
320     /* First, search in the g_oidTable */
321     for (uint32_t i = 0; i < g_tableSize; i++) {
322         if (g_oidTable[i].strOid.octetLen == oid->octetLen) {
323             if (memcmp(g_oidTable[i].strOid.octs, oid->octs, oid->octetLen) == 0) {
324                 return g_oidTable[i].oidName;
325             }
326         }
327     }
328 #ifndef HITLS_BSL_HASH
329     return NULL;
330 #else
331     if (g_oidHashTable == NULL) {
332         BSL_ERR_PUSH_ERROR(BSL_OBJ_INVALID_HASH_TABLE);
333         return NULL;
334     }
335 
336     /* Second, search in the g_oidHashTable with read lock */
337     const char *oidName = NULL;
338     int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
339     if (ret != BSL_SUCCESS) {
340         BSL_ERR_PUSH_ERROR(ret);
341         return NULL;
342     }
343 
344     /* Since g_oidHashTable is keyed by cid, we need to iterate through all entries */
345     BSL_HASH_Iterator iter = BSL_HASH_IterBegin(g_oidHashTable);
346     BSL_HASH_Iterator end = BSL_HASH_IterEnd(g_oidHashTable);
347 
348     while (iter != end) {
349         BslOidInfo *oidInfo = (BslOidInfo *)BSL_HASH_IterValue(g_oidHashTable, iter);
350         if (oidInfo != NULL && oidInfo->strOid.octetLen == oid->octetLen &&
351             memcmp(oidInfo->strOid.octs, oid->octs, oid->octetLen) == 0) {
352             oidName = oidInfo->oidName;
353             break;
354         }
355         iter = BSL_HASH_IterNext(g_oidHashTable, iter);
356     }
357 
358     (void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
359     return oidName;
360 #endif // HITLS_BSL_HASH
361 }
362 
BSL_OBJ_GetDnInfoFromCid(BslCid cid)363 const BslAsn1DnInfo *BSL_OBJ_GetDnInfoFromCid(BslCid cid)
364 {
365     for (size_t i = 0; i < sizeof(g_asn1StrTab) / sizeof(g_asn1StrTab[0]); i++) {
366         if (cid == g_asn1StrTab[i].cid) {
367             return &g_asn1StrTab[i];
368         }
369     }
370 
371     return NULL;
372 }
373 
374 #ifdef HITLS_BSL_HASH
BslOidStringCopy(const BslOidString * srcOidStr,BslOidString * oidString)375 static int32_t BslOidStringCopy(const BslOidString *srcOidStr, BslOidString *oidString)
376 {
377     oidString->octs = BSL_SAL_Dump(srcOidStr->octs, srcOidStr->octetLen);
378     if (oidString->octs == NULL) {
379         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
380         return BSL_MALLOC_FAIL;
381     }
382     oidString->octetLen = srcOidStr->octetLen;
383     oidString->flags = srcOidStr->flags;
384     return BSL_SUCCESS;
385 }
386 
IsOidCidInStaticTable(int32_t cid)387 static bool IsOidCidInStaticTable(int32_t cid)
388 {
389     for (uint32_t i = 0; i < g_tableSize; i++) {
390         if ((int32_t)g_oidTable[i].cid == cid) {
391             return true;
392         }
393     }
394     return false;
395 }
396 
IsOidCidInHashTable(int32_t cid)397 static int32_t IsOidCidInHashTable(int32_t cid)
398 {
399     BslOidInfo *oidInfo = NULL;
400     int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
401     if (ret != BSL_SUCCESS) {
402         BSL_ERR_PUSH_ERROR(ret);
403         return ret;
404     }
405 
406     ret = BSL_HASH_At(g_oidHashTable, (uintptr_t)cid, (uintptr_t *)&oidInfo);
407     (void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
408     return ret;
409 }
410 
CreateOidInfo(const BslOidString * oid,const char * oidName,int32_t cid,BslOidInfo ** newOidInfo)411 static int32_t CreateOidInfo(const BslOidString *oid, const char *oidName, int32_t cid, BslOidInfo **newOidInfo)
412 {
413     BslOidInfo *oidInfo = (BslOidInfo *)BSL_SAL_Calloc(1, sizeof(BslOidInfo));
414     if (oidInfo == NULL) {
415         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
416         return BSL_MALLOC_FAIL;
417     }
418 
419     int32_t ret = BslOidStringCopy(oid, &oidInfo->strOid);
420     if (ret != BSL_SUCCESS) {
421         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
422         BSL_SAL_Free(oidInfo);
423         return ret;
424     }
425 
426     oidInfo->oidName = BSL_SAL_Dump(oidName, (uint32_t)strlen(oidName) + 1);
427     if (oidInfo->oidName == NULL) {
428         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
429         BSL_SAL_Free(oidInfo->strOid.octs);
430         BSL_SAL_Free(oidInfo);
431         return BSL_MALLOC_FAIL;
432     }
433 
434     oidInfo->cid = cid;
435     *newOidInfo = oidInfo;
436     return BSL_SUCCESS;
437 }
438 
439 // Insert OID info into hash table with write lock
InsertOidInfoToHashTable(int32_t cid,BslOidInfo * oidInfo)440 static int32_t InsertOidInfoToHashTable(int32_t cid, BslOidInfo *oidInfo)
441 {
442     int32_t ret = BSL_SAL_ThreadWriteLock(g_oidHashRwLock);
443     if (ret != BSL_SUCCESS) {
444         BSL_ERR_PUSH_ERROR(ret);
445         return ret;
446     }
447 
448     BslOidInfo *checkInfo = NULL;
449     ret = BSL_HASH_At(g_oidHashTable, (uintptr_t)cid, (uintptr_t *)&checkInfo);
450     if (ret == BSL_SUCCESS) {
451         (void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
452         return BSL_SUCCESS;
453     }
454 
455     ret = BSL_HASH_Insert(g_oidHashTable, (uintptr_t)cid, sizeof(int32_t), (uintptr_t)oidInfo, sizeof(BslOidInfo));
456     (void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
457     return ret;
458 }
459 
460 // Main function for creating and registering OIDs
BSL_OBJ_Create(char * octs,uint32_t octetLen,const char * oidName,int32_t cid)461 int32_t BSL_OBJ_Create(char *octs, uint32_t octetLen, const char *oidName, int32_t cid)
462 {
463     if (octs == NULL || octetLen == 0 || oidName == NULL || cid == BSL_CID_UNKNOWN) {
464         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
465         return BSL_INVALID_ARG;
466     }
467 
468     if (IsOidCidInStaticTable(cid)) {
469         return BSL_SUCCESS;
470     }
471     const BslOidString oid = {
472         .octs = octs,
473         .octetLen = octetLen,
474         .flags = 6
475     };
476 
477     int32_t ret = BSL_SAL_ThreadRunOnce(&g_oidHashInitOnce, InitOidHashTableOnce);
478     if (ret != BSL_SUCCESS) {
479         BSL_ERR_PUSH_ERROR(ret);
480         return ret;
481     }
482     if (g_oidHashTable == NULL) {
483         BSL_ERR_PUSH_ERROR(BSL_OBJ_INVALID_HASH_TABLE);
484         return BSL_OBJ_INVALID_HASH_TABLE;
485     }
486     ret = IsOidCidInHashTable(cid);
487     if (ret == BSL_SUCCESS) {
488         return BSL_SUCCESS;
489     }
490 
491     BslOidInfo *oidInfo = NULL;
492     ret = CreateOidInfo(&oid, oidName, cid, &oidInfo);
493     if (ret != BSL_SUCCESS) {
494         return ret;
495     }
496 
497     ret = InsertOidInfoToHashTable(cid, oidInfo);
498     if (ret != BSL_SUCCESS) {
499         FreeBslOidInfo(oidInfo);
500         return ret;
501     }
502 
503     return BSL_SUCCESS;
504 }
505 
BSL_OBJ_FreeHashTable(void)506 void BSL_OBJ_FreeHashTable(void)
507 {
508     if (g_oidHashTable != NULL) {
509         int32_t ret = BSL_SAL_ThreadWriteLock(g_oidHashRwLock);
510         if (ret != BSL_SUCCESS) {
511             BSL_ERR_PUSH_ERROR(ret);
512             return;
513         }
514         BSL_HASH_Destory(g_oidHashTable);
515         g_oidHashTable = NULL;
516         (void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
517         if (g_oidHashRwLock != NULL) {
518             (void)BSL_SAL_ThreadLockFree(g_oidHashRwLock);
519             g_oidHashRwLock = NULL;
520         }
521         g_oidHashInitOnce = BSL_SAL_ONCE_INIT;
522     }
523 }
524 #endif // HITLS_BSL_HASH
525 
526 #endif
527