diff --git a/include/libaries_askar.h b/include/libaries_askar.h index fdcceffc..103dc47f 100644 --- a/include/libaries_askar.h +++ b/include/libaries_askar.h @@ -219,6 +219,14 @@ typedef struct ArcHandle_FfiKeyEntryList { typedef struct ArcHandle_FfiKeyEntryList KeyEntryListHandle; +typedef struct FfiResultList_String FfiStringList; + +typedef struct ArcHandle_FfiStringList { + const FfiStringList *_0; +} ArcHandle_FfiStringList; + +typedef struct ArcHandle_FfiStringList StringListHandle; + typedef int64_t CallbackId; typedef void (*LogCallback)(const void *context, @@ -229,14 +237,6 @@ typedef void (*LogCallback)(const void *context, const char *file, int32_t line); -typedef struct FfiResultList_String FfiStringList; - -typedef struct ArcHandle_FfiStringList { - const FfiStringList *_0; -} ArcHandle_FfiStringList; - -typedef struct ArcHandle_FfiStringList StringListHandle; - #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -384,6 +384,8 @@ ErrorCode askar_key_get_public_bytes(LocalKeyHandle handle, struct SecretBuffer ErrorCode askar_key_get_secret_bytes(LocalKeyHandle handle, struct SecretBuffer *out); +ErrorCode skar_key_get_supported_backends(StringListHandle *out); + ErrorCode askar_key_sign_message(LocalKeyHandle handle, struct ByteBuffer message, FfiStr sig_type, diff --git a/src/ffi/key.rs b/src/ffi/key.rs index 70ff2c41..67526867 100644 --- a/src/ffi/key.rs +++ b/src/ffi/key.rs @@ -1,5 +1,6 @@ use super::{ handle::ArcHandle, + result_list::{FfiStringList, StringListHandle}, secret::{EncryptedBuffer, SecretBuffer}, ErrorCode, }; @@ -576,3 +577,29 @@ pub extern "C" fn askar_key_derive_ecdh_1pu( Ok(ErrorCode::Success) } } + +#[no_mangle] +pub extern "C" fn askar_key_get_supported_backends(out: *mut StringListHandle) -> ErrorCode { + catch_err! { + trace!("Retrieving supported key backends"); + check_useful_c_ptr!(out); + + let mut backends = vec![KeyBackend::Software]; + + if cfg!(feature = "mobile_secure_element") { + backends.push(KeyBackend::SecureElement); + } + + let backends: Vec = backends + .iter() + .map(|b| >::into(b.clone()).to_owned()) + .collect(); + + let string_list = StringListHandle::create(FfiStringList::from(backends)); + + + unsafe { *out = string_list }; + + Ok(ErrorCode::Success) + } +} diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index baa78d32..0d47ecfb 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -20,7 +20,7 @@ mod macros; mod error; mod key; mod log; -mod result_list; +pub(crate) mod result_list; mod secret; mod store; mod tags; diff --git a/wrappers/javascript/aries-askar-nodejs/src/NodeJSAriesAskar.ts b/wrappers/javascript/aries-askar-nodejs/src/NodeJSAriesAskar.ts index 8b01ddb6..950cbbab 100644 --- a/wrappers/javascript/aries-askar-nodejs/src/NodeJSAriesAskar.ts +++ b/wrappers/javascript/aries-askar-nodejs/src/NodeJSAriesAskar.ts @@ -99,6 +99,7 @@ import { } from '@hyperledger/aries-askar-shared' import { + allocateStringListHandle, serializeArguments, encryptedBufferStructToClass, deallocateCallbackBuffer, @@ -616,7 +617,7 @@ export class NodeJSAriesAskar implements AriesAskar { } public keyGenerate(options: KeyGenerateOptions): LocalKeyHandle { - const { algorithm, ephemeral,backend } = serializeArguments(options) + const { algorithm, ephemeral, backend } = serializeArguments(options) const ret = allocatePointer() const errorCode = this.nativeAriesAskar.askar_key_generate(algorithm, backend, ephemeral, ret) @@ -742,6 +743,31 @@ export class NodeJSAriesAskar implements AriesAskar { return encryptedBufferStructToClass(encryptedBuffer) } + public keyGetSupportedBackends(): Array { + const stringListHandlePtr = allocateStringListHandle() + + const keyGetSupportedBackendsErrorCode = this.nativeAriesAskar.askar_key_get_supported_backends(stringListHandlePtr) + this.handleError(keyGetSupportedBackendsErrorCode) + const stringListHandle = stringListHandlePtr.deref() as Buffer + + const listCountPtr = allocateInt32Buffer() + const stringListCountErrorCode = this.nativeAriesAskar.askar_string_list_count(stringListHandle, listCountPtr) + this.handleError(stringListCountErrorCode) + const count = listCountPtr.deref() as number + + const supportedBackends = [] + + for (let i = 0; i < count; i++) { + const strPtr = allocateStringBuffer() + const errorCode = this.nativeAriesAskar.askar_string_list_get_item(stringListHandle, i, strPtr) + this.handleError(errorCode) + supportedBackends.push(strPtr.deref() as string) + } + this.nativeAriesAskar.askar_string_list_free(stringListHandle) + + return supportedBackends + } + public scanFree(options: ScanFreeOptions): void { const { scanHandle } = serializeArguments(options) diff --git a/wrappers/javascript/aries-askar-nodejs/src/ffi/alloc.ts b/wrappers/javascript/aries-askar-nodejs/src/ffi/alloc.ts index 415760c4..2cff8d2f 100644 --- a/wrappers/javascript/aries-askar-nodejs/src/ffi/alloc.ts +++ b/wrappers/javascript/aries-askar-nodejs/src/ffi/alloc.ts @@ -19,6 +19,8 @@ export const allocateAeadParams = (): Buffer => alloc(AeadParamsStruct) export const allocateLocalKeyHandle = allocatePointer +export const allocateStringListHandle = allocatePointer + export const allocateCallbackBuffer = (callback: Buffer) => setTimeout(() => callback, 1000000) export const deallocateCallbackBuffer = (id: number) => clearTimeout(id as unknown as NodeJS.Timeout) diff --git a/wrappers/javascript/aries-askar-nodejs/src/library/bindings.ts b/wrappers/javascript/aries-askar-nodejs/src/library/bindings.ts index 169a530c..e1007d5e 100644 --- a/wrappers/javascript/aries-askar-nodejs/src/library/bindings.ts +++ b/wrappers/javascript/aries-askar-nodejs/src/library/bindings.ts @@ -130,6 +130,7 @@ export const nativeBindings = { [FFI_POINTER, ByteBufferStruct, ByteBufferStruct, FFI_STRING, FFI_INT8_PTR], ], askar_key_wrap_key: [FFI_ERROR_CODE, [FFI_POINTER, FFI_POINTER, ByteBufferStruct, EncryptedBufferStructPtr]], + askar_key_get_supported_backends: [FFI_ERROR_CODE, [FFI_STRING_LIST_HANDLE]], askar_scan_free: [FFI_ERROR_CODE, [FFI_SCAN_HANDLE]], askar_scan_next: [FFI_ERROR_CODE, [FFI_SCAN_HANDLE, FFI_CALLBACK_PTR, FFI_CALLBACK_ID]], diff --git a/wrappers/javascript/aries-askar-nodejs/tests/keys.test.ts b/wrappers/javascript/aries-askar-nodejs/tests/keys.test.ts index 587489c6..8d7b34d8 100644 --- a/wrappers/javascript/aries-askar-nodejs/tests/keys.test.ts +++ b/wrappers/javascript/aries-askar-nodejs/tests/keys.test.ts @@ -1,10 +1,19 @@ import { Key, KeyAlgs, KeyMethod } from '@hyperledger/aries-askar-shared' +import { ariesAskarNodeJS } from '../src' + describe('keys', () => { beforeAll(() => { require('@hyperledger/aries-askar-nodejs') }) + test('supported backends', () => { + const backends = ariesAskarNodeJS.keyGetSupportedBackends() + + expect(backends.length).toStrictEqual(1) + expect(backends).toStrictEqual(expect.arrayContaining(['software'])) + }) + test('aes cbc hmac', () => { const key = Key.generate(KeyAlgs.AesA128CbcHs256) expect(key.algorithm).toStrictEqual(KeyAlgs.AesA128CbcHs256) diff --git a/wrappers/javascript/aries-askar-shared/src/ariesAskar/AriesAskar.ts b/wrappers/javascript/aries-askar-shared/src/ariesAskar/AriesAskar.ts index a0e07844..aac70012 100644 --- a/wrappers/javascript/aries-askar-shared/src/ariesAskar/AriesAskar.ts +++ b/wrappers/javascript/aries-askar-shared/src/ariesAskar/AriesAskar.ts @@ -8,8 +8,7 @@ import type { SessionHandle, StoreHandle, } from '../crypto' -import type { KeyAlgs, LogLevel, SigAlgs } from '../enums' -import { KeyBackend } from '../enums' +import type { KeyAlgs, LogLevel, SigAlgs, KeyBackend } from '../enums' import type { AriesAskarErrorObject } from '../error' import type { AeadParams, EncryptedBuffer } from '../types' diff --git a/wrappers/python/aries_askar/bindings/__init__.py b/wrappers/python/aries_askar/bindings/__init__.py index ec0abddf..3bdc4948 100644 --- a/wrappers/python/aries_askar/bindings/__init__.py +++ b/wrappers/python/aries_askar/bindings/__init__.py @@ -202,6 +202,7 @@ async def store_list_profiles(handle: StoreHandle) -> Sequence[str]: byref(buf), ) ret.append(str(buf)) + return ret @@ -865,6 +866,31 @@ def key_unwrap_key( return result +def key_get_supported_backends() -> Sequence[str]: + handle = StringListHandle() + invoke("askar_key_get_string_handle", POINTER(StringListHandle), byref(handle)) + count = c_int32() + invoke( + "askar_string_list_count", + (StringListHandle, POINTER(c_int32)), + handle, + byref(count), + ) + ret = [] + for idx in range(count.value): + buf = StrBuffer() + invoke( + "askar_string_list_get_item", + (StringListHandle, c_int32, POINTER(StrBuffer)), + handle, + idx, + byref(buf), + ) + ret.append(str(buf)) + + return ret + + def key_crypto_box_random_nonce() -> ByteBuffer: buf = ByteBuffer() invoke( diff --git a/wrappers/python/aries_askar/key.py b/wrappers/python/aries_askar/key.py index 7e96bca1..d622c9ba 100644 --- a/wrappers/python/aries_askar/key.py +++ b/wrappers/python/aries_askar/key.py @@ -1,6 +1,6 @@ """Handling of Key instances.""" -from typing import Union, Optional +from typing import Union, Optional, Sequence from . import bindings from .bindings import AeadParams, Encrypted, LocalKeyHandle @@ -15,7 +15,13 @@ def __init__(self, handle: LocalKeyHandle): self._handle = handle @classmethod - def generate(cls, alg: Union[str, KeyAlg], *, key_backend: Optional[KeyBackend] = None, ephemeral: bool = False) -> "Key": + def generate( + cls, + alg: Union[str, KeyAlg], + *, + key_backend: Optional[KeyBackend] = None, + ephemeral: bool = False, + ) -> "Key": return cls(bindings.key_generate(alg, key_backend, ephemeral)) @classmethod @@ -40,6 +46,10 @@ def from_public_bytes(cls, alg: Union[str, KeyAlg], public: bytes) -> "Key": def from_jwk(cls, jwk: Union[dict, str, bytes]) -> "Key": return cls(bindings.key_from_jwk(jwk)) + @classmethod + def get_supported_backends(cls) -> Sequence[str]: + return bindings.key_get_supported_backends() + @property def handle(self) -> LocalKeyHandle: """Accessor for the key handle.""" diff --git a/wrappers/python/tests/test_keys.py b/wrappers/python/tests/test_keys.py index 49a79f9e..b2d03e63 100644 --- a/wrappers/python/tests/test_keys.py +++ b/wrappers/python/tests/test_keys.py @@ -1,5 +1,6 @@ import json +from aries_askar.types import KeyBackend import pytest from aries_askar import ( @@ -9,6 +10,12 @@ ) +def test_get_supported_backends(): + backends = Key.get_supported_backends() + + assert backends == [str(KeyBackend.Software)] + + def test_aes_cbc_hmac(): key = Key.generate(KeyAlg.A128CBC_HS256) assert key.algorithm == KeyAlg.A128CBC_HS256