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