From b97d5da1375fbd1460a8c8ed7e3a41b49ac7fbe4 Mon Sep 17 00:00:00 2001 From: kang1024 Date: Wed, 9 Apr 2025 15:43:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8taihe=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E9=87=8D=E5=86=99=E5=9B=BE=E5=BA=93=E4=BE=9D=E8=B5=96=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: kang1024 --- frameworks/crypto_operation/mac.c | 4 +- frameworks/js/ani/BUILD.gn | 92 +++- frameworks/js/ani/dts/cert.d.ts | 427 +++++++++++++++ frameworks/js/ani/dts/cryptoFramework.d.ts | 490 ++++++++++++++++++ ...rity.cryptoFramework.cryptoFramework.taihe | 83 +++ frameworks/js/ani/inc/ani_common.h | 35 ++ frameworks/js/ani/inc/ani_key.h | 37 ++ frameworks/js/ani/inc/ani_mac.h | 43 ++ frameworks/js/ani/inc/ani_md.h | 42 ++ frameworks/js/ani/inc/ani_rand.h | 41 ++ frameworks/js/ani/inc/ani_sym_key.h | 43 ++ frameworks/js/ani/inc/ani_sym_key_generator.h | 41 ++ frameworks/js/ani/src/ani_constructor.cpp | 30 ++ frameworks/js/ani/src/ani_key.cpp | 41 ++ frameworks/js/ani/src/ani_mac.cpp | 110 ++++ frameworks/js/ani/src/ani_md.cpp | 91 ++++ frameworks/js/ani/src/ani_rand.cpp | 84 +++ .../ani_sym_key.cpp} | 79 ++- .../js/ani/src/ani_sym_key_generator.cpp | 75 +++ frameworks/js/ani/src/cryptoframework_ani.cpp | 283 ---------- ...y.cryptoFramework.cryptoFramework.impl.cpp | 193 +++++++ frameworks/js/ani/test/arktsconfig.json | 4 +- frameworks/js/ani/test/test_mac.ets | 41 ++ frameworks/js/ani/test/test_main.ets | 24 + frameworks/js/ani/test/test_md.ets | 35 ++ frameworks/js/ani/test/test_rand.ets | 34 ++ .../js/ani/test/{test.ets => test_utils.ets} | 30 +- 27 files changed, 2148 insertions(+), 384 deletions(-) create mode 100644 frameworks/js/ani/dts/cert.d.ts create mode 100644 frameworks/js/ani/dts/cryptoFramework.d.ts create mode 100644 frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe create mode 100644 frameworks/js/ani/inc/ani_common.h create mode 100644 frameworks/js/ani/inc/ani_key.h create mode 100644 frameworks/js/ani/inc/ani_mac.h create mode 100644 frameworks/js/ani/inc/ani_md.h create mode 100644 frameworks/js/ani/inc/ani_rand.h create mode 100644 frameworks/js/ani/inc/ani_sym_key.h create mode 100644 frameworks/js/ani/inc/ani_sym_key_generator.h create mode 100644 frameworks/js/ani/src/ani_constructor.cpp create mode 100644 frameworks/js/ani/src/ani_key.cpp create mode 100644 frameworks/js/ani/src/ani_mac.cpp create mode 100644 frameworks/js/ani/src/ani_md.cpp create mode 100644 frameworks/js/ani/src/ani_rand.cpp rename frameworks/js/ani/{ets/@ohos.security.cryptoFramework.ets => src/ani_sym_key.cpp} (35%) create mode 100644 frameworks/js/ani/src/ani_sym_key_generator.cpp delete mode 100644 frameworks/js/ani/src/cryptoframework_ani.cpp create mode 100644 frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp create mode 100644 frameworks/js/ani/test/test_mac.ets create mode 100644 frameworks/js/ani/test/test_main.ets create mode 100644 frameworks/js/ani/test/test_md.ets create mode 100644 frameworks/js/ani/test/test_rand.ets rename frameworks/js/ani/test/{test.ets => test_utils.ets} (61%) diff --git a/frameworks/crypto_operation/mac.c b/frameworks/crypto_operation/mac.c index ea6c22e..88b5f2f 100644 --- a/frameworks/crypto_operation/mac.c +++ b/frameworks/crypto_operation/mac.c @@ -180,7 +180,7 @@ static HcfResult HandleCmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *par return HCF_INVALID_PARAMS; } *createSpiFunc = OpensslCmacSpiCreate; - return SetMacAlgoName(macImpl, cipherName); + return SetMacAlgoName(macImpl, paramsSpec->algName); } static HcfResult HandleHmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *paramsSpec, @@ -192,7 +192,7 @@ static HcfResult HandleHmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *par LOGE("Unsupported HMAC algorithm: %{public}s", mdName); return HCF_INVALID_PARAMS; } - return SetMacAlgoName(macImpl, mdName); + return SetMacAlgoName(macImpl, paramsSpec->algName); } HcfResult HcfMacCreate(HcfMacParamsSpec *paramsSpec, HcfMac **mac) diff --git a/frameworks/js/ani/BUILD.gn b/frameworks/js/ani/BUILD.gn index b38cfea..554cf25 100644 --- a/frameworks/js/ani/BUILD.gn +++ b/frameworks/js/ani/BUILD.gn @@ -16,9 +16,45 @@ import("//base/security/crypto_framework/frameworks/frameworks.gni") import("//base/security/crypto_framework/plugin/plugin.gni") import("//build/config/components/ets_frontend/ets2abc_config.gni") import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") -ohos_shared_library("crypto_framework_ani") { - branch_protector_ret = "pac_ret" +subsystem_name = "security" +part_name = "crypto_framework" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" + +copy_taihe_idl("copy_taihe") { + sources = [ "${framework_path}/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe" ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.security.cryptoFramework.cryptoFramework.ani.cpp", + "$taihe_generated_file_path/src/ohos.security.cryptoFramework.cryptoFramework.abi.c", + ] +} + +taihe_shared_library("crypto_framework_ani") { + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + include_dirs = framework_inc_path + include_dirs += [ "${framework_path}/js/ani/inc" ] + sources = get_target_outputs(":run_taihe") + sources += [ + "${framework_path}/js/ani/src/ani_constructor.cpp", + "${framework_path}/js/ani/src/ani_key.cpp", + "${framework_path}/js/ani/src/ani_mac.cpp", + "${framework_path}/js/ani/src/ani_md.cpp", + "${framework_path}/js/ani/src/ani_rand.cpp", + "${framework_path}/js/ani/src/ani_sym_key.cpp", + "${framework_path}/js/ani/src/ani_sym_key_generator.cpp", + ] + deps = [ + ":run_taihe", + "//base/security/crypto_framework/frameworks:crypto_framework_lib", + ] if (os_level == "standard") { sanitize = { cfi = true @@ -26,22 +62,11 @@ ohos_shared_library("crypto_framework_ani") { debug = false } } - cflags = [ - "-Wall", - "-Werror", - "-fPIC", "-DHILOG_ENABLE", + "-fPIC", + "-g3", ] - - subsystem_name = "security" - part_name = "crypto_framework" - - include_dirs = framework_inc_path - sources = crypto_framwork_common_files + plugin_files + framework_key_files + - framework_mac_files - sources += [ "./src/cryptoframework_ani.cpp" ] - external_deps = [ "bounds_checking_function:libsec_shared", "c_utils:utils", @@ -51,24 +76,41 @@ ohos_shared_library("crypto_framework_ani") { ] } -generate_static_abc("cryptoframework") { - base_url = "./ets" - files = [ "./ets/@ohos.security.cryptoFramework.ets" ] +generate_static_abc("crypto_framework_ets") { + base_url = "$taihe_generated_file_path" + files = [ "$taihe_generated_file_path/@ohos.security.cryptoFramework.ets" ] is_boot_abc = "True" - device_dst_file = "/system/framework/cryptoframework.abc" + device_dst_file = "/system/framework/crypto_framework_ets.abc" + dependencies = [ ":run_taihe" ] } -ohos_prebuilt_etc("crypto_framework_abc") { - source = "$target_out_dir/cryptoframework.abc" +generate_static_abc("crypto_framework_test") { + base_url = "${framework_path}/js/ani/test" + files = [ + "${framework_path}/js/ani/test/test_main.ets", + "${framework_path}/js/ani/test/test_md.ets", + "${framework_path}/js/ani/test/test_mac.ets", + "${framework_path}/js/ani/test/test_rand.ets", + "${framework_path}/js/ani/test/test_utils.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/crypto_framework_test.abc" +} + +ohos_prebuilt_etc("crypto_framework_etc") { + source = "$target_out_dir/crypto_framework_ets.abc" module_install_dir = "framework" - subsystem_name = "security" - part_name = "crypto_framework" - deps = [ ":cryptoframework" ] + part_name = "$part_name" + subsystem_name = "$subsystem_name" + deps = [ + ":crypto_framework_ets", + # ":crypto_framework_test", + ] } group("cryptoframework_ani") { deps = [ - ":crypto_framework_abc", ":crypto_framework_ani", + ":crypto_framework_etc", ] } diff --git a/frameworks/js/ani/dts/cert.d.ts b/frameworks/js/ani/dts/cert.d.ts new file mode 100644 index 0000000..012c662 --- /dev/null +++ b/frameworks/js/ani/dts/cert.d.ts @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { AsyncCallback } from './@ohos.base'; +import cryptoFramework from './@ohos.security.cryptoFramework'; + +declare namespace cert { + enum CertResult { + INVALID_PARAMS = 401, + NOT_SUPPORT = 801, + ERR_OUT_OF_MEMORY = 19020001, + ERR_RUNTIME_ERROR = 19020002, + ERR_CRYPTO_OPERATION = 19030001, + ERR_CERT_SIGNATURE_FAILURE = 19030002, + ERR_CERT_NOT_YET_VALID = 19030003, + ERR_CERT_HAS_EXPIRED = 19030004, + ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 19030005, + ERR_KEYUSAGE_NO_CERTSIGN = 19030006, + ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE = 19030007, + ERR_MAYBE_WRONG_PASSWORD = 19030008 + } + + interface DataBlob { + data: Uint8Array; + } + + interface DataArray { + data: Array; + } + + enum EncodingFormat { + FORMAT_DER = 0, + FORMAT_PEM = 1, + FORMAT_PKCS7 = 2 + } + + enum CertItemType { + CERT_ITEM_TYPE_TBS = 0, + CERT_ITEM_TYPE_PUBLIC_KEY = 1, + CERT_ITEM_TYPE_ISSUER_UNIQUE_ID = 2, + CERT_ITEM_TYPE_SUBJECT_UNIQUE_ID = 3, + CERT_ITEM_TYPE_EXTENSIONS = 4 + } + + enum ExtensionOidType { + EXTENSION_OID_TYPE_ALL = 0, + EXTENSION_OID_TYPE_CRITICAL = 1, + EXTENSION_OID_TYPE_UNCRITICAL = 2 + } + + enum ExtensionEntryType { + EXTENSION_ENTRY_TYPE_ENTRY = 0, + EXTENSION_ENTRY_TYPE_ENTRY_CRITICAL = 1, + EXTENSION_ENTRY_TYPE_ENTRY_VALUE = 2 + } + + interface EncodingBlob { + data: Uint8Array; + encodingFormat: EncodingFormat; + } + + interface CertChainData { + data: Uint8Array; + count: number; + encodingFormat: EncodingFormat; + } + + enum EncodingType { + ENCODING_UTF8 = 0 + } + + interface X509Cert { + verify(key: cryptoFramework.PubKey, callback: AsyncCallback): void; + verify(key: cryptoFramework.PubKey): Promise; + getEncoded(callback: AsyncCallback): void; + getEncoded(): Promise; + getPublicKey(): cryptoFramework.PubKey; + checkValidityWithDate(date: string): void; + getVersion(): number; + getSerialNumber(): number; + getCertSerialNumber(): bigint; + getIssuerName(): DataBlob; + getSubjectName(encodingType?: EncodingType): DataBlob; + getNotBeforeTime(): string; + getNotAfterTime(): string; + getSignature(): DataBlob; + getSignatureAlgName(): string; + getSignatureAlgOid(): string; + getSignatureAlgParams(): DataBlob; + getKeyUsage(): DataBlob; + getExtKeyUsage(): DataArray; + getBasicConstraints(): number; + getSubjectAltNames(): DataArray; + getIssuerAltNames(): DataArray; + getItem(itemType: CertItemType): DataBlob; + match(param: X509CertMatchParameters): boolean; + getCRLDistributionPoint(): DataArray; + getIssuerX500DistinguishedName(): X500DistinguishedName; + getSubjectX500DistinguishedName(): X500DistinguishedName; + toString(): string; + hashCode(): Uint8Array; + getExtensionsObject(): CertExtension; + } + function createX509Cert(inStream: EncodingBlob, callback: AsyncCallback): void; + function createX509Cert(inStream: EncodingBlob): Promise; + + interface CertExtension { + getEncoded(): EncodingBlob; + getOidList(valueType: ExtensionOidType): DataArray; + getEntry(valueType: ExtensionEntryType, oid: DataBlob): DataBlob; + checkCA(): number; + hasUnsupportedCriticalExtension(): boolean; + } + function createCertExtension(inStream: EncodingBlob, callback: AsyncCallback): void; + function createCertExtension(inStream: EncodingBlob): Promise; + + interface X509CrlEntry { + getEncoded(callback: AsyncCallback): void; + getEncoded(): Promise; + getSerialNumber(): number; + getCertIssuer(): DataBlob; + getRevocationDate(): string; + } + + interface X509CRLEntry { + getEncoded(callback: AsyncCallback): void; + getEncoded(): Promise; + getSerialNumber(): bigint; + getCertIssuer(): DataBlob; + getRevocationDate(): string; + getExtensions(): DataBlob; + hasExtensions(): boolean; + getCertIssuerX500DistinguishedName(): X500DistinguishedName; + toString(): string; + hashCode(): Uint8Array; + getExtensionsObject(): CertExtension; + } + + interface X509Crl { + isRevoked(cert: X509Cert): boolean; + getType(): string; + getEncoded(callback: AsyncCallback): void; + getEncoded(): Promise; + verify(key: cryptoFramework.PubKey, callback: AsyncCallback): void; + verify(key: cryptoFramework.PubKey): Promise; + getVersion(): number; + getIssuerName(): DataBlob; + getLastUpdate(): string; + getNextUpdate(): string; + getRevokedCert(serialNumber: number): X509CrlEntry; + getRevokedCertWithCert(cert: X509Cert): X509CrlEntry; + getRevokedCerts(callback: AsyncCallback>): void; + getRevokedCerts(): Promise>; + getTbsInfo(): DataBlob; + getSignature(): DataBlob; + getSignatureAlgName(): string; + getSignatureAlgOid(): string; + getSignatureAlgParams(): DataBlob; + } + function createX509Crl(inStream: EncodingBlob, callback: AsyncCallback): void; + function createX509Crl(inStream: EncodingBlob): Promise; + + interface X509CRL { + isRevoked(cert: X509Cert): boolean; + getType(): string; + getEncoded(callback: AsyncCallback): void; + getEncoded(): Promise; + verify(key: cryptoFramework.PubKey, callback: AsyncCallback): void; + verify(key: cryptoFramework.PubKey): Promise; + getVersion(): number; + getIssuerName(): DataBlob; + getLastUpdate(): string; + getNextUpdate(): string; + getRevokedCert(serialNumber: bigint): X509CRLEntry; + getRevokedCertWithCert(cert: X509Cert): X509CRLEntry; + getRevokedCerts(callback: AsyncCallback>): void; + getRevokedCerts(): Promise>; + getTBSInfo(): DataBlob; + getSignature(): DataBlob; + getSignatureAlgName(): string; + getSignatureAlgOid(): string; + getSignatureAlgParams(): DataBlob; + getExtensions(): DataBlob; + match(param: X509CRLMatchParameters): boolean; + getIssuerX500DistinguishedName(): X500DistinguishedName; + toString(): string; + hashCode(): Uint8Array; + getExtensionsObject(): CertExtension; + } + function createX509CRL(inStream: EncodingBlob, callback: AsyncCallback): void; + function createX509CRL(inStream: EncodingBlob): Promise; + + interface CertChainValidator { + validate(certChain: CertChainData, callback: AsyncCallback): void; + validate(certChain: CertChainData): Promise; + readonly algorithm: string; + } + function createCertChainValidator(algorithm: string): CertChainValidator; + + enum GeneralNameType { + GENERAL_NAME_TYPE_OTHER_NAME = 0, + GENERAL_NAME_TYPE_RFC822_NAME = 1, + GENERAL_NAME_TYPE_DNS_NAME = 2, + GENERAL_NAME_TYPE_X400_ADDRESS = 3, + GENERAL_NAME_TYPE_DIRECTORY_NAME = 4, + GENERAL_NAME_TYPE_EDI_PARTY_NAME = 5, + GENERAL_NAME_TYPE_UNIFORM_RESOURCE_ID = 6, + GENERAL_NAME_TYPE_IP_ADDRESS = 7, + GENERAL_NAME_TYPE_REGISTERED_ID = 8 + } + + interface GeneralName { + type: GeneralNameType; + name?: Uint8Array; + } + + interface X509CertMatchParameters { + subjectAlternativeNames?: Array; + matchAllSubjectAltNames?: boolean; + authorityKeyIdentifier?: Uint8Array; + minPathLenConstraint?: number; + x509Cert?: X509Cert; + validDate?: string; + issuer?: Uint8Array; + extendedKeyUsage?: Array; + nameConstraints?: Uint8Array; + certPolicy?: Array; + privateKeyValid?: string; + keyUsage?: Array; + serialNumber?: bigint; + subject?: Uint8Array; + subjectKeyIdentifier?: Uint8Array; + publicKey?: DataBlob; + publicKeyAlgID?: string; + } + + interface X509CRLMatchParameters { + issuer?: Array; + x509Cert?: X509Cert; + updateDateTime?: string; + maxCRL?: bigint; + minCRL?: bigint; + } + + interface CertCRLCollection { + selectCerts(param: X509CertMatchParameters): Promise>; + selectCerts(param: X509CertMatchParameters, callback: AsyncCallback>): void; + selectCRLs(param: X509CRLMatchParameters): Promise>; + selectCRLs(param: X509CRLMatchParameters, callback: AsyncCallback>): void; + } + function createCertCRLCollection(certs: Array, crls?: Array): CertCRLCollection; + + interface X509CertChain { + getCertList(): Array; + validate(param: CertChainValidationParameters): Promise; + validate(param: CertChainValidationParameters, callback: AsyncCallback): void; + toString(): string; + hashCode(): Uint8Array; + } + function createX509CertChain(inStream: EncodingBlob): Promise; + function createX509CertChain(inStream: EncodingBlob, callback: AsyncCallback): void; + function createX509CertChain(certs: Array): X509CertChain; + function buildX509CertChain(param: CertChainBuildParameters): Promise; + + enum EncodingBaseFormat { + PEM = 0, + DER = 1 + } + + interface Pkcs12Data { + privateKey?: string | Uint8Array; + cert?: X509Cert; + otherCerts?: Array; + } + + interface Pkcs12ParsingConfig { + password: string; + needsPrivateKey?: boolean; + privateKeyFormat?: EncodingBaseFormat; + needsCert?: boolean; + needsOtherCerts?: boolean; + } + function parsePkcs12(data: Uint8Array, config: Pkcs12ParsingConfig): Pkcs12Data; + function createTrustAnchorsWithKeyStore(keystore: Uint8Array, pwd: string): Promise>; + function createX500DistinguishedName(nameStr: string): Promise; + function createX500DistinguishedName(nameDer: Uint8Array): Promise; + + interface X500DistinguishedName { + getName(): string; + getName(type: string): Array; + getEncoded(): EncodingBlob; + } + + interface X509TrustAnchor { + CACert?: X509Cert; + CAPubKey?: Uint8Array; + CASubject?: Uint8Array; + nameConstraints?: Uint8Array; + } + + enum RevocationCheckOptions { + REVOCATION_CHECK_OPTION_PREFER_OCSP = 0, + REVOCATION_CHECK_OPTION_ACCESS_NETWORK, + REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER, + REVOCATION_CHECK_OPTION_FALLBACK_LOCAL + } + + enum ValidationPolicyType { + VALIDATION_POLICY_TYPE_X509 = 0, + VALIDATION_POLICY_TYPE_SSL + } + + enum KeyUsageType { + KEYUSAGE_DIGITAL_SIGNATURE = 0, + KEYUSAGE_NON_REPUDIATION, + KEYUSAGE_KEY_ENCIPHERMENT, + KEYUSAGE_DATA_ENCIPHERMENT, + KEYUSAGE_KEY_AGREEMENT, + KEYUSAGE_KEY_CERT_SIGN, + KEYUSAGE_CRL_SIGN, + KEYUSAGE_ENCIPHER_ONLY, + KEYUSAGE_DECIPHER_ONLY + } + + interface RevocationCheckParameter { + ocspRequestExtension?: Array; + ocspResponderURI?: string; + ocspResponderCert?: X509Cert; + ocspResponses?: Uint8Array; + crlDownloadURI?: string; + options?: Array; + ocspDigest?: string; + } + + interface CertChainValidationParameters { + date?: string; + trustAnchors: Array; + certCRLs?: Array; + revocationCheckParam?: RevocationCheckParameter; + policy?: ValidationPolicyType; + sslHostname?: string; + keyUsage?: Array; + } + + interface CertChainValidationResult { + readonly trustAnchor: X509TrustAnchor; + readonly entityCert: X509Cert; + } + + interface CertChainBuildParameters { + certMatchParameters: X509CertMatchParameters; + maxLength?: number; + validationParameters: CertChainValidationParameters; + } + + interface CertChainBuildResult { + readonly certChain: X509CertChain; + readonly validationResult: CertChainValidationResult; + } + + enum CmsContentType { + SIGNED_DATA = 0 + } + + enum CmsContentDataFormat { + BINARY = 0, + TEXT = 1 + } + + enum CmsFormat { + PEM = 0, + DER = 1 + } + + interface PrivateKeyInfo { + key: string | Uint8Array; + password?: string; + } + + interface CmsSignerConfig { + mdName: string; + addCert?: boolean; + addAttr?: boolean; + addSmimeCapAttr?: boolean; + } + + interface CmsGeneratorOptions { + contentDataFormat?: CmsContentDataFormat; + outFormat?: CmsFormat; + isDetached?: boolean; + } + + interface CmsGenerator { + addSigner(cert: X509Cert, keyInfo: PrivateKeyInfo, config: CmsSignerConfig): void; + addCert(cert: X509Cert): void; + doFinal(data: Uint8Array, options?: CmsGeneratorOptions): Promise; + doFinalSync(data: Uint8Array, options?: CmsGeneratorOptions): Uint8Array | string; + } + function createCmsGenerator(contentType: CmsContentType): CmsGenerator; + + interface CsrAttribute { + type: string; + value: string; + } + + interface CsrGenerationConfig { + subject: X500DistinguishedName; + mdName: string; + attributes?: Array; + outFormat?: EncodingBaseFormat; + } + function generateCsr(keyInfo: PrivateKeyInfo, config: CsrGenerationConfig): string | Uint8Array; +} + +export default cert; diff --git a/frameworks/js/ani/dts/cryptoFramework.d.ts b/frameworks/js/ani/dts/cryptoFramework.d.ts new file mode 100644 index 0000000..87c5247 --- /dev/null +++ b/frameworks/js/ani/dts/cryptoFramework.d.ts @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { AsyncCallback, Callback } from './@ohos.base'; + +declare namespace cryptoFramework { + enum Result { + INVALID_PARAMS = 401, + NOT_SUPPORT = 801, + ERR_OUT_OF_MEMORY = 17620001, + ERR_RUNTIME_ERROR = 17620002, + ERR_CRYPTO_OPERATION = 17630001 + } + + interface DataBlob { + data: Uint8Array; + } + + interface ParamsSpec { + algName: string; + } + + interface IvParamsSpec extends ParamsSpec { + iv: DataBlob; + } + + interface GcmParamsSpec extends ParamsSpec { + iv: DataBlob; + aad: DataBlob; + authTag: DataBlob; + } + + interface CcmParamsSpec extends ParamsSpec { + iv: DataBlob; + aad: DataBlob; + authTag: DataBlob; + } + + enum CryptoMode { + ENCRYPT_MODE = 0, + DECRYPT_MODE = 1 + } + + interface KeyEncodingConfig { + password: string; + cipherName: string; + } + + + interface Key { + getEncoded(): DataBlob; + readonly format: string; + readonly algName: string; + } + + interface SymKey extends Key { + clearMem(): void; + } + + interface PriKey extends Key { + clearMem(): void; + getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number; + getEncodedDer(format: string): DataBlob; + getEncodedPem(format: string): string; + getEncodedPem(format: string, config: KeyEncodingConfig): string; + } + + interface PubKey extends Key { + getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number; + getEncodedDer(format: string): DataBlob; + getEncodedPem(format: string): string; + } + + interface KeyPair { + readonly priKey: PriKey; + readonly pubKey: PubKey; + } + + interface Random { + generateRandom(len: number, callback: AsyncCallback): void; + generateRandom(len: number): Promise; + generateRandomSync(len: number): DataBlob; + setSeed(seed: DataBlob): void; + readonly algName: string; + } + function createRandom(): Random; + + interface AsyKeyGenerator { + generateKeyPair(callback: AsyncCallback): void; + generateKeyPair(): Promise; + generateKeyPairSync(): KeyPair; + convertKey(pubKey: DataBlob, priKey: DataBlob, callback: AsyncCallback): void; + convertKey(pubKey: DataBlob | null, priKey: DataBlob | null, callback: AsyncCallback): void; + convertKey(pubKey: DataBlob, priKey: DataBlob): Promise; + convertKey(pubKey: DataBlob | null, priKey: DataBlob | null): Promise; + convertKeySync(pubKey: DataBlob | null, priKey: DataBlob | null): KeyPair; + convertPemKey(pubKey: string | null, priKey: string | null): Promise; + convertPemKey(pubKey: string | null, priKey: string | null, password: string): Promise; + convertPemKeySync(pubKey: string | null, priKey: string | null): KeyPair; + convertPemKeySync(pubKey: string | null, priKey: string | null, password: string): KeyPair; + readonly algName: string; + } + + interface SymKeyGenerator { + generateSymKey(callback: AsyncCallback): void; + generateSymKey(): Promise; + generateSymKeySync(): SymKey; + convertKey(key: DataBlob, callback: AsyncCallback): void; + convertKey(key: DataBlob): Promise; + convertKeySync(key: DataBlob): SymKey; + readonly algName: string; + } + + function createAsyKeyGenerator(algName: string): AsyKeyGenerator; + function createSymKeyGenerator(algName: string): SymKeyGenerator; + + interface MacSpec { + algName: string; + } + + interface HmacSpec extends MacSpec { + mdName: string; + } + + interface CmacSpec extends MacSpec { + cipherName: string; + } + + interface Mac { + init(key: SymKey, callback: AsyncCallback): void; + init(key: SymKey): Promise; + initSync(key: SymKey): void; + update(input: DataBlob, callback: AsyncCallback): void; + update(input: DataBlob): Promise; + updateSync(input: DataBlob): void; + doFinal(callback: AsyncCallback): void; + doFinal(): Promise; + doFinalSync(): DataBlob; + getMacLength(): number; + readonly algName: string; + } + function createMac(algName: string): Mac; + function createMac(macSpec: MacSpec): Mac; + + interface Md { + update(input: DataBlob, callback: AsyncCallback): void; + update(input: DataBlob): Promise; + updateSync(input: DataBlob): void; + digest(callback: AsyncCallback): void; + digest(): Promise; + digestSync(): DataBlob; + getMdLength(): number; + readonly algName: string; + } + function createMd(algName: string): Md; + + enum CipherSpecItem { + OAEP_MD_NAME_STR = 100, + OAEP_MGF_NAME_STR = 101, + OAEP_MGF1_MD_STR = 102, + OAEP_MGF1_PSRC_UINT8ARR = 103, + SM2_MD_NAME_STR = 104 + } + + enum SignSpecItem { + PSS_MD_NAME_STR = 100, + PSS_MGF_NAME_STR = 101, + PSS_MGF1_MD_STR = 102, + PSS_SALT_LEN_NUM = 103, + PSS_TRAILER_FIELD_NUM = 104, + SM2_USER_ID_UINT8ARR = 105 + } + + interface Cipher { + init(opMode: CryptoMode, key: Key, params: ParamsSpec, callback: AsyncCallback): void; + init(opMode: CryptoMode, key: Key, params: ParamsSpec | null, callback: AsyncCallback): void; + init(opMode: CryptoMode, key: Key, params: ParamsSpec): Promise; + init(opMode: CryptoMode, key: Key, params: ParamsSpec | null): Promise; + initSync(opMode: CryptoMode, key: Key, params: ParamsSpec | null): void; + update(data: DataBlob, callback: AsyncCallback): void; + update(data: DataBlob): Promise; + updateSync(data: DataBlob): DataBlob; + doFinal(data: DataBlob, callback: AsyncCallback): void; + doFinal(data: DataBlob | null, callback: AsyncCallback): void; + doFinal(data: DataBlob): Promise; + doFinal(data: DataBlob | null): Promise; + doFinalSync(data: DataBlob | null): DataBlob; + setCipherSpec(itemType: CipherSpecItem, itemValue: Uint8Array): void; + getCipherSpec(itemType: CipherSpecItem): string | Uint8Array; + readonly algName: string; + } + function createCipher(transformation: string): Cipher; + + interface Sign { + init(priKey: PriKey, callback: AsyncCallback): void; + init(priKey: PriKey): Promise; + initSync(priKey: PriKey): void; + update(data: DataBlob, callback: AsyncCallback): void; + update(data: DataBlob): Promise; + updateSync(data: DataBlob): void; + sign(data: DataBlob, callback: AsyncCallback): void; + sign(data: DataBlob | null, callback: AsyncCallback): void; + sign(data: DataBlob): Promise; + sign(data: DataBlob | null): Promise; + signSync(data: DataBlob | null): DataBlob; + setSignSpec(itemType: SignSpecItem, itemValue: number): void; + setSignSpec(itemType: SignSpecItem, itemValue: number | Uint8Array): void; + getSignSpec(itemType: SignSpecItem): string | number; + readonly algName: string; + } + + interface Verify { + init(pubKey: PubKey, callback: AsyncCallback): void; + init(pubKey: PubKey): Promise; + initSync(pubKey: PubKey): void; + update(data: DataBlob, callback: AsyncCallback): void; + update(data: DataBlob): Promise; + updateSync(data: DataBlob): void; + verify(data: DataBlob, signatureData: DataBlob, callback: AsyncCallback): void; + verify(data: DataBlob | null, signatureData: DataBlob, callback: AsyncCallback): void; + verify(data: DataBlob, signatureData: DataBlob): Promise; + verify(data: DataBlob | null, signatureData: DataBlob): Promise; + verifySync(data: DataBlob | null, signatureData: DataBlob): boolean; + recover(signatureData: DataBlob): Promise; + recoverSync(signatureData: DataBlob): DataBlob | null; + setVerifySpec(itemType: SignSpecItem, itemValue: number): void; + setVerifySpec(itemType: SignSpecItem, itemValue: number | Uint8Array): void; + getVerifySpec(itemType: SignSpecItem): string | number; + readonly algName: string; + } + function createSign(algName: string): Sign; + function createVerify(algName: string): Verify; + + interface KeyAgreement { + generateSecret(priKey: PriKey, pubKey: PubKey, callback: AsyncCallback): void; + generateSecret(priKey: PriKey, pubKey: PubKey): Promise; + generateSecretSync(priKey: PriKey, pubKey: PubKey): DataBlob; + readonly algName: string; + } + function createKeyAgreement(algName: string): KeyAgreement; + + enum AsyKeySpecItem { + DSA_P_BN = 101, + DSA_Q_BN = 102, + DSA_G_BN = 103, + DSA_SK_BN = 104, + DSA_PK_BN = 105, + ECC_FP_P_BN = 201, + ECC_A_BN = 202, + ECC_B_BN = 203, + ECC_G_X_BN = 204, + ECC_G_Y_BN = 205, + ECC_N_BN = 206, + ECC_H_NUM = 207, + ECC_SK_BN = 208, + ECC_PK_X_BN = 209, + ECC_PK_Y_BN = 210, + ECC_FIELD_TYPE_STR = 211, + ECC_FIELD_SIZE_NUM = 212, + ECC_CURVE_NAME_STR = 213, + RSA_N_BN = 301, + RSA_SK_BN = 302, + RSA_PK_BN = 303, + DH_P_BN = 401, + DH_G_BN = 402, + DH_L_NUM = 403, + DH_SK_BN = 404, + DH_PK_BN = 405, + ED25519_SK_BN = 501, + ED25519_PK_BN = 502, + X25519_SK_BN = 601, + X25519_PK_BN = 602 + } + + enum AsyKeySpecType { + COMMON_PARAMS_SPEC = 0, + PRIVATE_KEY_SPEC = 1, + PUBLIC_KEY_SPEC = 2, + KEY_PAIR_SPEC = 3 + } + + interface AsyKeySpec { + algName: string; + specType: AsyKeySpecType; + } + + interface DSACommonParamsSpec extends AsyKeySpec { + p: bigint; + q: bigint; + g: bigint; + } + + interface DSAPubKeySpec extends AsyKeySpec { + params: DSACommonParamsSpec; + pk: bigint; + } + + interface DSAKeyPairSpec extends AsyKeySpec { + params: DSACommonParamsSpec; + sk: bigint; + pk: bigint; + } + + interface ECField { + fieldType: string; + } + + interface ECFieldFp extends ECField { + p: bigint; + } + + interface Point { + x: bigint; + y: bigint; + } + + interface ECCCommonParamsSpec extends AsyKeySpec { + field: ECField; + a: bigint; + b: bigint; + g: Point; + n: bigint; + h: number; + } + + interface ECCPriKeySpec extends AsyKeySpec { + params: ECCCommonParamsSpec; + sk: bigint; + } + + interface ECCPubKeySpec extends AsyKeySpec { + params: ECCCommonParamsSpec; + pk: Point; + } + + interface ECCKeyPairSpec extends AsyKeySpec { + params: ECCCommonParamsSpec; + sk: bigint; + pk: Point; + } + + class ECCKeyUtil { + static genECCCommonParamsSpec(curveName: string): ECCCommonParamsSpec; + static convertPoint(curveName: string, encodedPoint: Uint8Array): Point; + static getEncodedPoint(curveName: string, point: Point, format: string): Uint8Array; + } + + interface DHCommonParamsSpec extends AsyKeySpec { + p: bigint; + g: bigint; + l: number; + } + + interface DHPriKeySpec extends AsyKeySpec { + params: DHCommonParamsSpec; + sk: bigint; + } + + interface DHPubKeySpec extends AsyKeySpec { + params: DHCommonParamsSpec; + pk: bigint; + } + + interface DHKeyPairSpec extends AsyKeySpec { + params: DHCommonParamsSpec; + sk: bigint; + pk: bigint; + } + + class DHKeyUtil { + static genDHCommonParamsSpec(pLen: number, skLen?: number): DHCommonParamsSpec; + } + + interface ED25519PriKeySpec extends AsyKeySpec { + sk: bigint; + } + + interface ED25519PubKeySpec extends AsyKeySpec { + pk: bigint; + } + + interface ED25519KeyPairSpec extends AsyKeySpec { + sk: bigint; + pk: bigint; + } + + interface X25519PriKeySpec extends AsyKeySpec { + sk: bigint; + } + + interface X25519PubKeySpec extends AsyKeySpec { + pk: bigint; + } + + interface X25519KeyPairSpec extends AsyKeySpec { + sk: bigint; + pk: bigint; + } + + interface RSACommonParamsSpec extends AsyKeySpec { + n: bigint; + } + + interface RSAPubKeySpec extends AsyKeySpec { + params: RSACommonParamsSpec; + pk: bigint; + } + + interface RSAKeyPairSpec extends AsyKeySpec { + params: RSACommonParamsSpec; + sk: bigint; + pk: bigint; + } + + interface AsyKeyGeneratorBySpec { + generateKeyPair(callback: AsyncCallback): void; + generateKeyPair(): Promise; + generateKeyPairSync(): KeyPair; + generatePriKey(callback: AsyncCallback): void; + generatePriKey(): Promise; + generatePriKeySync(): PriKey; + generatePubKey(callback: AsyncCallback): void; + generatePubKey(): Promise; + generatePubKeySync(): PubKey; + readonly algName: string; + } + function createAsyKeyGeneratorBySpec(asyKeySpec: AsyKeySpec): AsyKeyGeneratorBySpec; + + interface KdfSpec { + algName: string; + } + + interface PBKDF2Spec extends KdfSpec { + password: string | Uint8Array; + salt: Uint8Array; + iterations: number; + keySize: number; + } + + interface HKDFSpec extends KdfSpec { + key: string | Uint8Array; + salt: Uint8Array; + info: Uint8Array; + keySize: number; + } + + interface ScryptSpec extends KdfSpec { + passphrase: string | Uint8Array; + salt: Uint8Array; + n: number; + r: number; + p: number; + maxMemory: number; + keySize: number; + } + + interface Kdf { + generateSecret(params: KdfSpec, callback: AsyncCallback): void; + generateSecret(params: KdfSpec): Promise; + generateSecretSync(params: KdfSpec): DataBlob; + readonly algName: string; + } + function createKdf(algName: string): Kdf; + + interface SM2CipherTextSpec { + xCoordinate: bigint; + yCoordinate: bigint; + cipherTextData: Uint8Array; + hashData: Uint8Array; + } + + class SM2CryptoUtil { + static genCipherTextBySpec(spec: SM2CipherTextSpec, mode?: string): DataBlob; + static getCipherTextSpec(cipherText: DataBlob, mode?: string): SM2CipherTextSpec; + } +} + +export default cryptoFramework; diff --git a/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe b/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe new file mode 100644 index 0000000..42b5987 --- /dev/null +++ b/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@!namespace("@ohos.security.cryptoFramework", "cryptoFramework") +@!typed_array + +@!sts_inject(""" +static { loadLibrary("crypto_framework_ani.z"); } +""") + +struct DataBlob { + data: Array; +} + +interface Md { + @gen_async("update") + @gen_promise("update") + UpdateSync(input: DataBlob): void; + @gen_async("digest") + @gen_promise("digest") + DigestSync(): DataBlob; + GetMdLength(): i32; + @get GetAlgName(): String; +} +function CreateMd(algName: String): Md; + +interface Random { + @gen_async("generateRandom") + @gen_promise("generateRandom") + GenerateRandomSync(len: i32): DataBlob; + SetSeed(seed: DataBlob): void; + @get GetAlgName(): String; +} +function CreateRandom(): Random; + +interface Mac { + @gen_async("init") + @gen_promise("init") + InitSync(key: SymKey): void; + @gen_async("update") + @gen_promise("update") + UpdateSync(input: DataBlob): void; + @gen_async("doFinal") + @gen_promise("doFinal") + DoFinalSync(): DataBlob; + GetMacLength(): i32; + @get GetAlgName(): String; +} +function CreateMac(algName: String): Mac; + +interface Key { + GetEncoded(): DataBlob; + @get GetFormat(): String; + @get GetAlgName(): String; +} + +interface SymKey: Key { + ClearMem(): void; + GetSymKeyObj(): i64; +} + +interface SymKeyGenerator { + @gen_async("generateSymKey") + @gen_promise("generateSymKey") + GenerateSymKeySync(): SymKey; + @gen_async("convertKey") + @gen_promise("convertKey") + ConvertKeySync(key: DataBlob): SymKey; + @get GetAlgName(): String; +} +function CreateSymKeyGenerator(algName: String): SymKeyGenerator; diff --git a/frameworks/js/ani/inc/ani_common.h b/frameworks/js/ani/inc/ani_common.h new file mode 100644 index 0000000..ce4e8ba --- /dev/null +++ b/frameworks/js/ani/inc/ani_common.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_COMMON_H +#define ANI_COMMON_H + +#include "stdexcept" +#include "taihe/runtime.hpp" +#include "ohos.security.cryptoFramework.cryptoFramework.proj.hpp" +#include "ohos.security.cryptoFramework.cryptoFramework.impl.hpp" + +#include "log.h" +#include "blob.h" +#include "result.h" +#include "object_base.h" + +#define ANI_LOGE_THROW(code, msg) \ + do { \ + taihe::set_business_error(code, msg); \ + LOGE(msg); \ + } while (0) + +#endif // ANI_COMMON_H diff --git a/frameworks/js/ani/inc/ani_key.h b/frameworks/js/ani/inc/ani_key.h new file mode 100644 index 0000000..1cf1f40 --- /dev/null +++ b/frameworks/js/ani/inc/ani_key.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_KEY_H +#define ANI_KEY_H + +#include "ani_common.h" +#include "key.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class KeyImpl { +public: + KeyImpl(); + ~KeyImpl(); + + DataBlob GetEncoded(); + string GetFormat(); + string GetAlgName(); +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_KEY_H diff --git a/frameworks/js/ani/inc/ani_mac.h b/frameworks/js/ani/inc/ani_mac.h new file mode 100644 index 0000000..0416ef2 --- /dev/null +++ b/frameworks/js/ani/inc/ani_mac.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_MAC_H +#define ANI_MAC_H + +#include "ani_common.h" +#include "mac.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class MacImpl { +public: + MacImpl(); + explicit MacImpl(HcfMac *obj); + ~MacImpl(); + + void InitSync(weak::SymKey key); + void UpdateSync(DataBlob const& input); + DataBlob DoFinalSync(); + int32_t GetMacLength(); + string GetAlgName(); + +private: + HcfMac *macObj = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_MAC_H diff --git a/frameworks/js/ani/inc/ani_md.h b/frameworks/js/ani/inc/ani_md.h new file mode 100644 index 0000000..35cbe7c --- /dev/null +++ b/frameworks/js/ani/inc/ani_md.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_MD_H +#define ANI_MD_H + +#include "ani_common.h" +#include "md.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class MdImpl { +public: + MdImpl(); + explicit MdImpl(HcfMd *obj); + ~MdImpl(); + + void UpdateSync(DataBlob const& input); + DataBlob DigestSync(); + int32_t GetMdLength(); + string GetAlgName(); + +private: + HcfMd *mdObj = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_MD_H diff --git a/frameworks/js/ani/inc/ani_rand.h b/frameworks/js/ani/inc/ani_rand.h new file mode 100644 index 0000000..f027dcd --- /dev/null +++ b/frameworks/js/ani/inc/ani_rand.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_RAND_H +#define ANI_RAND_H + +#include "ani_common.h" +#include "rand.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class RandomImpl { +public: + RandomImpl(); + explicit RandomImpl(HcfRand *obj); + ~RandomImpl(); + + DataBlob GenerateRandomSync(int32_t len); + void SetSeed(DataBlob const& seed); + string GetAlgName(); + +private: + HcfRand *randObj = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_RAND_H diff --git a/frameworks/js/ani/inc/ani_sym_key.h b/frameworks/js/ani/inc/ani_sym_key.h new file mode 100644 index 0000000..af42597 --- /dev/null +++ b/frameworks/js/ani/inc/ani_sym_key.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_SYM_KEY_H +#define ANI_SYM_KEY_H + +#include "ani_common.h" +#include "sym_key.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class SymKeyImpl { +public: + SymKeyImpl(); + explicit SymKeyImpl(HcfSymKey *obj); + ~SymKeyImpl(); + + void ClearMem(); + int64_t GetSymKeyObj(); + DataBlob GetEncoded(); + string GetFormat(); + string GetAlgName(); + +private: + HcfSymKey *symKey = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_SYM_KEY_H diff --git a/frameworks/js/ani/inc/ani_sym_key_generator.h b/frameworks/js/ani/inc/ani_sym_key_generator.h new file mode 100644 index 0000000..4ad8250 --- /dev/null +++ b/frameworks/js/ani/inc/ani_sym_key_generator.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_SYM_KEY_GENERATOR_H +#define ANI_SYM_KEY_GENERATOR_H + +#include "ani_common.h" +#include "sym_key_generator.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class SymKeyGeneratorImpl { +public: + SymKeyGeneratorImpl(); + explicit SymKeyGeneratorImpl(HcfSymKeyGenerator *obj); + ~SymKeyGeneratorImpl(); + + SymKey GenerateSymKeySync(); + SymKey ConvertKeySync(DataBlob const& key); + string GetAlgName(); + +private: + HcfSymKeyGenerator *generator = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_SYM_KEY_GENERATOR_H diff --git a/frameworks/js/ani/src/ani_constructor.cpp b/frameworks/js/ani/src/ani_constructor.cpp new file mode 100644 index 0000000..9d38ae4 --- /dev/null +++ b/frameworks/js/ani/src/ani_constructor.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos.security.cryptoFramework.cryptoFramework.ani.hpp" + +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::security::cryptoFramework::cryptoFramework::ANIRegister(env)) { + std::cerr << "ohos::security::cryptoFramework::cryptoFramework" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} diff --git a/frameworks/js/ani/src/ani_key.cpp b/frameworks/js/ani/src/ani_key.cpp new file mode 100644 index 0000000..d297915 --- /dev/null +++ b/frameworks/js/ani/src/ani_key.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_key.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +KeyImpl::KeyImpl() {} + +KeyImpl::~KeyImpl() {} + +DataBlob KeyImpl::GetEncoded() +{ + TH_THROW(std::runtime_error, "GetEncoded not implemented"); +} + +string KeyImpl::GetFormat() +{ + TH_THROW(std::runtime_error, "GetFormat not implemented"); +} + +string KeyImpl::GetAlgName() +{ + TH_THROW(std::runtime_error, "GetAlgName not implemented"); +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_mac.cpp b/frameworks/js/ani/src/ani_mac.cpp new file mode 100644 index 0000000..bb05103 --- /dev/null +++ b/frameworks/js/ani/src/ani_mac.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_mac.h" +#include "detailed_hmac_params.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +MacImpl::MacImpl() : macObj(nullptr) {} + +MacImpl::MacImpl(HcfMac *obj) : macObj(obj) {} + +MacImpl::~MacImpl() +{ + HcfObjDestroy(macObj); +} + +void MacImpl::InitSync(weak::SymKey key) +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return; + } + HcfSymKey *symKey = reinterpret_cast(key->GetSymKeyObj()); + HcfResult res = macObj->init(macObj, symKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac init failed!"); + return; + } +} + +void MacImpl::UpdateSync(DataBlob const& input) +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return; + } + HcfBlob inBlob = { .data = input.data.data(), .len = input.data.size() }; + HcfResult res = macObj->update(macObj, &inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac update failed!"); + return; + } +} + +DataBlob MacImpl::DoFinalSync() +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return { taihe::array(nullptr, 0) }; + } + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + HcfResult res = macObj->doFinal(macObj, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac doFinal failed!"); + return { taihe::array(nullptr, 0) }; + } + taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +int32_t MacImpl::GetMacLength() +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return 0; + } + uint32_t length = macObj->getMacLength(macObj); + return static_cast(length); +} + +string MacImpl::GetAlgName() +{ + if (macObj == nullptr) { + return ""; + } + const char *algName = macObj->getAlgoName(macObj); + return (algName == nullptr) ? "" : string(algName); +} + +Mac CreateMac(string_view algName) +{ + HcfMac *macObj = nullptr; + HcfHmacParamsSpec parmas = { .base.algName = "HMAC", .mdName = algName.c_str() }; + HcfResult res = HcfMacCreate(reinterpret_cast(&parmas), &macObj); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C mac obj failed."); + return make_holder(nullptr); + } + return make_holder(macObj); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateMac(CreateMac); diff --git a/frameworks/js/ani/src/ani_md.cpp b/frameworks/js/ani/src/ani_md.cpp new file mode 100644 index 0000000..c264161 --- /dev/null +++ b/frameworks/js/ani/src/ani_md.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_md.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +MdImpl::MdImpl() : mdObj(nullptr) {} + +MdImpl::MdImpl(HcfMd *obj) : mdObj(obj) {} + +MdImpl::~MdImpl() {} + +void MdImpl::UpdateSync(DataBlob const& input) +{ + if (mdObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); + return; + } + HcfBlob inBlob = { .data = input.data.data(), .len = input.data.size() }; + HcfResult res = mdObj->update(mdObj, &inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "md doFinal failed!"); + return; + } +} + +DataBlob MdImpl::DigestSync() +{ + if (mdObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); + return { taihe::array(nullptr, 0) }; + } + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + HcfResult res = mdObj->doFinal(mdObj, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac doFinal failed!"); + return { taihe::array(nullptr, 0) }; + } + taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +int32_t MdImpl::GetMdLength() +{ + if (mdObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); + return 0; + } + uint32_t length = mdObj->getMdLength(mdObj); + return static_cast(length); +} + +string MdImpl::GetAlgName() +{ + if (mdObj == nullptr) { + return ""; + } + const char *algName = mdObj->getAlgoName(mdObj); + return (algName == nullptr) ? "" : string(algName); +} + +Md CreateMd(string_view algName) +{ + HcfMd *mdObj = nullptr; + HcfResult res = HcfMdCreate(algName.c_str(), &mdObj); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C md obj failed."); + return make_holder(nullptr); + } + return make_holder(mdObj); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateMd(CreateMd); diff --git a/frameworks/js/ani/src/ani_rand.cpp b/frameworks/js/ani/src/ani_rand.cpp new file mode 100644 index 0000000..0022017 --- /dev/null +++ b/frameworks/js/ani/src/ani_rand.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_rand.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +RandomImpl::RandomImpl() : randObj(nullptr) {} + +RandomImpl::RandomImpl(HcfRand *obj) : randObj(obj) {} + +RandomImpl::~RandomImpl() +{ + HcfObjDestroy(randObj); +} + +DataBlob RandomImpl::GenerateRandomSync(int32_t len) +{ + if (randObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "rand obj is nullptr!"); + return { taihe::array(nullptr, 0) }; + } + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + HcfResult res = randObj->generateRandom(randObj, len, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "generateRandom failed!"); + return { taihe::array(nullptr, 0) }; + } + taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +void RandomImpl::SetSeed(DataBlob const& seed) +{ + if (randObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "rand obj is nullptr!"); + return; + } + HcfBlob seedBlob = { .data = seed.data.data(), .len = seed.data.size() }; + HcfResult res = randObj->setSeed(randObj, &seedBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "set seed failed."); + return; + } +} + +string RandomImpl::GetAlgName() +{ + if (randObj == nullptr) { + return ""; + } + const char *algName = randObj->getAlgoName(randObj); + return (algName == nullptr) ? "" : string(algName); +} + +Random CreateRandom() +{ + HcfRand *randObj = nullptr; + HcfResult res = HcfRandCreate(&randObj); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C rand obj failed."); + return make_holder(nullptr); + } + return make_holder(randObj); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateRandom(CreateRandom); diff --git a/frameworks/js/ani/ets/@ohos.security.cryptoFramework.ets b/frameworks/js/ani/src/ani_sym_key.cpp similarity index 35% rename from frameworks/js/ani/ets/@ohos.security.cryptoFramework.ets rename to frameworks/js/ani/src/ani_sym_key.cpp index 81592ed..cb08945 100644 --- a/frameworks/js/ani/ets/@ohos.security.cryptoFramework.ets +++ b/frameworks/js/ani/src/ani_sym_key.cpp @@ -13,61 +13,44 @@ * limitations under the License. */ -namespace cryptoFramework { - loadLibrary("crypto_framework_ani.z"); - native function createSymKeyGenerator(algName: string): SymKeyGenerator; - native function createMac(algName: string): Mac; +#include "ani_sym_key.h" - interface DataBlob { - data: Uint8Array; - } +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; - interface SymKey { - } +namespace ANI::CryptoFramework { +SymKeyImpl::SymKeyImpl() : symKey(nullptr) {} - interface SymKeyGenerator { - convertKeySync(key: DataBlob): SymKey; - } +SymKeyImpl::SymKeyImpl(HcfSymKey *obj) : symKey(obj) {} - interface Mac { - initSync(key: SymKey): void; - updateSync(input: DataBlob): void; - doFinalSync(): DataBlob; - } - - class DataBlobInner implements DataBlob { - data: Uint8Array; - constructor(obj: Uint8Array) { - this.data = obj; - } - } - - class SymKeyInner implements SymKey { - private symKey: long; - constructor(obj: long) { - this.symKey = obj; - } - } +SymKeyImpl::~SymKeyImpl() +{ + HcfObjDestroy(symKey); +} - class SymKeyGeneratorInner implements SymKeyGenerator { - native convertKeySync(data: DataBlob): SymKey; +void SymKeyImpl::ClearMem() +{ + TH_THROW(std::runtime_error, "ClearMem not implemented"); +} - private generator: long; - constructor(obj: long) { - this.generator = obj; - } - } +int64_t SymKeyImpl::GetSymKeyObj() +{ + return reinterpret_cast(symKey); +} - class MacInner implements Mac { - native initSync(key: SymKey): void; - native updateSync(input: DataBlob): void; - native doFinalSync(): DataBlob; +DataBlob SymKeyImpl::GetEncoded() +{ + TH_THROW(std::runtime_error, "GetEncoded not implemented"); +} - private macObj: long; - constructor(obj: long) { - this.macObj = obj; - } - } +string SymKeyImpl::GetFormat() +{ + TH_THROW(std::runtime_error, "GetFormat not implemented"); } -export default cryptoFramework; +string SymKeyImpl::GetAlgName() +{ + TH_THROW(std::runtime_error, "GetAlgName not implemented"); +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_sym_key_generator.cpp b/frameworks/js/ani/src/ani_sym_key_generator.cpp new file mode 100644 index 0000000..5b45115 --- /dev/null +++ b/frameworks/js/ani/src/ani_sym_key_generator.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_sym_key_generator.h" +#include "ani_sym_key.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +SymKeyGeneratorImpl::SymKeyGeneratorImpl() : generator(nullptr) {} + +SymKeyGeneratorImpl::SymKeyGeneratorImpl(HcfSymKeyGenerator *obj) : generator(obj) {} + +SymKeyGeneratorImpl::~SymKeyGeneratorImpl() +{ + HcfObjDestroy(generator); +} + +SymKey SymKeyGeneratorImpl::GenerateSymKeySync() +{ + return make_holder(nullptr); +} + +SymKey SymKeyGeneratorImpl::ConvertKeySync(DataBlob const& key) +{ + if (generator == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); + return make_holder(nullptr); + } + HcfSymKey *symKey = nullptr; + HcfBlob keyData = { .data = key.data.data(), .len = key.data.size() }; + HcfResult res = generator->convertSymKey(generator, &keyData, &symKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "convertSymKey key failed!"); + return make_holder(nullptr); + } + return make_holder(symKey); +} + +string SymKeyGeneratorImpl::GetAlgName() +{ + if (generator == nullptr) { + return ""; + } + const char *algName = generator->getAlgoName(generator); + return (algName == nullptr) ? "" : string(algName); +} + +SymKeyGenerator CreateSymKeyGenerator(string_view algName) +{ + HcfSymKeyGenerator *generator = nullptr; + HcfResult res = HcfSymKeyGeneratorCreate(algName.c_str(), &generator); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C generator obj fail."); + return make_holder(nullptr); + } + return make_holder(generator); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateSymKeyGenerator(CreateSymKeyGenerator); diff --git a/frameworks/js/ani/src/cryptoframework_ani.cpp b/frameworks/js/ani/src/cryptoframework_ani.cpp deleted file mode 100644 index 59cc6a9..0000000 --- a/frameworks/js/ani/src/cryptoframework_ani.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2025-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#include -#include "log.h" -#include "mac.h" -#include "sym_key_generator.h" - -namespace { -const std::string CRYPTO_FRAMEWORK_CLASS_NAME = "L@ohos/security/cryptoFramework/cryptoFramework;"; -const std::string GENERATOR_CLASS_NAME = "L@ohos/security/cryptoFramework/cryptoFramework/SymKeyGeneratorInner;"; -const std::string SYM_KEY_CLASS_NAME = "L@ohos/security/cryptoFramework/cryptoFramework/SymKeyInner;"; -const std::string MAC_CLASS_NAME = "L@ohos/security/cryptoFramework/cryptoFramework/MacInner;"; -const std::string DATA_BLOB_CLASS_NAME = "L@ohos/security/cryptoFramework/cryptoFramework/DataBlobInner;"; - -std::string GetStdString(ani_env *env, ani_string str) -{ - ani_size strSize; - if (env->String_GetUTF8Size(str, &strSize)) { - LOGE("get utf8 size failed"); - return ""; - } - - std::vector buffer(strSize + 1); - char *utf8Buffer = buffer.data(); - ani_size length = 0; - if (env->String_GetUTF8(str, utf8Buffer, strSize + 1, &length) != ANI_OK) { - LOGE("get utf8 string failed"); - return ""; - } - - utf8Buffer[length] = '\0'; - std::string content = std::string(utf8Buffer); - return content; -} - -bool GetUint8Array(ani_env *env, ani_object object, HcfBlob &blob) -{ - ani_ref buffer; - if (env->Object_GetFieldByName_Ref(object, "buffer", &buffer) != ANI_OK) { - LOGE("get buffer ref failed"); - return false; - } - - uint8_t *data = nullptr; - size_t length = 0; - if (env->ArrayBuffer_GetInfo(reinterpret_cast(buffer), - reinterpret_cast(&data), &length) != ANI_OK) { - LOGE("get arraybuffer info failed"); - return false; - } - - blob.data = data; - blob.len = length; - return true; -} - -template -ani_object CreateAniObject(ani_env *env, std::string name, const char *signature, Args... args) -{ - ani_class cls; - if (env->FindClass(name.c_str(), &cls) != ANI_OK) { - LOGE("not found '%s'", name.c_str()); - return {}; - } - - ani_method ctor; - if (env->Class_FindMethod(cls, "", signature, &ctor) != ANI_OK) { - LOGE("get ctor failed '%s'", name.c_str()); - return {}; - } - - ani_object obj = {}; - if (env->Object_New(cls, ctor, &obj, args...) != ANI_OK) { - LOGE("create object failed '%s'", name.c_str()); - return obj; - } - - LOGI("create object success '%s'", name.c_str()); - return obj; -} - -ani_long GetLongValue(ani_env *env, ani_object object, std::string name) -{ - ani_long value; - if (env->Object_GetFieldByName_Long(object, name.c_str(), &value) != ANI_OK) { - LOGE("get generator object failed '%s'", name.c_str()); - return 0; - } - return value; -} -} // namespace - -static ani_object CreateSymKeyGenerator([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, - ani_string str) -{ - HcfSymKeyGenerator *generator = nullptr; - std::string algo = GetStdString(env, str); - HcfResult ret = HcfSymKeyGeneratorCreate(algo.c_str(), &generator); - if (ret != HCF_SUCCESS) { - LOGE("create symkey generator failed"); - return {}; - } - - return CreateAniObject(env, GENERATOR_CLASS_NAME, nullptr, reinterpret_cast(generator)); -} - -static ani_object ConvertKeySync([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_object data) -{ - ani_ref dataRef; - if (env->Object_CallMethodByName_Ref(data, "data", nullptr, &dataRef) != ANI_OK) { - LOGE("get datablob failed"); - return {}; - } - - HcfBlob keyData = {}; - if (!GetUint8Array(env, reinterpret_cast(dataRef), keyData)) { - LOGE("get key data failed"); - return {}; - } - - HcfSymKey *symKey = nullptr; - ani_long context = GetLongValue(env, object, "generator"); - HcfSymKeyGenerator *generator = reinterpret_cast(context); - HcfResult ret = generator->convertSymKey(generator, &keyData, &symKey); - if (ret != HCF_SUCCESS) { - LOGE("convert symkey failed"); - return {}; - } - - return CreateAniObject(env, SYM_KEY_CLASS_NAME, nullptr, reinterpret_cast(symKey)); -} - -static ani_object CreateMac([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_string str) -{ - HcfMac *macObj = nullptr; - std::string algo = GetStdString(env, str); - HcfMacParamsSpec params = { algo.c_str() }; - HcfResult ret = HcfMacCreate(¶ms, &macObj); - if (ret != HCF_SUCCESS) { - LOGE("create mac object failed"); - return {}; - } - - return CreateAniObject(env, MAC_CLASS_NAME, nullptr, reinterpret_cast(macObj)); -} - -static void InitSync([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_object key) -{ - ani_long context = GetLongValue(env, object, "macObj"); - HcfMac *macObj = reinterpret_cast(context); - context = GetLongValue(env, key, "symKey"); - HcfSymKey *symKey = reinterpret_cast(context); - HcfResult ret = macObj->init(macObj, symKey); - if (ret != HCF_SUCCESS) { - LOGE("init failed"); - return; - } - LOGI("init success"); -} - -static void UpdateSync([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_object input) -{ - ani_ref inputRef; - if (env->Object_CallMethodByName_Ref(input, "data", nullptr, &inputRef) != ANI_OK) { - LOGE("get datablob failed"); - return; - } - - HcfBlob inBlob = {}; - if (!GetUint8Array(env, reinterpret_cast(inputRef), inBlob)) { - LOGE("get input data failed"); - return; - } - - ani_long context = GetLongValue(env, object, "macObj"); - HcfMac *macObj = reinterpret_cast(context); - HcfResult ret = macObj->update(macObj, &inBlob); - if (ret != HCF_SUCCESS) { - LOGE("update failed"); - return; - } - LOGI("update success"); -} - -static ani_object DoFinalSync([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object) -{ - ani_long context = GetLongValue(env, object, "macObj"); - HcfMac *macObj = reinterpret_cast(context); - HcfBlob resBlob = { .data = nullptr, .len = 0 }; - HcfResult ret = macObj->doFinal(macObj, &resBlob); - std::vector result(resBlob.data, resBlob.data + resBlob.len); - HcfBlobDataClearAndFree(&resBlob); - if (ret != HCF_SUCCESS) { - LOGE("dofinal failed"); - return {}; - } - LOGI("dofinal success"); - - ani_object out = CreateAniObject(env, "Lescompat/Uint8Array;", "I:V", result.size()); - HcfBlob outBlob = {}; - if (!GetUint8Array(env, out, outBlob)) { - LOGE("get output data failed"); - return {}; - } - - if (memcpy_s(outBlob.data, outBlob.len, result.data(), result.size()) != EOK) { - LOGE("memcpy_s failed"); - return {}; - } - - return CreateAniObject(env, DATA_BLOB_CLASS_NAME, nullptr, out); -} - -static std::unordered_map> entrys = { - { - CRYPTO_FRAMEWORK_CLASS_NAME, - { - ani_native_function {"createSymKeyGenerator", nullptr, reinterpret_cast(CreateSymKeyGenerator)}, - ani_native_function {"createMac", nullptr, reinterpret_cast(CreateMac)}, - } - }, - { - GENERATOR_CLASS_NAME, - { - ani_native_function {"convertKeySync", nullptr, reinterpret_cast(ConvertKeySync)}, - } - }, - { - MAC_CLASS_NAME, - { - ani_native_function {"initSync", nullptr, reinterpret_cast(InitSync)}, - ani_native_function {"updateSync", nullptr, reinterpret_cast(UpdateSync)}, - ani_native_function {"doFinalSync", nullptr, reinterpret_cast(DoFinalSync)}, - } - }, -}; - -ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) -{ - ani_env *env; - if (vm->GetEnv(ANI_VERSION_1, &env) != ANI_OK) { - LOGE("unsupported ANI_VERSION_1"); - return ANI_ERROR; - } - - for (const auto &entry : entrys) { - const char *className = entry.first.c_str(); - std::vector methods = entry.second; - ani_class cls; - if (env->FindClass(className, &cls) != ANI_OK) { - LOGE("not found '%s'", className); - return ANI_ERROR; - } - if (env->Class_BindNativeMethods(cls, methods.data(), methods.size()) != ANI_OK) { - LOGE("cannot bind native methods to '%s'", className); - return ANI_ERROR; - }; - } - - *result = ANI_VERSION_1; - return ANI_OK; -} - -ANI_EXPORT ani_status ANI_Destructor(ani_vm *vm) -{ - return ANI_OK; -} diff --git a/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp b/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp new file mode 100644 index 0000000..5327a10 --- /dev/null +++ b/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos.security.cryptoFramework.cryptoFramework.proj.hpp" +#include "ohos.security.cryptoFramework.cryptoFramework.impl.hpp" +#include "taihe/runtime.hpp" +#include "stdexcept" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +namespace { +// To be implemented. + +class MdImpl { +public: + MdImpl() { + // Don't forget to implement the constructor. + } + + void UpdateSync(DataBlob const& input) { + TH_THROW(std::runtime_error, "UpdateSync not implemented"); + } + + DataBlob DigestSync() { + TH_THROW(std::runtime_error, "DigestSync not implemented"); + } + + int32_t GetMdLength() { + TH_THROW(std::runtime_error, "GetMdLength not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class RandomImpl { +public: + RandomImpl() { + // Don't forget to implement the constructor. + } + + DataBlob GenerateRandomSync(int32_t len) { + TH_THROW(std::runtime_error, "GenerateRandomSync not implemented"); + } + + void SetSeed(DataBlob const& seed) { + TH_THROW(std::runtime_error, "SetSeed not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class MacImpl { +public: + MacImpl() { + // Don't forget to implement the constructor. + } + + void InitSync(weak::SymKey key) { + TH_THROW(std::runtime_error, "InitSync not implemented"); + } + + void UpdateSync(DataBlob const& input) { + TH_THROW(std::runtime_error, "UpdateSync not implemented"); + } + + DataBlob DoFinalSync() { + TH_THROW(std::runtime_error, "DoFinalSync not implemented"); + } + + int32_t GetMacLength() { + TH_THROW(std::runtime_error, "GetMacLength not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class KeyImpl { +public: + KeyImpl() { + // Don't forget to implement the constructor. + } + + DataBlob GetEncoded() { + TH_THROW(std::runtime_error, "GetEncoded not implemented"); + } + + string GetFormat() { + TH_THROW(std::runtime_error, "GetFormat not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class SymKeyImpl { +public: + SymKeyImpl() { + // Don't forget to implement the constructor. + } + + void ClearMem() { + TH_THROW(std::runtime_error, "ClearMem not implemented"); + } + + int64_t GetSymKeyObj() { + TH_THROW(std::runtime_error, "GetSymKeyObj not implemented"); + } + + DataBlob GetEncoded() { + TH_THROW(std::runtime_error, "GetEncoded not implemented"); + } + + string GetFormat() { + TH_THROW(std::runtime_error, "GetFormat not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class SymKeyGeneratorImpl { +public: + SymKeyGeneratorImpl() { + // Don't forget to implement the constructor. + } + + SymKey GenerateSymKeySync() { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); + } + + SymKey ConvertKeySync(DataBlob const& key) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +Md CreateMd(string_view algName) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +Random CreateRandom() { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +Mac CreateMac(string_view algName) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +SymKeyGenerator CreateSymKeyGenerator(string_view algName) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} +} // namespace + +TH_EXPORT_CPP_API_CreateMd(CreateMd); +TH_EXPORT_CPP_API_CreateRandom(CreateRandom); +TH_EXPORT_CPP_API_CreateMac(CreateMac); +TH_EXPORT_CPP_API_CreateSymKeyGenerator(CreateSymKeyGenerator); diff --git a/frameworks/js/ani/test/arktsconfig.json b/frameworks/js/ani/test/arktsconfig.json index 22b1840..6973403 100644 --- a/frameworks/js/ani/test/arktsconfig.json +++ b/frameworks/js/ani/test/arktsconfig.json @@ -15,7 +15,7 @@ ] } }, - "files": [ - "./test.ets" + "includes": [ + "*.ets" ] } diff --git a/frameworks/js/ani/test/test_mac.ets b/frameworks/js/ani/test/test_mac.ets new file mode 100644 index 0000000..69f74d5 --- /dev/null +++ b/frameworks/js/ani/test/test_mac.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +export function testMac() { + try { + let key = "1234567890"; + let keyBytes = utils.hexStrToUint8Array(key); + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + let symKey = cryptoFramework.createSymKeyGenerator("HMAC").convertKeySync({ + data: keyBytes + }); + let mac = cryptoFramework.createMac("SHA256"); + mac.initSync(symKey); + mac.updateSync({ + data: dataBytes + }); + let output = mac.doFinalSync(); + let str = utils.uint8ArrayToHexStr(output.data); + console.log("HMAC algName: " + mac.algName); + console.log("HMAC-SHA256: " + str); + } + catch (err) { + console.error("HMAC-SHA256: " + err) + } +} diff --git a/frameworks/js/ani/test/test_main.ets b/frameworks/js/ani/test/test_main.ets new file mode 100644 index 0000000..616b5c3 --- /dev/null +++ b/frameworks/js/ani/test/test_main.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { testMd } from "./test_md"; +import { testRandom } from "./test_rand"; +import { testMac } from "./test_mac"; + +function main() { + testMac(); + testMd(); + testRandom(); +} diff --git a/frameworks/js/ani/test/test_md.ets b/frameworks/js/ani/test/test_md.ets new file mode 100644 index 0000000..e2f7949 --- /dev/null +++ b/frameworks/js/ani/test/test_md.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +export function testMd() { + try { + let md = cryptoFramework.createMd("MD5"); + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + md.updateSync({ + data: dataBytes + }); + let output = md.digestSync(); + let str = utils.uint8ArrayToHexStr(output.data); + console.log("MD5: " + str); + let length = md.getMdLength(); + console.log("MD5 length: " + length); + } catch (err) { + console.log("MD5: " + err); + } +} diff --git a/frameworks/js/ani/test/test_rand.ets b/frameworks/js/ani/test/test_rand.ets new file mode 100644 index 0000000..5dcf01e --- /dev/null +++ b/frameworks/js/ani/test/test_rand.ets @@ -0,0 +1,34 @@ + +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +export function testRandom() { + try { + let random = cryptoFramework.createRandom(); + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + random.setSeed({ + data: dataBytes + }); + let output = random.generateRandomSync(16); + let str = utils.uint8ArrayToHexStr(output.data); + console.log("Random: " + str); + } catch (err) { + console.error("Random: " + err) + } +} diff --git a/frameworks/js/ani/test/test.ets b/frameworks/js/ani/test/test_utils.ets similarity index 61% rename from frameworks/js/ani/test/test.ets rename to frameworks/js/ani/test/test_utils.ets index a12f4c7..38a1239 100644 --- a/frameworks/js/ani/test/test.ets +++ b/frameworks/js/ani/test/test_utils.ets @@ -14,9 +14,9 @@ */ // import buffer from "@ohos.buffer" -import cryptoFramework from "@ohos.security.cryptoFramework"; -function hexStrToUint8Array(data: string): Uint8Array { +namespace utils { +export function hexStrToUint8Array(data: string): Uint8Array { // return new Uint8Array(buffer.from(data, 'hex').buffer); if (data.length % 2 !== 0) { throw new Error("Invalid hex string"); @@ -28,7 +28,7 @@ function hexStrToUint8Array(data: string): Uint8Array { return array; } -function stringToUint8Array(str: string): Uint8Array { +export function stringToUint8Array(str: string): Uint8Array { // return new Uint8Array(buffer.from(str, 'utf-8').buffer); const array = new Uint8Array(str.length); for (let i = 0; i < str.length; i++) { @@ -37,7 +37,7 @@ function stringToUint8Array(str: string): Uint8Array { return array; } -function uint8ArrayToHexStr(data: Uint8Array): string { +export function uint8ArrayToHexStr(data: Uint8Array): string { // return buffer.from(data).toString('hex').toUpperCase(); let str = ''; for (let i = 0; i < data.length; i++) { @@ -46,24 +46,6 @@ function uint8ArrayToHexStr(data: Uint8Array): string { } return str; } +} // namespace utils -function main() { - let key = "1234567890"; - let data = "Hello World"; - let keyAlgo = "HMAC"; - let macAlgo = "SHA256"; - let keyBytes = hexStrToUint8Array(key); - let dataBytes = stringToUint8Array(data); - let symKey = cryptoFramework.createSymKeyGenerator(keyAlgo).convertKeySync({ - data: keyBytes - }); - let mac = cryptoFramework.createMac(macAlgo); - mac.initSync(symKey); - mac.updateSync({ - data: dataBytes - }); - let output = mac.doFinalSync(); - let str = uint8ArrayToHexStr(output.data); - console.log(keyAlgo + "-" + macAlgo + ": " + str); - // HMAC-SHA256: 610654DF0F74D94B02EBCAB2CF6A0D190B0E889F0777AC63C803C60CBC0AB935 -} +export default utils; -- Gitee