* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "hitls_build.h"
#ifdef HITLS_BSL_OBJ
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "bsl_sal.h"
#include "bsl_obj.h"
#include "bsl_obj_internal.h"
#include "bsl_err_internal.h"
#ifdef HITLS_BSL_OBJ_CUSTOM
#include "bsl_hash.h"
#define BSL_OBJ_HASH_BKT_SIZE 256u
BSL_HASH_Hash *g_oidHashTable = NULL;
static BSL_SAL_ThreadLockHandle g_oidHashRwLock = NULL;
BSL_SAL_DECLARE_THREAD_ONCE(g_oidHashInitOnce);
#endif
#define BSL_OBJ_ARCS_X_MAX 2
#define BSL_OBJ_ARCS_Y_MAX 40
#define BSL_OBJ_ARCS_MAX (BSL_OBJ_ARCS_X_MAX * BSL_OBJ_ARCS_Y_MAX + BSL_OBJ_ARCS_Y_MAX - 1)
BslOidInfo g_oidTable[] = {
{{9, "\140\206\110\1\145\3\4\1\1", BSL_OID_GLOBAL}, "aes-128-ecb", BSL_CID_AES128_ECB},
{{9, "\140\206\110\1\145\3\4\1\2", BSL_OID_GLOBAL}, "aes-128-cbc", BSL_CID_AES128_CBC},
{{9, "\140\206\110\1\145\3\4\1\3", BSL_OID_GLOBAL}, "aes-128-ofb", BSL_CID_AES128_OFB},
{{9, "\140\206\110\1\145\3\4\1\4", BSL_OID_GLOBAL}, "aes-128-cfb", BSL_CID_AES128_CFB},
{{9, "\140\206\110\1\145\3\4\1\25", BSL_OID_GLOBAL}, "aes-192-ecb", BSL_CID_AES192_ECB},
{{9, "\140\206\110\1\145\3\4\1\26", BSL_OID_GLOBAL}, "aes-192-cbc", BSL_CID_AES192_CBC},
{{9, "\140\206\110\1\145\3\4\1\27", BSL_OID_GLOBAL}, "aes-192-ofb", BSL_CID_AES192_OFB},
{{9, "\140\206\110\1\145\3\4\1\30", BSL_OID_GLOBAL}, "aes-192-cfb", BSL_CID_AES192_CFB},
{{9, "\140\206\110\1\145\3\4\1\51", BSL_OID_GLOBAL}, "aes-256-ecb", BSL_CID_AES256_ECB},
{{9, "\140\206\110\1\145\3\4\1\52", BSL_OID_GLOBAL}, "aes-256-cbc", BSL_CID_AES256_CBC},
{{9, "\140\206\110\1\145\3\4\1\53", BSL_OID_GLOBAL}, "aes-256-ofb", BSL_CID_AES256_OFB},
{{9, "\140\206\110\1\145\3\4\1\54", BSL_OID_GLOBAL}, "aes-256-cfb", BSL_CID_AES256_CFB},
{{9, "\52\206\110\206\367\15\1\1\1", BSL_OID_GLOBAL}, "rsaEncryption", BSL_CID_RSA},
{{7, "\52\206\110\316\70\4\1", BSL_OID_GLOBAL}, "dsaEncryption", BSL_CID_DSA},
{{7, "\52\206\110\316\76\2\1", BSL_OID_GLOBAL}, "dhPublicNumber", BSL_CID_DH},
{{8, "\52\206\110\206\367\15\2\5", BSL_OID_GLOBAL}, "MD5", BSL_CID_MD5},
{{5, "\53\16\3\2\32", BSL_OID_GLOBAL}, "SHA1", BSL_CID_SHA1},
{{9, "\140\206\110\1\145\3\4\2\4", BSL_OID_GLOBAL}, "SHA224", BSL_CID_SHA224},
{{9, "\140\206\110\1\145\3\4\2\1", BSL_OID_GLOBAL}, "SHA256", BSL_CID_SHA256},
{{9, "\140\206\110\1\145\3\4\2\2", BSL_OID_GLOBAL}, "SHA384", BSL_CID_SHA384},
{{9, "\140\206\110\1\145\3\4\2\3", BSL_OID_GLOBAL}, "SHA512", BSL_CID_SHA512},
{{8, "\53\6\1\5\5\10\1\1", BSL_OID_GLOBAL}, "HMAC-MD5", BSL_CID_HMAC_MD5},
{{8, "\52\206\110\206\367\15\2\7", BSL_OID_GLOBAL}, "HMAC-SHA1", BSL_CID_HMAC_SHA1},
{{8, "\52\206\110\206\367\15\2\10", BSL_OID_GLOBAL}, "HMAC-SHA224", BSL_CID_HMAC_SHA224},
{{8, "\52\206\110\206\367\15\2\11", BSL_OID_GLOBAL}, "HMAC-SHA256", BSL_CID_HMAC_SHA256},
{{8, "\52\206\110\206\367\15\2\12", BSL_OID_GLOBAL}, "HMAC-SHA384", BSL_CID_HMAC_SHA384},
{{8, "\52\206\110\206\367\15\2\13", BSL_OID_GLOBAL}, "HMAC-SHA512", BSL_CID_HMAC_SHA512},
{{9, "\52\206\110\206\367\15\1\1\4", BSL_OID_GLOBAL}, "md5WithRSAEncryption", BSL_CID_MD5WITHRSA},
{{9, "\52\206\110\206\367\15\1\1\5", BSL_OID_GLOBAL}, "sha1WithRSAEncryption", BSL_CID_SHA1WITHRSA},
{{7, "\52\206\110\316\70\4\3", BSL_OID_GLOBAL}, "dsaWithSHA1", BSL_CID_DSAWITHSHA1},
{{7, "\52\206\110\316\75\4\1", BSL_OID_GLOBAL}, "ecdsa-with-SHA1", BSL_CID_ECDSAWITHSHA1},
{{8, "\52\206\110\316\75\4\3\1", BSL_OID_GLOBAL}, "ecdsa-with-SHA224", BSL_CID_ECDSAWITHSHA224},
{{8, "\52\206\110\316\75\4\3\2", BSL_OID_GLOBAL}, "ecdsa-with-SHA256", BSL_CID_ECDSAWITHSHA256},
{{8, "\52\206\110\316\75\4\3\3", BSL_OID_GLOBAL}, "ecdsa-with-SHA384", BSL_CID_ECDSAWITHSHA384},
{{8, "\52\206\110\316\75\4\3\4", BSL_OID_GLOBAL}, "ecdsa-with-SHA512", BSL_CID_ECDSAWITHSHA512},
{{9, "\52\206\110\206\367\15\1\1\13", BSL_OID_GLOBAL}, "sha256WithRSAEncryption", BSL_CID_SHA256WITHRSAENCRYPTION},
{{9, "\52\206\110\206\367\15\1\1\14", BSL_OID_GLOBAL}, "sha384WithRSAEncryption", BSL_CID_SHA384WITHRSAENCRYPTION},
{{9, "\52\206\110\206\367\15\1\1\15", BSL_OID_GLOBAL}, "sha512WithRSAEncryption", BSL_CID_SHA512WITHRSAENCRYPTION},
{{8, "\52\206\110\316\75\3\1\1", BSL_OID_GLOBAL}, "prime192v1", BSL_CID_PRIME192V1},
{{8, "\52\206\110\316\75\3\1\7", BSL_OID_GLOBAL}, "prime256v1", BSL_CID_PRIME256V1},
{{9, "\52\206\110\206\367\15\1\5\14", BSL_OID_GLOBAL}, "PBKDF2", BSL_CID_PBKDF2},
{{9, "\52\206\110\206\367\15\1\5\15", BSL_OID_GLOBAL}, "PBES2", BSL_CID_PBES2},
{{9, "\52\206\110\206\367\15\1\11\16", BSL_OID_GLOBAL}, "Extension Request", BSL_CID_EXTENSIONREQUEST},
{{3, "\125\4\4", BSL_OID_GLOBAL}, "SN", BSL_CID_AT_SURNAME},
{{3, "\125\4\52", BSL_OID_GLOBAL}, "GN", BSL_CID_AT_GIVENNAME},
{{3, "\125\4\53", BSL_OID_GLOBAL}, "initials", BSL_CID_AT_INITIALS},
{{3, "\125\4\54", BSL_OID_GLOBAL}, "generationQualifier", BSL_CID_AT_GENERATIONQUALIFIER},
{{3, "\125\4\3", BSL_OID_GLOBAL}, "CN", BSL_CID_AT_COMMONNAME},
{{3, "\125\4\7", BSL_OID_GLOBAL}, "L", BSL_CID_AT_LOCALITYNAME},
{{3, "\125\4\10", BSL_OID_GLOBAL}, "ST", BSL_CID_AT_STATEORPROVINCENAME},
{{3, "\125\4\12", BSL_OID_GLOBAL}, "O", BSL_CID_AT_ORGANIZATIONNAME},
{{3, "\125\4\13", BSL_OID_GLOBAL}, "OU", BSL_CID_AT_ORGANIZATIONALUNITNAME},
{{3, "\125\4\14", BSL_OID_GLOBAL}, "title", BSL_CID_AT_TITLE},
{{3, "\125\4\56", BSL_OID_GLOBAL}, "dnQualifier", BSL_CID_AT_DNQUALIFIER},
{{3, "\125\4\6", BSL_OID_GLOBAL}, "C", BSL_CID_AT_COUNTRYNAME},
{{3, "\125\4\5", BSL_OID_GLOBAL}, "serialNumber", BSL_CID_AT_SERIALNUMBER},
{{3, "\125\4\101", BSL_OID_GLOBAL}, "pseudonym", BSL_CID_AT_PSEUDONYM},
{{10, "\11\222\46\211\223\362\54\144\1\31", BSL_OID_GLOBAL}, "DC", BSL_CID_DOMAINCOMPONENT},
{{9, "\52\206\110\206\367\15\1\11\1", BSL_OID_GLOBAL}, "emailAddress", BSL_CID_EMAILADDRESS},
{{3, "\125\35\43", BSL_OID_GLOBAL}, "AuthorityKeyIdentifier", BSL_CID_CE_AUTHORITYKEYIDENTIFIER},
{{3, "\125\35\16", BSL_OID_GLOBAL}, "SubjectKeyIdentifier", BSL_CID_CE_SUBJECTKEYIDENTIFIER},
{{3, "\125\35\17", BSL_OID_GLOBAL}, "KeyUsage", BSL_CID_CE_KEYUSAGE},
{{3, "\125\35\21", BSL_OID_GLOBAL}, "SubjectAltName", BSL_CID_CE_SUBJECTALTNAME},
{{3, "\125\35\22", BSL_OID_GLOBAL}, "IssuerAlternativeName", BSL_CID_CE_ISSUERALTNAME},
{{3, "\125\35\23", BSL_OID_GLOBAL}, "BasicConstraints", BSL_CID_CE_BASICCONSTRAINTS},
{{3, "\125\35\37", BSL_OID_GLOBAL}, "CRLDistributionPoints", BSL_CID_CE_CRLDISTRIBUTIONPOINTS},
{{3, "\125\35\45", BSL_OID_GLOBAL}, "ExtendedKeyUsage", BSL_CID_CE_EXTKEYUSAGE},
{{4, "\125\35\45\0", BSL_OID_GLOBAL}, "AnyExtendedKeyUsage", BSL_CID_ANYEXTENDEDKEYUSAGE},
{{8, "\53\6\1\5\5\7\3\1", BSL_OID_GLOBAL}, "ServerAuth", BSL_CID_KP_SERVERAUTH},
{{8, "\53\6\1\5\5\7\3\2", BSL_OID_GLOBAL}, "ClientAuth", BSL_CID_KP_CLIENTAUTH},
{{8, "\53\6\1\5\5\7\3\3", BSL_OID_GLOBAL}, "CodeSigning", BSL_CID_KP_CODESIGNING},
{{8, "\53\6\1\5\5\7\3\4", BSL_OID_GLOBAL}, "EmailProtection", BSL_CID_KP_EMAILPROTECTION},
{{8, "\53\6\1\5\5\7\3\10", BSL_OID_GLOBAL}, "TimeStamping", BSL_CID_KP_TIMESTAMPING},
{{8, "\53\6\1\5\5\7\3\11", BSL_OID_GLOBAL}, "OSCPSigning", BSL_CID_KP_OCSPSIGNING},
{{3, "\125\35\56", BSL_OID_GLOBAL}, "FreshestCRL", BSL_CID_CE_FRESHESTCRL},
{{8, "\53\6\1\5\5\7\1\1", BSL_OID_GLOBAL}, "AuthorityInformationAccess", BSL_CID_PE_AUTHORITYINFOACCESS},
{{3, "\125\35\24", BSL_OID_GLOBAL}, "CrlNumber", BSL_CID_CE_CRLNUMBER},
{{3, "\125\35\34", BSL_OID_GLOBAL}, "IssuingDistributionPoint", BSL_CID_CE_ISSUINGDISTRIBUTIONPOINT},
{{3, "\125\35\33", BSL_OID_GLOBAL}, "DeltaCrlIndicator", BSL_CID_CE_DELTACRLINDICATOR},
{{3, "\125\35\25", BSL_OID_GLOBAL}, "CrlReason", BSL_CID_CE_CRLREASONS},
{{3, "\125\35\35", BSL_OID_GLOBAL}, "CertificateIssuer", BSL_CID_CE_CERTIFICATEISSUER},
{{3, "\125\35\30", BSL_OID_GLOBAL}, "InvalidityDate", BSL_CID_CE_INVALIDITYDATE},
{{11, "\52\206\110\206\367\15\1\14\12\1\1", BSL_OID_GLOBAL}, "keyBag", BSL_CID_KEYBAG},
{{11, "\52\206\110\206\367\15\1\14\12\1\2", BSL_OID_GLOBAL}, "pkcs8shroudedkeyBag", BSL_CID_PKCS8SHROUDEDKEYBAG},
{{11, "\52\206\110\206\367\15\1\14\12\1\3", BSL_OID_GLOBAL}, "certBag", BSL_CID_CERTBAG},
{{11, "\52\206\110\206\367\15\1\14\12\1\4", BSL_OID_GLOBAL}, "crlBag", BSL_CID_CRLBAG},
{{11, "\52\206\110\206\367\15\1\14\12\1\5", BSL_OID_GLOBAL}, "secretBag", BSL_CID_SECRETBAG},
{{11, "\52\206\110\206\367\15\1\14\12\1\6", BSL_OID_GLOBAL}, "safeContent", BSL_CID_SAFECONTENTSBAG},
{{10, "\52\206\110\206\367\15\1\11\26\1", BSL_OID_GLOBAL}, "x509Certificate", BSL_CID_X509CERTIFICATE},
{{9, "\52\206\110\206\367\15\1\11\24", BSL_OID_GLOBAL}, "friendlyName", BSL_CID_FRIENDLYNAME},
{{9, "\52\206\110\206\367\15\1\11\25", BSL_OID_GLOBAL}, "localKeyId", BSL_CID_LOCALKEYID},
{{9, "\52\206\110\206\367\15\1\7\1", BSL_OID_GLOBAL}, "data", BSL_CID_PKCS7_SIMPLEDATA},
{{9, "\52\206\110\206\367\15\1\7\2", BSL_OID_GLOBAL}, "signedData", BSL_CID_PKCS7_SIGNEDDATA},
{{9, "\52\206\110\206\367\15\1\7\6", BSL_OID_GLOBAL}, "encryptedData", BSL_CID_PKCS7_ENCRYPTEDDATA},
{{9, "\52\206\110\206\367\15\1\11\3", BSL_OID_GLOBAL}, "contentType", BSL_CID_PKCS9_AT_CONTENTTYPE},
{{9, "\52\206\110\206\367\15\1\11\4", BSL_OID_GLOBAL}, "messageDigest", BSL_CID_PKCS9_AT_MESSAGEDIGEST},
{{9, "\52\206\110\206\367\15\1\11\5", BSL_OID_GLOBAL}, "signingTime", BSL_CID_PKCS9_AT_SIGNINGTIME},
{{5, "\53\201\4\0\42", BSL_OID_GLOBAL}, "secp384r1", BSL_CID_SECP384R1},
{{5, "\53\201\4\0\43", BSL_OID_GLOBAL}, "secp521r1", BSL_CID_SECP521R1},
{{8, "\52\201\34\317\125\1\203\21", BSL_OID_GLOBAL}, "SM3", BSL_CID_SM3},
{{10, "\52\201\34\317\125\1\203\21\3\1", BSL_OID_GLOBAL}, "HMAC-SM3", BSL_CID_HMAC_SM3},
{{8, "\52\201\34\317\125\1\203\165", BSL_OID_GLOBAL}, "SM2DSAWITHSM3", BSL_CID_SM2DSAWITHSM3},
{{8, "\52\201\34\317\125\1\203\166", BSL_OID_GLOBAL}, "SM2DSAWITHSHA1", BSL_CID_SM2DSAWITHSHA1},
{{8, "\52\201\34\317\125\1\203\167", BSL_OID_GLOBAL}, "SM2DSAWITHSHA256", BSL_CID_SM2DSAWITHSHA256},
{{8, "\52\201\34\317\125\1\202\55", BSL_OID_GLOBAL}, "SM2PRIME256", BSL_CID_SM2PRIME256},
{{3, "\125\4\11", BSL_OID_GLOBAL}, "STREET", BSL_CID_AT_STREETADDRESS},
{{5, "\53\201\4\0\41", BSL_OID_GLOBAL}, "secp224r1", BSL_CID_NIST_PRIME224},
{{3, "\53\145\160", BSL_OID_GLOBAL}, "ED25519", BSL_CID_ED25519},
{{3, "\53\145\156", BSL_OID_GLOBAL}, "X25519", BSL_CID_X25519},
{{9, "\52\206\110\206\367\15\1\1\12", BSL_OID_GLOBAL}, "RSASSA-PSS", BSL_CID_RSASSAPSS},
{{9, "\52\206\110\206\367\15\1\1\10", BSL_OID_GLOBAL}, "MGF1", BSL_CID_MGF1},
{{8, "\52\201\34\317\125\1\150\2", BSL_OID_GLOBAL}, "sm4-cbc", BSL_CID_SM4_CBC},
{{8, "\52\201\34\317\125\1\203\170", BSL_OID_GLOBAL}, "sm3WithRSAEncryption", BSL_CID_SM3WITHRSAENCRYPTION},
{{9, "\140\206\110\1\145\3\4\3\2", BSL_OID_GLOBAL}, "dsa-with-SHA256", BSL_CID_DSAWITHSHA256},
{{9, "\140\206\110\1\145\3\4\3\1", BSL_OID_GLOBAL}, "dsa-with-SHA224", BSL_CID_DSAWITHSHA224},
{{9, "\140\206\110\1\145\3\4\3\3", BSL_OID_GLOBAL}, "dsa-with-SHA384", BSL_CID_DSAWITHSHA384},
{{9, "\140\206\110\1\145\3\4\3\4", BSL_OID_GLOBAL}, "dsa-with-SHA512", BSL_CID_DSAWITHSHA512},
{{9, "\52\206\110\206\367\15\1\1\16", BSL_OID_GLOBAL}, "sha224WithRSAEncryption", BSL_CID_SHA224WITHRSAENCRYPTION},
{{9, "\140\206\110\1\145\3\4\2\7", BSL_OID_GLOBAL}, "SHA3-224", BSL_CID_SHA3_224},
{{9, "\140\206\110\1\145\3\4\2\10", BSL_OID_GLOBAL}, "SHA3-256", BSL_CID_SHA3_256},
{{9, "\140\206\110\1\145\3\4\2\11", BSL_OID_GLOBAL}, "SHA3-384", BSL_CID_SHA3_384},
{{9, "\140\206\110\1\145\3\4\2\12", BSL_OID_GLOBAL}, "SHA3-512", BSL_CID_SHA3_512},
{{9, "\140\206\110\1\145\3\4\2\13", BSL_OID_GLOBAL}, "SHAKE128", BSL_CID_SHAKE128},
{{9, "\140\206\110\1\145\3\4\2\14", BSL_OID_GLOBAL}, "SHAKE256", BSL_CID_SHAKE256},
{{8, "\53\157\2\214\123\0\1\1", BSL_OID_GLOBAL}, "aes-128-xts", BSL_CID_AES128_XTS},
{{8, "\53\157\2\214\123\0\1\2", BSL_OID_GLOBAL}, "aes-256-xts", BSL_CID_AES256_XTS},
{{9, "\140\206\110\1\145\3\4\1\5", BSL_OID_GLOBAL}, "aes-128-wrap-nopad", BSL_CID_AES128_WRAP_NOPAD},
{{9, "\140\206\110\1\145\3\4\1\31", BSL_OID_GLOBAL}, "aes-192-wrap-nopad", BSL_CID_AES192_WRAP_NOPAD},
{{9, "\140\206\110\1\145\3\4\1\55", BSL_OID_GLOBAL}, "aes-256-wrap-nopad", BSL_CID_AES256_WRAP_NOPAD},
{{9, "\140\206\110\1\145\3\4\1\10", BSL_OID_GLOBAL}, "aes-128-wrap-pad", BSL_CID_AES128_WRAP_PAD},
{{9, "\140\206\110\1\145\3\4\1\34", BSL_OID_GLOBAL}, "aes-192-wrap-pad", BSL_CID_AES192_WRAP_PAD},
{{9, "\140\206\110\1\145\3\4\1\60", BSL_OID_GLOBAL}, "aes-256-wrap-pad", BSL_CID_AES256_WRAP_PAD},
{{8, "\52\201\34\317\125\1\150\12", BSL_OID_GLOBAL}, "sm4-xts", BSL_CID_SM4_XTS},
{{8, "\52\201\34\317\125\1\150\7", BSL_OID_GLOBAL}, "sm4-ctr", BSL_CID_SM4_CTR},
{{8, "\52\201\34\317\125\1\150\10", BSL_OID_GLOBAL}, "sm4-gcm", BSL_CID_SM4_GCM},
{{8, "\52\201\34\317\125\1\150\4", BSL_OID_GLOBAL}, "sm4-cfb", BSL_CID_SM4_CFB},
{{8, "\52\201\34\317\125\1\150\3", BSL_OID_GLOBAL}, "sm4-ofb", BSL_CID_SM4_OFB},
{{9, "\53\44\3\3\2\10\1\1\7", BSL_OID_GLOBAL}, "brainpoolP256r1", BSL_CID_ECC_BRAINPOOLP256R1},
{{9, "\53\44\3\3\2\10\1\1\13", BSL_OID_GLOBAL}, "brainpoolP384r1", BSL_CID_ECC_BRAINPOOLP384R1},
{{9, "\53\44\3\3\2\10\1\1\15", BSL_OID_GLOBAL}, "brainpoolP512r1", BSL_CID_ECC_BRAINPOOLP512R1},
{{7, "\52\206\110\316\75\2\1", BSL_OID_GLOBAL}, "id-ecPublicKey", BSL_CID_EC_PUBLICKEY},
{{10, "\11\222\46\211\223\362\54\144\1\1", BSL_OID_GLOBAL}, "UID", BSL_CID_AT_USERID},
{{9, "\140\206\110\1\145\3\4\3\21", BSL_OID_GLOBAL}, "ML-DSA-44", BSL_CID_ML_DSA_44},
{{9, "\140\206\110\1\145\3\4\3\22", BSL_OID_GLOBAL}, "ML-DSA-65", BSL_CID_ML_DSA_65},
{{9, "\140\206\110\1\145\3\4\3\23", BSL_OID_GLOBAL}, "ML-DSA-87", BSL_CID_ML_DSA_87},
{{9, "\140\206\110\1\145\3\4\4\1", BSL_OID_GLOBAL}, "ML-KEM-512", BSL_CID_ML_KEM_512},
{{9, "\140\206\110\1\145\3\4\4\2", BSL_OID_GLOBAL}, "ML-KEM-768", BSL_CID_ML_KEM_768},
{{9, "\140\206\110\1\145\3\4\4\3", BSL_OID_GLOBAL}, "ML-KEM-1024", BSL_CID_ML_KEM_1024},
{{9, "\140\206\110\1\145\3\4\3\24", BSL_OID_GLOBAL}, "SLH-DSA-SHA2-128S", BSL_CID_SLH_DSA_SHA2_128S},
{{9, "\140\206\110\1\145\3\4\3\32", BSL_OID_GLOBAL}, "SLH-DSA-SHAKE-128S", BSL_CID_SLH_DSA_SHAKE_128S},
{{9, "\140\206\110\1\145\3\4\3\25", BSL_OID_GLOBAL}, "SLH-DSA-SHA2-128F", BSL_CID_SLH_DSA_SHA2_128F},
{{9, "\140\206\110\1\145\3\4\3\33", BSL_OID_GLOBAL}, "SLH-DSA-SHAKE-128F", BSL_CID_SLH_DSA_SHAKE_128F},
{{9, "\140\206\110\1\145\3\4\3\26", BSL_OID_GLOBAL}, "SLH-DSA-SHA2-192S", BSL_CID_SLH_DSA_SHA2_192S},
{{9, "\140\206\110\1\145\3\4\3\34", BSL_OID_GLOBAL}, "SLH-DSA-SHAKE-192S", BSL_CID_SLH_DSA_SHAKE_192S},
{{9, "\140\206\110\1\145\3\4\3\27", BSL_OID_GLOBAL}, "SLH-DSA-SHA2-192F", BSL_CID_SLH_DSA_SHA2_192F},
{{9, "\140\206\110\1\145\3\4\3\35", BSL_OID_GLOBAL}, "SLH-DSA-SHAKE-192F", BSL_CID_SLH_DSA_SHAKE_192F},
{{9, "\140\206\110\1\145\3\4\3\30", BSL_OID_GLOBAL}, "SLH-DSA-SHA2-256S", BSL_CID_SLH_DSA_SHA2_256S},
{{9, "\140\206\110\1\145\3\4\3\36", BSL_OID_GLOBAL}, "SLH-DSA-SHAKE-256S", BSL_CID_SLH_DSA_SHAKE_256S},
{{9, "\140\206\110\1\145\3\4\3\31", BSL_OID_GLOBAL}, "SLH-DSA-SHA2-256F", BSL_CID_SLH_DSA_SHA2_256F},
{{9, "\140\206\110\1\145\3\4\3\37", BSL_OID_GLOBAL}, "SLH-DSA-SHAKE-256F", BSL_CID_SLH_DSA_SHAKE_256F},
{{8, "\53\6\1\5\5\7\6\42", BSL_OID_GLOBAL}, "XMSS", BSL_CID_XMSS},
{{8, "\53\6\1\5\5\7\6\45", BSL_OID_GLOBAL}, "MLDSA44-RSA2048-PSS-SHA256", BSL_CID_MLDSA44_RSA2048_PSS_SHA256},
{{8, "\53\6\1\5\5\7\6\46", BSL_OID_GLOBAL}, "MLDSA44-RSA2048-PKCS15-SHA256", BSL_CID_MLDSA44_RSA2048_PKCS15_SHA256},
{{8, "\53\6\1\5\5\7\6\47", BSL_OID_GLOBAL}, "MLDSA44-Ed25519-SHA512", BSL_CID_MLDSA44_ED25519_SHA512},
{{8, "\53\6\1\5\5\7\6\50", BSL_OID_GLOBAL}, "MLDSA44-ECDSA-P256-SHA256", BSL_CID_MLDSA44_ECDSA_P256_SHA256},
{{8, "\53\6\1\5\5\7\6\51", BSL_OID_GLOBAL}, "MLDSA65-RSA3072-PSS-SHA512", BSL_CID_MLDSA65_RSA3072_PSS_SHA512},
{{8, "\53\6\1\5\5\7\6\52", BSL_OID_GLOBAL}, "MLDSA65-RSA3072-PKCS15-SHA512", BSL_CID_MLDSA65_RSA3072_PKCS15_SHA512},
{{8, "\53\6\1\5\5\7\6\53", BSL_OID_GLOBAL}, "MLDSA65-RSA4096-PSS-SHA512", BSL_CID_MLDSA65_RSA4096_PSS_SHA512},
{{8, "\53\6\1\5\5\7\6\54", BSL_OID_GLOBAL}, "MLDSA65-RSA4096-PKCS15-SHA512", BSL_CID_MLDSA65_RSA4096_PKCS15_SHA512},
{{8, "\53\6\1\5\5\7\6\55", BSL_OID_GLOBAL}, "MLDSA65-ECDSA-P256-SHA512", BSL_CID_MLDSA65_ECDSA_P256_SHA512},
{{8, "\53\6\1\5\5\7\6\56", BSL_OID_GLOBAL}, "MLDSA65-ECDSA-P384-SHA512", BSL_CID_MLDSA65_ECDSA_P384_SHA512},
{{8, "\53\6\1\5\5\7\6\57", BSL_OID_GLOBAL},"MLDSA65-ECDSA-brainpoolP256r1-SHA512",BSL_CID_MLDSA65_ECDSA_BRAINPOOLP256R1_SHA512},
{{8, "\53\6\1\5\5\7\6\60", BSL_OID_GLOBAL}, "MLDSA65-Ed25519-SHA512", BSL_CID_MLDSA65_ED25519_SHA512},
{{8, "\53\6\1\5\5\7\6\61", BSL_OID_GLOBAL}, "MLDSA87-ECDSA-P384-SHA512", BSL_CID_MLDSA87_ECDSA_P384_SHA512},
{{8, "\53\6\1\5\5\7\6\62", BSL_OID_GLOBAL},"MLDSA87-ECDSA-brainpoolP384r1-SHA512",BSL_CID_MLDSA87_ECDSA_BRAINPOOLP384R1_SHA512},
{{8, "\53\6\1\5\5\7\6\63", BSL_OID_GLOBAL}, "MLDSA87-Ed448-SHAKE256", BSL_CID_MLDSA87_ED448_SHAKE256},
{{8, "\53\6\1\5\5\7\6\64", BSL_OID_GLOBAL}, "MLDSA87-RSA3072-PSS-SHA512", BSL_CID_MLDSA87_RSA3072_PSS_SHA512},
{{8, "\53\6\1\5\5\7\6\65", BSL_OID_GLOBAL}, "MLDSA87-RSA4096-PSS-SHA512", BSL_CID_MLDSA87_RSA4096_PSS_SHA512},
{{8, "\53\6\1\5\5\7\6\66", BSL_OID_GLOBAL}, "MLDSA87-ECDSA-P521-SHA512", BSL_CID_MLDSA87_ECDSA_P521_SHA512},
{{8, "\53\6\1\5\5\7\6\43", BSL_OID_GLOBAL}, "XMSSMT", BSL_CID_XMSSMT},
{{10, "\52\206\110\206\367\15\1\11\27\1", BSL_OID_GLOBAL}, "x509crl", BSL_CID_X509CRL},
{{9, "\52\206\110\206\367\15\1\11\17", BSL_OID_GLOBAL}, "smimeCapabilities", BSL_CID_SMIMECAP},
{{8, "\53\6\1\5\5\7\10\7", BSL_OID_GLOBAL}, "id-on-dnsSRV", BSL_CID_ON_DNSSRV},
};
uint32_t g_tableSize = (uint32_t)sizeof(g_oidTable)/sizeof(g_oidTable[0]);
#ifdef HITLS_BSL_OBJ_CUSTOM
static void FreeBslOidInfo(void *data)
{
if (data == NULL) {
return;
}
BslOidInfo *oidInfo = (BslOidInfo *)data;
BSL_SAL_Free(oidInfo->strOid.octs);
BSL_SAL_Free((char *)(uintptr_t)oidInfo->oidName);
BSL_SAL_Free(oidInfo);
}
static void InitOidHashTableOnce(void)
{
int32_t ret = BSL_SAL_ThreadLockNew(&g_oidHashRwLock);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return;
}
ListDupFreeFuncPair valueFunc = {NULL, FreeBslOidInfo};
g_oidHashTable = BSL_HASH_Create(BSL_OBJ_HASH_BKT_SIZE, NULL, NULL, NULL, &valueFunc);
if (g_oidHashTable == NULL) {
(void)BSL_SAL_ThreadLockFree(g_oidHashRwLock);
g_oidHashRwLock = NULL;
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
}
}
#endif
static int32_t GetOidIndex(int32_t inputCid)
{
int32_t left = 0;
int32_t right = g_tableSize - 1;
while (left <= right) {
int32_t mid = (right - left) / 2 + left;
int32_t cid = g_oidTable[mid].cid;
if (cid == inputCid) {
return mid;
} else if (cid > inputCid) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
BslCid BSL_OBJ_GetCidFromOidBuff(const uint8_t *oid, uint32_t len)
{
if (oid == NULL || len == 0) {
return BSL_CID_UNKNOWN;
}
for (uint32_t i = 0; i < g_tableSize; i++) {
if (g_oidTable[i].strOid.octetLen == len) {
if (memcmp(g_oidTable[i].strOid.octs, oid, len) == 0) {
return g_oidTable[i].cid;
}
}
}
#ifndef HITLS_BSL_OBJ_CUSTOM
return BSL_CID_UNKNOWN;
#else
if (g_oidHashTable == NULL) {
return BSL_CID_UNKNOWN;
}
BslCid cid = BSL_CID_UNKNOWN;
int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return BSL_CID_UNKNOWN;
}
BSL_HASH_Iterator iter = BSL_HASH_IterBegin(g_oidHashTable);
BSL_HASH_Iterator end = BSL_HASH_IterEnd(g_oidHashTable);
while (iter != end) {
BslOidInfo *oidInfo = (BslOidInfo *)BSL_HASH_IterValue(g_oidHashTable, iter);
if (oidInfo != NULL && oidInfo->strOid.octetLen == len &&
memcmp(oidInfo->strOid.octs, oid, len) == 0) {
cid = oidInfo->cid;
break;
}
iter = BSL_HASH_IterNext(g_oidHashTable, iter);
}
(void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
return cid;
#endif
}
BslCid BSL_OBJ_GetCID(const BslOidString *oidstr)
{
if (oidstr == NULL) {
return BSL_CID_UNKNOWN;
}
return BSL_OBJ_GetCidFromOidBuff((const uint8_t *)oidstr->octs, oidstr->octetLen);
}
BslOidString *BSL_OBJ_GetOID(BslCid ulCID)
{
if (ulCID == BSL_CID_UNKNOWN) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
int32_t index = GetOidIndex(ulCID);
if (index != -1) {
return &g_oidTable[index].strOid;
}
#ifndef HITLS_BSL_OBJ_CUSTOM
return NULL;
#else
if (g_oidHashTable == NULL) {
return NULL;
}
BslOidInfo *oidInfo = NULL;
int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return NULL;
}
ret = BSL_HASH_At(g_oidHashTable, (uintptr_t)ulCID, (uintptr_t *)&oidInfo);
(void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
BslOidString *oidString = (ret == BSL_SUCCESS && oidInfo != NULL) ? &oidInfo->strOid : NULL;
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(BSL_OBJ_ERR_FIND_HASH_TABLE);
}
return oidString;
#endif
}
const char *BSL_OBJ_GetOidNameFromOidBuff(const uint8_t *oid, uint32_t len)
{
if (oid == NULL || len == 0) {
return NULL;
}
for (uint32_t i = 0; i < g_tableSize; i++) {
if (g_oidTable[i].strOid.octetLen == len) {
if (memcmp(g_oidTable[i].strOid.octs, oid, len) == 0) {
return g_oidTable[i].oidName;
}
}
}
#ifndef HITLS_BSL_OBJ_CUSTOM
return NULL;
#else
if (g_oidHashTable == NULL) {
BSL_ERR_PUSH_ERROR(BSL_OBJ_INVALID_HASH_TABLE);
return NULL;
}
const char *oidName = NULL;
int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return NULL;
}
BSL_HASH_Iterator iter = BSL_HASH_IterBegin(g_oidHashTable);
BSL_HASH_Iterator end = BSL_HASH_IterEnd(g_oidHashTable);
while (iter != end) {
BslOidInfo *oidInfo = (BslOidInfo *)BSL_HASH_IterValue(g_oidHashTable, iter);
if (oidInfo != NULL && oidInfo->strOid.octetLen == len &&
memcmp(oidInfo->strOid.octs, oid, len) == 0) {
oidName = oidInfo->oidName;
break;
}
iter = BSL_HASH_IterNext(g_oidHashTable, iter);
}
(void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
return oidName;
#endif
}
const char *BSL_OBJ_GetOidNameFromOid(const BslOidString *oid)
{
if (oid == NULL) {
return NULL;
}
return BSL_OBJ_GetOidNameFromOidBuff((const uint8_t *)oid->octs, oid->octetLen);
}
#if defined(HITLS_PKI_X509) || defined(HITLS_PKI_INFO)
* RFC 5280: A.1. Explicitly Tagged Module, 1988 Syntax
* -- Upper Bounds
*/
static const BslAsn1DnInfo g_asn1DnTab[] = {
{BSL_CID_AT_COMMONNAME, 1, 64, "CN"},
{BSL_CID_AT_SURNAME, 1, 40, "SN"},
{BSL_CID_AT_SERIALNUMBER, 1, 64, "serialNumber"},
{BSL_CID_AT_COUNTRYNAME, 2, 2, "C"},
{BSL_CID_AT_LOCALITYNAME, 1, 128, "L"},
{BSL_CID_AT_STATEORPROVINCENAME, 1, 128, "ST"},
{BSL_CID_AT_STREETADDRESS, 1, -1, "street"},
{BSL_CID_AT_ORGANIZATIONNAME, 1, 64, "O"},
{BSL_CID_AT_ORGANIZATIONALUNITNAME, 1, 64, "OU"},
{BSL_CID_AT_TITLE, 1, 64, "title"},
{BSL_CID_AT_GIVENNAME, 1, 32768, "GN"},
{BSL_CID_AT_INITIALS, 1, 32768, "initials"},
{BSL_CID_AT_GENERATIONQUALIFIER, 1, 32768, "generationQualifier"},
{BSL_CID_AT_DNQUALIFIER, 1, -1, "dnQualifier"},
{BSL_CID_AT_PSEUDONYM, 1, 128, "pseudonym"},
{BSL_CID_DOMAINCOMPONENT, 1, -1, "DC"},
{BSL_CID_AT_USERID, 1, 256, "UID"},
};
#define BSL_DN_STR_CNT (sizeof(g_asn1DnTab) / sizeof(g_asn1DnTab[0]))
const BslAsn1DnInfo *BSL_OBJ_GetDnInfoFromShortName(const char *shortName)
{
for (size_t i = 0; i < BSL_DN_STR_CNT; i++) {
if (strcmp(g_asn1DnTab[i].shortName, shortName) == 0) {
return &g_asn1DnTab[i];
}
}
return NULL;
}
const BslAsn1DnInfo *BSL_OBJ_GetDnInfoFromCid(BslCid cid)
{
for (size_t i = 0; i < sizeof(g_asn1DnTab) / sizeof(g_asn1DnTab[0]); i++) {
if (cid == g_asn1DnTab[i].cid) {
return &g_asn1DnTab[i];
}
}
return NULL;
}
#endif
#if defined(HITLS_PKI_X509) || defined(HITLS_PKI_INFO) || defined(HITLS_CRYPTO_KEY_INFO)
const char *BSL_OBJ_GetOidNameFromCID(BslCid ulCID)
{
if (ulCID >= BSL_CID_MAX) {
return NULL;
}
int32_t index = GetOidIndex(ulCID);
if (index == -1) {
return NULL;
}
return g_oidTable[index].oidName;
}
#endif
#ifdef HITLS_BSL_OBJ_CUSTOM
static int32_t BslOidStringCopy(const BslOidString *srcOidStr, BslOidString *oidString)
{
oidString->octs = BSL_SAL_Dump(srcOidStr->octs, srcOidStr->octetLen);
if (oidString->octs == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
return BSL_MALLOC_FAIL;
}
oidString->octetLen = srcOidStr->octetLen;
oidString->flags = srcOidStr->flags;
return BSL_SUCCESS;
}
static bool IsOidCidInStaticTable(int32_t cid)
{
for (uint32_t i = 0; i < g_tableSize; i++) {
if ((int32_t)g_oidTable[i].cid == cid) {
return true;
}
}
return false;
}
static int32_t IsOidCidInHashTable(int32_t cid)
{
BslOidInfo *oidInfo = NULL;
int32_t ret = BSL_SAL_ThreadReadLock(g_oidHashRwLock);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
ret = BSL_HASH_At(g_oidHashTable, (uintptr_t)cid, (uintptr_t *)&oidInfo);
(void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
return ret;
}
static int32_t CreateOidInfo(const BslOidString *oid, const char *oidName, int32_t cid, BslOidInfo **newOidInfo)
{
BslOidInfo *oidInfo = (BslOidInfo *)BSL_SAL_Calloc(1, sizeof(BslOidInfo));
if (oidInfo == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
return BSL_MALLOC_FAIL;
}
int32_t ret = BslOidStringCopy(oid, &oidInfo->strOid);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
BSL_SAL_Free(oidInfo);
return ret;
}
oidInfo->oidName = BSL_SAL_Dump(oidName, (uint32_t)strlen(oidName) + 1);
if (oidInfo->oidName == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
BSL_SAL_Free(oidInfo->strOid.octs);
BSL_SAL_Free(oidInfo);
return BSL_MALLOC_FAIL;
}
oidInfo->cid = cid;
*newOidInfo = oidInfo;
return BSL_SUCCESS;
}
static int32_t InsertOidInfoToHashTable(int32_t cid, BslOidInfo *oidInfo)
{
int32_t ret = BSL_SAL_ThreadWriteLock(g_oidHashRwLock);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
BslOidInfo *checkInfo = NULL;
ret = BSL_HASH_At(g_oidHashTable, (uintptr_t)cid, (uintptr_t *)&checkInfo);
if (ret == BSL_SUCCESS) {
(void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
return BSL_SUCCESS;
}
ret = BSL_HASH_Insert(g_oidHashTable, (uintptr_t)cid, sizeof(int32_t), (uintptr_t)oidInfo, sizeof(BslOidInfo));
(void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
return ret;
}
int32_t BSL_OBJ_Create(char *octs, uint32_t octetLen, const char *oidName, int32_t cid)
{
if (octs == NULL || octetLen == 0 || oidName == NULL || cid == BSL_CID_UNKNOWN) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return BSL_INVALID_ARG;
}
if (IsOidCidInStaticTable(cid)) {
return BSL_SUCCESS;
}
const BslOidString oid = {
.octs = octs,
.octetLen = octetLen,
.flags = 6
};
int32_t ret = BSL_SAL_ThreadRunOnce(&g_oidHashInitOnce, InitOidHashTableOnce);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
if (g_oidHashTable == NULL) {
BSL_ERR_PUSH_ERROR(BSL_OBJ_INVALID_HASH_TABLE);
return BSL_OBJ_INVALID_HASH_TABLE;
}
ret = IsOidCidInHashTable(cid);
if (ret == BSL_SUCCESS) {
return BSL_SUCCESS;
}
BslOidInfo *oidInfo = NULL;
ret = CreateOidInfo(&oid, oidName, cid, &oidInfo);
if (ret != BSL_SUCCESS) {
return ret;
}
ret = InsertOidInfoToHashTable(cid, oidInfo);
if (ret != BSL_SUCCESS) {
FreeBslOidInfo(oidInfo);
return ret;
}
return BSL_SUCCESS;
}
void BSL_OBJ_FreeHashTable(void)
{
if (g_oidHashTable != NULL) {
int32_t ret = BSL_SAL_ThreadWriteLock(g_oidHashRwLock);
if (ret != BSL_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return;
}
BSL_HASH_Destroy(g_oidHashTable);
g_oidHashTable = NULL;
(void)BSL_SAL_ThreadUnlock(g_oidHashRwLock);
if (g_oidHashRwLock != NULL) {
(void)BSL_SAL_ThreadLockFree(g_oidHashRwLock);
g_oidHashRwLock = NULL;
}
memset(&g_oidHashInitOnce, 0, sizeof(g_oidHashInitOnce));
}
}
#endif
* Conversion Rules:
* The first byte represents the first two nodes: X.Y, where X = first byte / 40, Y = first byte % 40.
* Subsequent nodes use variable length encoding (Base 128), where the highest bit of each byte indicates
* whether there are subsequent bytes (1 indicates continuation, 0 indicates end).
* Detailed conversion process:
* 1、Split the first two nodes, the first byte is decomposed into two numbers: first_node and second_node,
* first_node = byte_value / 40, second_node = byte_value % 40.
* 2、Decoding subsequent nodes, Each node may be composed of multiple bytes, with the most significant bit (MSB)
* of each byte being the continuation flag and the remaining 7 bits being a part of the actual value,
* Multiple 7-bit groups are combined in big endian order.
*/
char *BSL_OBJ_GetOidNumericString(const uint8_t *oid, uint32_t len)
{
if (oid == NULL || len < 1 || oid[0] > BSL_OBJ_ARCS_MAX) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
char buffer[256] = {0};
(void)snprintf(buffer, sizeof(buffer), "%d.%d", oid[0] / BSL_OBJ_ARCS_Y_MAX,
oid[0] % BSL_OBJ_ARCS_Y_MAX);
uint64_t value = 0;
uint32_t currentPos = strlen(buffer);
for (uint32_t i = 1; i < len; i++) {
if (value > (UINT64_MAX >> 7)) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
if ((value == 0) && ((oid[i]) == 0x80)) {
No unnecessary or meaningless leading bytes are allowed */
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
value = (value << 7) | (oid[i] & 0x7F);
if (!(oid[i] & 0x80)) {
char temp[20] = {0};
int tempLen = snprintf(temp, sizeof(temp), ".%lu", (unsigned long)value);
if (tempLen < 0 || (size_t)tempLen >= sizeof(temp)) {
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
return NULL;
}
if (currentPos + (uint32_t)tempLen >= sizeof(buffer)) {
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
return NULL;
}
memcpy(buffer + currentPos, temp, tempLen);
currentPos += tempLen;
value = 0;
}
}
if (value != 0) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
return BSL_SAL_Dump(buffer, sizeof(buffer));
}
static void BslEncodeOidPart(uint64_t num, uint8_t *output, uint32_t *offset)
{
if (num < 0x80) {
output[*offset] = num &0x7F;
(*offset)++;
} else {
uint8_t temp[10];
int32_t i = 0;
uint64_t t = num;
while (t > 0) {
temp[i] = (t & 0x7F) | 0x80;
i++;
t >>= 7;
}
temp[0] &= 0x7F;
for (int32_t j = i - 1; j >= 0; j--) {
output[*offset] = temp[j];
(*offset)++;
}
}
}
static bool BslEncodeOidValueCheck(uint64_t *parts, uint32_t count)
{
if (count < 2 || parts[0] > BSL_OBJ_ARCS_X_MAX) {
return false;
}
if (parts[1] >= BSL_OBJ_ARCS_Y_MAX) {
return false;
}
return true;
}
#define MAX_OID_PARTS_LEN 128
uint8_t *BSL_OBJ_GetOidFromNumericString(const char *oid, uint32_t len, uint32_t *outLen)
{
if (len == 0 || oid == NULL || oid[0] == '.' || outLen == NULL || oid[len - 1] == '.') {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
uint64_t parts[MAX_OID_PARTS_LEN];
uint32_t count = 0;
parts[count] = 0;
for (uint32_t i = 0; i < len; i++) {
if (oid[i] > '9' || (oid[i] < '0' && oid[i] != '.')) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
if ((i < len - 1) && oid[i] == '.' && oid[i + 1] == '.') {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
if (oid[i] != '.') {
if (parts[count] > (UINT64_MAX - (oid[i] - '0')) / 10) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
parts[count] = parts[count] * 10 + (oid[i] - '0');
} else {
count++;
if (count >= MAX_OID_PARTS_LEN) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
parts[count] = 0;
}
}
count++;
if (BslEncodeOidValueCheck(parts, count) != true) {
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
return NULL;
}
uint32_t offset = 0;
uint8_t *outBuf = BSL_SAL_Malloc(count * 10);
if (outBuf == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
return NULL;
}
outBuf[0] = (uint8_t)(parts[0] * BSL_OBJ_ARCS_Y_MAX + parts[1]);
offset++;
for (uint32_t i = 2; i < count; i++) {
BslEncodeOidPart(parts[i], outBuf, &offset);
}
*outLen = offset;
return outBuf;
}
#endif