Restructred blob utilities to make them accessible in tests.
Creating a new library "libkeystore2_with_test_utils" where it includes blob utils
apis and sample test vectors based on feature flag keystore2_blob_test_utils.
Bug: 213173772
Bug: 213172664
Bug: 203101472
Test: keystore2_test
Change-Id: I869d27d1d3e8c6d28d8f5e5d6aed4305b5265816
diff --git a/keystore2/src/legacy_blob.rs b/keystore2/src/legacy_blob.rs
index cbc680d..d75bfd2 100644
--- a/keystore2/src/legacy_blob.rs
+++ b/keystore2/src/legacy_blob.rs
@@ -1387,25 +1387,24 @@
}
}
-#[cfg(test)]
-mod test {
+/// This module implements utility apis for creating legacy blob files.
+#[cfg(feature = "keystore2_blob_test_utils")]
+pub mod test_utils {
#![allow(dead_code)]
- use super::*;
- use keystore2_crypto::{aes_gcm_decrypt, aes_gcm_encrypt};
- use rand::Rng;
- use std::string::FromUtf8Error;
- mod legacy_blob_test_vectors;
+
+ /// test vectors for legacy key blobs
+ pub mod legacy_blob_test_vectors;
+
use crate::legacy_blob::blob_types::{
GENERIC, KEY_CHARACTERISTICS, KEY_CHARACTERISTICS_CACHE, KM_BLOB, SUPER_KEY,
SUPER_KEY_AES256,
};
- use crate::legacy_blob::test::legacy_blob_test_vectors::*;
+ use crate::legacy_blob::*;
use anyhow::{anyhow, Result};
- use keystore2_test_utils::TempDir;
+ use keystore2_crypto::{aes_gcm_decrypt, aes_gcm_encrypt};
use std::convert::TryInto;
use std::fs::OpenOptions;
use std::io::Write;
- use std::ops::Deref;
/// This function takes a blob and synchronizes the encrypted/super encrypted flags
/// with the blob type for the pairs Generic/EncryptedGeneric,
@@ -1414,7 +1413,7 @@
/// or flags::ENCRYPTED is set, the payload is encrypted and the corresponding
/// encrypted variant is returned, and vice versa. All other variants remain untouched
/// even if flags and BlobValue variant are inconsistent.
- fn prepare_blob(blob: Blob, key: &[u8]) -> Result<Blob> {
+ pub fn prepare_blob(blob: Blob, key: &[u8]) -> Result<Blob> {
match blob {
Blob { value: BlobValue::Generic(data), flags } if blob.is_encrypted() => {
let (ciphertext, iv, tag) = aes_gcm_encrypt(&data, key).unwrap();
@@ -1453,7 +1452,8 @@
}
}
- struct LegacyBlobHeader {
+ /// Legacy blob header structure.
+ pub struct LegacyBlobHeader {
version: u8,
blob_type: u8,
flags: u8,
@@ -1467,7 +1467,7 @@
/// version 3. Note that the flags field and the values field may be
/// inconsistent and could be sanitized by this function. It is intentionally
/// not done to enable tests to construct malformed blobs.
- fn write_legacy_blob(out: &mut dyn Write, blob: Blob) -> Result<usize> {
+ pub fn write_legacy_blob(out: &mut dyn Write, blob: Blob) -> Result<usize> {
let (header, data, salt) = match blob {
Blob { value: BlobValue::Generic(data), flags } => (
LegacyBlobHeader {
@@ -1581,7 +1581,9 @@
write_legacy_blob_helper(out, &header, &data, salt.as_deref())
}
- fn write_legacy_blob_helper(
+ /// This function takes LegacyBlobHeader, blob payload and writes it to out as a legacy blob file
+ /// version 3.
+ pub fn write_legacy_blob_helper(
out: &mut dyn Write,
header: &LegacyBlobHeader,
data: &[u8],
@@ -1622,10 +1624,51 @@
Ok(40 + data.len() + info.map(|v| v.len()).unwrap_or(0))
}
- fn make_encrypted_characteristics_file<P: AsRef<Path>>(path: P, key: &[u8]) -> Result<()> {
+ /// Create encrypted characteristics file using given key.
+ pub fn make_encrypted_characteristics_file<P: AsRef<Path>>(
+ path: P,
+ key: &[u8],
+ data: &[u8],
+ ) -> Result<()> {
+ let mut file = OpenOptions::new().write(true).create_new(true).open(path).unwrap();
+ let blob =
+ Blob { value: BlobValue::Characteristics(data.to_vec()), flags: flags::ENCRYPTED };
+ let blob = prepare_blob(blob, key).unwrap();
+ write_legacy_blob(&mut file, blob).unwrap();
+ Ok(())
+ }
+
+ /// Create encrypted user certificate file using given key.
+ pub fn make_encrypted_usr_cert_file<P: AsRef<Path>>(
+ path: P,
+ key: &[u8],
+ data: &[u8],
+ ) -> Result<()> {
+ let mut file = OpenOptions::new().write(true).create_new(true).open(path).unwrap();
+ let blob = Blob { value: BlobValue::Generic(data.to_vec()), flags: flags::ENCRYPTED };
+ let blob = prepare_blob(blob, key).unwrap();
+ write_legacy_blob(&mut file, blob).unwrap();
+ Ok(())
+ }
+
+ /// Create encrypted CA certificate file using given key.
+ pub fn make_encrypted_ca_cert_file<P: AsRef<Path>>(
+ path: P,
+ key: &[u8],
+ data: &[u8],
+ ) -> Result<()> {
+ let mut file = OpenOptions::new().write(true).create_new(true).open(path).unwrap();
+ let blob = Blob { value: BlobValue::Generic(data.to_vec()), flags: flags::ENCRYPTED };
+ let blob = prepare_blob(blob, key).unwrap();
+ write_legacy_blob(&mut file, blob).unwrap();
+ Ok(())
+ }
+
+ /// Create encrypted user key file using given key.
+ pub fn make_encrypted_key_file<P: AsRef<Path>>(path: P, key: &[u8], data: &[u8]) -> Result<()> {
let mut file = OpenOptions::new().write(true).create_new(true).open(path).unwrap();
let blob = Blob {
- value: BlobValue::Characteristics(KEY_PARAMETERS.to_vec()),
+ value: BlobValue::Decrypted(ZVec::try_from(data).unwrap()),
flags: flags::ENCRYPTED,
};
let blob = prepare_blob(blob, key).unwrap();
@@ -1633,27 +1676,29 @@
Ok(())
}
- fn make_encrypted_usr_cert_file<P: AsRef<Path>>(path: P, key: &[u8]) -> Result<()> {
+ /// Create user or ca cert blob file.
+ pub fn make_cert_blob_file<P: AsRef<Path>>(path: P, data: &[u8]) -> Result<()> {
let mut file = OpenOptions::new().write(true).create_new(true).open(path).unwrap();
- let blob = Blob {
- value: BlobValue::Generic(LOADED_CERT_AUTHBOUND.to_vec()),
- flags: flags::ENCRYPTED,
- };
- let blob = prepare_blob(blob, key).unwrap();
+ let blob = Blob { value: BlobValue::Generic(data.to_vec()), flags: 0 };
+ let blob = prepare_blob(blob, &[]).unwrap();
write_legacy_blob(&mut file, blob).unwrap();
Ok(())
}
+}
- fn make_encrypted_ca_cert_file<P: AsRef<Path>>(path: P, key: &[u8]) -> Result<()> {
- let mut file = OpenOptions::new().write(true).create_new(true).open(path).unwrap();
- let blob = Blob {
- value: BlobValue::Generic(LOADED_CACERT_AUTHBOUND.to_vec()),
- flags: flags::ENCRYPTED,
- };
- let blob = prepare_blob(blob, key).unwrap();
- write_legacy_blob(&mut file, blob).unwrap();
- Ok(())
- }
+#[cfg(test)]
+mod test {
+ #![allow(dead_code)]
+ use super::*;
+ use crate::legacy_blob::test_utils::legacy_blob_test_vectors::*;
+ use crate::legacy_blob::test_utils::*;
+ use anyhow::{anyhow, Result};
+ use keystore2_crypto::aes_gcm_decrypt;
+ use keystore2_test_utils::TempDir;
+ use rand::Rng;
+ use std::convert::TryInto;
+ use std::ops::Deref;
+ use std::string::FromUtf8Error;
#[test]
fn decode_encode_alias_test() {
@@ -1962,6 +2007,7 @@
make_encrypted_characteristics_file(
&*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
&super_key,
+ KEY_PARAMETERS,
)
.unwrap();
std::fs::write(
@@ -2053,11 +2099,13 @@
make_encrypted_usr_cert_file(
&*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
&super_key,
+ LOADED_CERT_AUTHBOUND,
)
.unwrap();
make_encrypted_ca_cert_file(
&*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
&super_key,
+ LOADED_CACERT_AUTHBOUND,
)
.unwrap();
@@ -2139,11 +2187,13 @@
make_encrypted_usr_cert_file(
&*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
&super_key,
+ LOADED_CERT_AUTHBOUND,
)
.unwrap();
make_encrypted_ca_cert_file(
&*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
&super_key,
+ LOADED_CACERT_AUTHBOUND,
)
.unwrap();