Adding tests to verify EVP_PKEY_from_keystore2
API [Keystore2-engine].
1. Generate RSA key and grant it to a user. In user context load the key using `EVP_PKEY_from_keystore` and perform sign and verify opeearions. [keystore2_perofrm_crypto_op_using_keystore2_engine_rsa_key_success] 2. Generate EC key and grant it to a user. In user context load the key using `EVP_PKEY_from_keystore` and perform sign and verify operations. [keystore2_perofrm_crypto_op_using_keystore2_engine_ec_key_success] 3. Generate RSA key and grant it to a user. Re-encode the certificate as PEM and update the certificate using `updateSubcomponents`. In user context load the key using `EVP_PKEY_from_keystore` and perform sign and verify operations. Bug: 201343811 Test: atest keystore2_client_tests Change-Id: I7dafd598f4198e11103cd11695b2f67636f24755
This commit is contained in:
parent
6ff734224e
commit
28abde6189
8 changed files with 457 additions and 3 deletions
|
@ -36,7 +36,7 @@ cc_library_shared {
|
|||
],
|
||||
|
||||
shared_libs: [
|
||||
"android.system.keystore2-V1-ndk",
|
||||
"android.system.keystore2-V3-ndk",
|
||||
"libbinder_ndk",
|
||||
"libcrypto",
|
||||
"libcutils",
|
||||
|
|
|
@ -299,6 +299,9 @@ pub enum Error {
|
|||
/// Error code to indicate error in ASN.1 DER-encoded data creation.
|
||||
#[error("Failed to create and encode ASN.1 data.")]
|
||||
DerEncodeFailed,
|
||||
/// Error code to indicate error while using keystore-engine API.
|
||||
#[error("Failed to perform crypto op using keystore-engine APIs.")]
|
||||
Keystore2EngineOpFailed,
|
||||
}
|
||||
|
||||
/// Keystore2 error mapping.
|
||||
|
|
|
@ -57,6 +57,7 @@ rust_test {
|
|||
"libkeymaster_portable",
|
||||
"libkeymaster_messages",
|
||||
"libcppbor_external",
|
||||
"libkeystore-engine",
|
||||
],
|
||||
require_root: true,
|
||||
}
|
||||
|
@ -80,6 +81,7 @@ cc_library_static {
|
|||
"libkeymaster_portable",
|
||||
"libkeymaster_messages",
|
||||
"libcppbor_external",
|
||||
"libkeystore-engine",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <KeyMintAidlTestBase.h>
|
||||
#include <aidl/android/hardware/security/keymint/ErrorCode.h>
|
||||
#include <keymaster/UniquePtr.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <hardware/keymaster_defs.h>
|
||||
|
@ -16,7 +17,6 @@
|
|||
#include <keymaster/km_openssl/attestation_record.h>
|
||||
#include <keymaster/km_openssl/openssl_err.h>
|
||||
#include <keymaster/km_openssl/openssl_utils.h>
|
||||
#include <openssl/asn1t.h>
|
||||
|
||||
using aidl::android::hardware::security::keymint::ErrorCode;
|
||||
|
||||
|
@ -24,6 +24,9 @@ using aidl::android::hardware::security::keymint::ErrorCode;
|
|||
#define LENGTH_MASK 0x80
|
||||
#define LENGTH_VALUE_MASK 0x7F
|
||||
|
||||
/* EVP_PKEY_from_keystore is from system/security/keystore-engine. */
|
||||
extern "C" EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id);
|
||||
|
||||
/**
|
||||
* ASN.1 structure for `KeyDescription` Schema.
|
||||
* See `IKeyMintDevice.aidl` for documentation of the `KeyDescription` schema.
|
||||
|
@ -84,6 +87,8 @@ struct TEST_SECURE_KEY_WRAPPER_Delete {
|
|||
void operator()(TEST_SECURE_KEY_WRAPPER* p) { TEST_SECURE_KEY_WRAPPER_free(p); }
|
||||
};
|
||||
|
||||
const std::string keystore2_grant_id_prefix("ks2_keystore-engine_grant_id:");
|
||||
|
||||
/* This function extracts a certificate from the certs_chain_buffer at the given
|
||||
* offset. Each DER encoded certificate starts with TAG_SEQUENCE followed by the
|
||||
* total length of the certificate. The length of the certificate is determined
|
||||
|
@ -364,3 +369,137 @@ CxxResult createWrappedKey(rust::Vec<rust::u8> encrypted_secure_key,
|
|||
|
||||
return cxx_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform EC/RSA sign operation using `EVP_PKEY`.
|
||||
*/
|
||||
bool performSignData(const char* data, size_t data_len, EVP_PKEY* pkey, unsigned char** signature,
|
||||
size_t* signature_len) {
|
||||
// Create the signing context
|
||||
EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
|
||||
if (md_ctx == NULL) {
|
||||
LOG(ERROR) << "Failed to create signing context";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize the signing operation
|
||||
if (EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
|
||||
LOG(ERROR) << "Failed to initialize signing operation";
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sign the data
|
||||
if (EVP_DigestSignUpdate(md_ctx, data, data_len) != 1) {
|
||||
LOG(ERROR) << "Failed to sign data";
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine the length of the signature
|
||||
if (EVP_DigestSignFinal(md_ctx, NULL, signature_len) != 1) {
|
||||
LOG(ERROR) << "Failed to determine signature length";
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate memory for the signature
|
||||
*signature = (unsigned char*)malloc(*signature_len);
|
||||
if (*signature == NULL) {
|
||||
LOG(ERROR) << "Failed to allocate memory for the signature";
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform the final signing operation
|
||||
if (EVP_DigestSignFinal(md_ctx, *signature, signature_len) != 1) {
|
||||
LOG(ERROR) << "Failed to perform signing operation";
|
||||
free(*signature);
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform EC/RSA verify operation using `EVP_PKEY`.
|
||||
*/
|
||||
int performVerifySignature(const char* data, size_t data_len, EVP_PKEY* pkey,
|
||||
const unsigned char* signature, size_t signature_len) {
|
||||
// Create the verification context
|
||||
EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
|
||||
if (md_ctx == NULL) {
|
||||
LOG(ERROR) << "Failed to create verification context";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize the verification operation
|
||||
if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
|
||||
LOG(ERROR) << "Failed to initialize verification operation";
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify the data
|
||||
if (EVP_DigestVerifyUpdate(md_ctx, data, data_len) != 1) {
|
||||
LOG(ERROR) << "Failed to verify data";
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform the verification operation
|
||||
int ret = EVP_DigestVerifyFinal(md_ctx, signature, signature_len);
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
|
||||
return ret == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the `EVP_PKEY` for the given KeyMint Key and perform Sign/Verify operations
|
||||
* using extracted `EVP_PKEY`.
|
||||
*/
|
||||
bool performCryptoOpUsingKeystoreEngine(int64_t grant_id) {
|
||||
const int KEY_ID_LEN = 20;
|
||||
char key_id[KEY_ID_LEN] = "";
|
||||
snprintf(key_id, KEY_ID_LEN, "%" PRIx64, grant_id);
|
||||
std::string str_key = std::string(keystore2_grant_id_prefix) + key_id;
|
||||
bool result = false;
|
||||
|
||||
#if defined(OPENSSL_IS_BORINGSSL)
|
||||
EVP_PKEY* evp = EVP_PKEY_from_keystore(str_key.c_str());
|
||||
if (!evp) {
|
||||
LOG(ERROR) << "Error while loading a key from keystore-engine";
|
||||
return false;
|
||||
}
|
||||
|
||||
int algo_type = EVP_PKEY_id(evp);
|
||||
if (algo_type != EVP_PKEY_RSA && algo_type != EVP_PKEY_EC) {
|
||||
LOG(ERROR) << "Unsupported Algorithm. Only RSA and EC are allowed.";
|
||||
EVP_PKEY_free(evp);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char* signature = NULL;
|
||||
size_t signature_len = 0;
|
||||
const char* INPUT_DATA = "MY MESSAGE FOR SIGN";
|
||||
size_t data_len = strlen(INPUT_DATA);
|
||||
if (!performSignData(INPUT_DATA, data_len, evp, &signature, &signature_len)) {
|
||||
LOG(ERROR) << "Failed to sign data";
|
||||
EVP_PKEY_free(evp);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = performVerifySignature(INPUT_DATA, data_len, evp, signature, signature_len);
|
||||
if (!result) {
|
||||
LOG(ERROR) << "Signature verification failed";
|
||||
} else {
|
||||
LOG(INFO) << "Signature verification success";
|
||||
}
|
||||
|
||||
free(signature);
|
||||
EVP_PKEY_free(evp);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -9,3 +9,4 @@ CxxResult createWrappedKey(rust::Vec<rust::u8> encrypted_secure_key,
|
|||
rust::Vec<rust::u8> iv,
|
||||
rust::Vec<rust::u8> tag);
|
||||
CxxResult buildAsn1DerEncodedWrappedKeyDescription();
|
||||
bool performCryptoOpUsingKeystoreEngine(int64_t grant_id);
|
||||
|
|
|
@ -31,6 +31,7 @@ mod ffi {
|
|||
tag: Vec<u8>,
|
||||
) -> CxxResult;
|
||||
fn buildAsn1DerEncodedWrappedKeyDescription() -> CxxResult;
|
||||
fn performCryptoOpUsingKeystoreEngine(grant_id: i64) -> bool;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,3 +79,11 @@ pub fn create_wrapped_key(
|
|||
pub fn create_wrapped_key_additional_auth_data() -> Result<Vec<u8>, Error> {
|
||||
get_result(ffi::buildAsn1DerEncodedWrappedKeyDescription())
|
||||
}
|
||||
|
||||
pub fn perform_crypto_op_using_keystore_engine(grant_id: i64) -> Result<bool, Error> {
|
||||
if ffi::performCryptoOpUsingKeystoreEngine(grant_id) {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
Err(Error::Keystore2EngineOpFailed)
|
||||
}
|
||||
|
|
299
keystore2/tests/keystore2_client_keystore_engine_tests.rs
Normal file
299
keystore2/tests/keystore2_client_keystore_engine_tests.rs
Normal file
|
@ -0,0 +1,299 @@
|
|||
// Copyright 2023, The Android Open Source Project
|
||||
//
|
||||
// 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.
|
||||
|
||||
use nix::unistd::{Gid, Uid};
|
||||
use rustutils::users::AID_USER_OFFSET;
|
||||
|
||||
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
|
||||
Algorithm::Algorithm, Digest::Digest, EcCurve::EcCurve, KeyPurpose::KeyPurpose,
|
||||
PaddingMode::PaddingMode, SecurityLevel::SecurityLevel,
|
||||
};
|
||||
use android_system_keystore2::aidl::android::system::keystore2::{
|
||||
Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
|
||||
IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor, KeyPermission::KeyPermission,
|
||||
};
|
||||
|
||||
use keystore2_test_utils::{authorizations::AuthSetBuilder, get_keystore_service, run_as};
|
||||
|
||||
use crate::ffi_test_utils::perform_crypto_op_using_keystore_engine;
|
||||
|
||||
use openssl::x509::X509;
|
||||
|
||||
fn generate_rsa_key_and_grant_to_user(
|
||||
keystore2: &binder::Strong<dyn IKeystoreService>,
|
||||
sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
|
||||
alias: &str,
|
||||
grantee_uid: i32,
|
||||
access_vector: i32,
|
||||
) -> binder::Result<KeyDescriptor> {
|
||||
let gen_params = AuthSetBuilder::new()
|
||||
.no_auth_required()
|
||||
.algorithm(Algorithm::RSA)
|
||||
.rsa_public_exponent(65537)
|
||||
.key_size(2048)
|
||||
.purpose(KeyPurpose::SIGN)
|
||||
.purpose(KeyPurpose::VERIFY)
|
||||
.padding_mode(PaddingMode::NONE)
|
||||
.digest(Digest::NONE);
|
||||
|
||||
let key_metadata = sec_level
|
||||
.generateKey(
|
||||
&KeyDescriptor {
|
||||
domain: Domain::APP,
|
||||
nspace: -1,
|
||||
alias: Some(alias.to_string()),
|
||||
blob: None,
|
||||
},
|
||||
None,
|
||||
&gen_params,
|
||||
0,
|
||||
b"entropy",
|
||||
)
|
||||
.expect("Failed to generate RSA Key.");
|
||||
|
||||
assert!(key_metadata.certificate.is_some());
|
||||
|
||||
keystore2.grant(&key_metadata.key, grantee_uid, access_vector)
|
||||
}
|
||||
|
||||
fn generate_ec_key_and_grant_to_user(
|
||||
keystore2: &binder::Strong<dyn IKeystoreService>,
|
||||
sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
|
||||
alias: &str,
|
||||
grantee_uid: i32,
|
||||
access_vector: i32,
|
||||
) -> binder::Result<KeyDescriptor> {
|
||||
let gen_params = AuthSetBuilder::new()
|
||||
.no_auth_required()
|
||||
.algorithm(Algorithm::EC)
|
||||
.purpose(KeyPurpose::SIGN)
|
||||
.purpose(KeyPurpose::VERIFY)
|
||||
.digest(Digest::NONE)
|
||||
.ec_curve(EcCurve::P_256);
|
||||
|
||||
let key_metadata = sec_level
|
||||
.generateKey(
|
||||
&KeyDescriptor {
|
||||
domain: Domain::APP,
|
||||
nspace: -1,
|
||||
alias: Some(alias.to_string()),
|
||||
blob: None,
|
||||
},
|
||||
None,
|
||||
&gen_params,
|
||||
0,
|
||||
b"entropy",
|
||||
)
|
||||
.expect("Failed to generate EC Key.");
|
||||
|
||||
assert!(key_metadata.certificate.is_some());
|
||||
|
||||
keystore2.grant(&key_metadata.key, grantee_uid, access_vector)
|
||||
}
|
||||
|
||||
fn generate_key_and_grant_to_user(
|
||||
keystore2: &binder::Strong<dyn IKeystoreService>,
|
||||
sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
|
||||
alias: &str,
|
||||
grantee_uid: u32,
|
||||
algo: Algorithm,
|
||||
) -> Result<i64, Box<dyn std::error::Error>> {
|
||||
let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0 | KeyPermission::DELETE.0;
|
||||
|
||||
assert!(matches!(algo, Algorithm::RSA | Algorithm::EC));
|
||||
|
||||
let grant_key = match algo {
|
||||
Algorithm::RSA => generate_rsa_key_and_grant_to_user(
|
||||
keystore2,
|
||||
sec_level,
|
||||
alias,
|
||||
grantee_uid.try_into().unwrap(),
|
||||
access_vector,
|
||||
)
|
||||
.unwrap(),
|
||||
Algorithm::EC => generate_ec_key_and_grant_to_user(
|
||||
keystore2,
|
||||
sec_level,
|
||||
alias,
|
||||
grantee_uid.try_into().unwrap(),
|
||||
access_vector,
|
||||
)
|
||||
.unwrap(),
|
||||
_ => panic!("Unsupported algorithms"),
|
||||
};
|
||||
|
||||
assert_eq!(grant_key.domain, Domain::GRANT);
|
||||
|
||||
Ok(grant_key.nspace)
|
||||
}
|
||||
|
||||
fn perform_crypto_op_using_granted_key(
|
||||
keystore2: &binder::Strong<dyn IKeystoreService>,
|
||||
grant_key_nspace: i64,
|
||||
) {
|
||||
// Load the granted key from Keystore2-Engine API and perform crypto operations.
|
||||
assert!(perform_crypto_op_using_keystore_engine(grant_key_nspace).unwrap());
|
||||
|
||||
// Delete the granted key.
|
||||
keystore2
|
||||
.deleteKey(&KeyDescriptor {
|
||||
domain: Domain::GRANT,
|
||||
nspace: grant_key_nspace,
|
||||
alias: None,
|
||||
blob: None,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keystore2_perofrm_crypto_op_using_keystore2_engine_rsa_key_success() {
|
||||
static TARGET_SU_CTX: &str = "u:r:su:s0";
|
||||
|
||||
static GRANTEE_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
|
||||
const USER_ID: u32 = 99;
|
||||
const APPLICATION_ID: u32 = 10001;
|
||||
static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
|
||||
static GRANTEE_GID: u32 = GRANTEE_UID;
|
||||
|
||||
// Generate a key and grant it to a user with GET_INFO|USE|DELETE key permissions.
|
||||
let grant_key_nspace = unsafe {
|
||||
run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
|
||||
let keystore2 = get_keystore_service();
|
||||
let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
|
||||
let alias = "keystore2_engine_rsa_key";
|
||||
generate_key_and_grant_to_user(
|
||||
&keystore2,
|
||||
&sec_level,
|
||||
alias,
|
||||
GRANTEE_UID,
|
||||
Algorithm::RSA,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
};
|
||||
|
||||
// In grantee context load the key and try to perform crypto operation.
|
||||
unsafe {
|
||||
run_as::run_as(
|
||||
GRANTEE_CTX,
|
||||
Uid::from_raw(GRANTEE_UID),
|
||||
Gid::from_raw(GRANTEE_GID),
|
||||
move || {
|
||||
let keystore2 = get_keystore_service();
|
||||
perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
|
||||
},
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keystore2_perofrm_crypto_op_using_keystore2_engine_ec_key_success() {
|
||||
static TARGET_SU_CTX: &str = "u:r:su:s0";
|
||||
|
||||
static GRANTEE_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
|
||||
const USER_ID: u32 = 99;
|
||||
const APPLICATION_ID: u32 = 10001;
|
||||
static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
|
||||
static GRANTEE_GID: u32 = GRANTEE_UID;
|
||||
|
||||
// Generate a key and grant it to a user with GET_INFO|USE|DELETE key permissions.
|
||||
let grant_key_nspace = unsafe {
|
||||
run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
|
||||
let keystore2 = get_keystore_service();
|
||||
let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
|
||||
let alias = "keystore2_engine_ec_test_key";
|
||||
generate_key_and_grant_to_user(
|
||||
&keystore2,
|
||||
&sec_level,
|
||||
alias,
|
||||
GRANTEE_UID,
|
||||
Algorithm::EC,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
};
|
||||
|
||||
// In grantee context load the key and try to perform crypto operation.
|
||||
unsafe {
|
||||
run_as::run_as(
|
||||
GRANTEE_CTX,
|
||||
Uid::from_raw(GRANTEE_UID),
|
||||
Gid::from_raw(GRANTEE_GID),
|
||||
move || {
|
||||
let keystore2 = get_keystore_service();
|
||||
perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
|
||||
},
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keystore2_perofrm_crypto_op_using_keystore2_engine_pem_pub_key_success() {
|
||||
static TARGET_SU_CTX: &str = "u:r:su:s0";
|
||||
|
||||
static GRANTEE_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
|
||||
const USER_ID: u32 = 99;
|
||||
const APPLICATION_ID: u32 = 10001;
|
||||
static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
|
||||
static GRANTEE_GID: u32 = GRANTEE_UID;
|
||||
|
||||
// Generate a key and re-encode it's certificate as PEM and update it and
|
||||
// grant it to a user with GET_INFO|USE|DELETE key permissions.
|
||||
let grant_key_nspace = unsafe {
|
||||
run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
|
||||
let keystore2 = get_keystore_service();
|
||||
let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
|
||||
let alias = "keystore2_engine_rsa_pem_pub_key";
|
||||
let grant_key_nspace = generate_key_and_grant_to_user(
|
||||
&keystore2,
|
||||
&sec_level,
|
||||
alias,
|
||||
GRANTEE_UID,
|
||||
Algorithm::RSA,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Update certificate with encodeed PEM data.
|
||||
let key_entry_response = keystore2
|
||||
.getKeyEntry(&KeyDescriptor {
|
||||
domain: Domain::APP,
|
||||
nspace: -1,
|
||||
alias: Some(alias.to_string()),
|
||||
blob: None,
|
||||
})
|
||||
.unwrap();
|
||||
let cert_bytes = key_entry_response.metadata.certificate.as_ref().unwrap();
|
||||
let cert = X509::from_der(cert_bytes.as_ref()).unwrap();
|
||||
let cert_pem = cert.to_pem().unwrap();
|
||||
keystore2
|
||||
.updateSubcomponent(&key_entry_response.metadata.key, Some(&cert_pem), None)
|
||||
.expect("updateSubcomponent failed.");
|
||||
|
||||
grant_key_nspace
|
||||
})
|
||||
};
|
||||
|
||||
// In grantee context load the key and try to perform crypto operation.
|
||||
unsafe {
|
||||
run_as::run_as(
|
||||
GRANTEE_CTX,
|
||||
Uid::from_raw(GRANTEE_UID),
|
||||
Gid::from_raw(GRANTEE_GID),
|
||||
move || {
|
||||
let keystore2 = get_keystore_service();
|
||||
perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
|
||||
},
|
||||
)
|
||||
};
|
||||
}
|
|
@ -23,6 +23,7 @@ pub mod keystore2_client_hmac_key_tests;
|
|||
pub mod keystore2_client_import_keys_tests;
|
||||
pub mod keystore2_client_key_agreement_tests;
|
||||
pub mod keystore2_client_key_id_domain_tests;
|
||||
pub mod keystore2_client_keystore_engine_tests;
|
||||
pub mod keystore2_client_list_entries_tests;
|
||||
pub mod keystore2_client_operation_tests;
|
||||
pub mod keystore2_client_rsa_key_tests;
|
||||
|
|
Loading…
Reference in a new issue