Adding RSA PKCS1 and EC SEC 1 formats to read_attestation_key
read_attestation_key now will try first to parse a key as if it was
a PKCS8 key, but if it fails it will try to parse an RSA key as a
PKCS1 encoded key and a EC key as a SEC 1 encoded key.
Bug: 258602662
Test: Build.py, run keymint TA unittests
Change-Id: I8ee45e3a8ea51e3cfd047dc797282a0c5e4de3eb
diff --git a/eckeysec1.key b/eckeysec1.key
new file mode 100644
index 0000000..80d27f6
--- /dev/null
+++ b/eckeysec1.key
Binary files differ
diff --git a/rsakeyrfc3447.key b/rsakeyrfc3447.key
new file mode 100644
index 0000000..27fa9ec
--- /dev/null
+++ b/rsakeyrfc3447.key
Binary files differ
diff --git a/secure_storage_manager.rs b/secure_storage_manager.rs
index 0c969b5..f04a713 100644
--- a/secure_storage_manager.rs
+++ b/secure_storage_manager.rs
@@ -370,6 +370,31 @@
Ok(pb)
}
+/// Tries to parse an EC private key as a SEC1 private EC key. If that fails, it tries to parse it
+/// as a PKCS#8 encoded key.
+fn import_ec_key(key_buffer: &[u8]) -> Result<KeyMaterial, Error> {
+ match crypto::ec::import_sec1_private_key(key_buffer) {
+ Ok(key_material) => Ok(key_material),
+ Err(e) => {
+ info!("couldn't parse as sec1 ECPrivateKey, will try as PKCS#8. Error {:?}", e);
+ crypto::ec::import_pkcs8_key(key_buffer)
+ }
+ }
+}
+
+/// Tries to parse an RSA key as a PKCS#1 encoded key. If that fails, it tries to parse it as a
+/// PKCS#8 one.
+fn import_rsa_key(key_buffer: &[u8]) -> Result<KeyMaterial, Error> {
+ match crypto::rsa::import_pkcs1_key(key_buffer) {
+ Ok((key_material, _, _)) => Ok(key_material),
+ Err(e) => {
+ info!("couldn't parse PKCS#1 RSA key, will try as PKCS#8. Error {:?}", e);
+ let (key_material, _, _) = crypto::rsa::import_pkcs8_key(key_buffer)?;
+ Ok(key_material)
+ }
+ }
+}
+
/// Retrieve the specified attestation key from the file in secure storage.
pub(crate) fn read_attestation_key(key_type: SigningKeyType) -> Result<KeyMaterial, Error> {
let mut attestation_key_pb: keymaster_attributes::AttestationKey =
@@ -379,15 +404,11 @@
return Err(km_err!(UnknownError, "attestation Key file found but it had no key"));
}
let key_buffer = attestation_key_pb.take_key();
- let key = match key_type.algo_hint {
- SigningAlgorithm::Ec => crypto::ec::import_pkcs8_key(key_buffer.as_slice())?,
- SigningAlgorithm::Rsa => {
- let (key_material, _key_size, _exponent) =
- crypto::rsa::import_pkcs8_key(key_buffer.as_slice())?;
- key_material
- }
- };
- Ok(key)
+
+ match key_type.algo_hint {
+ SigningAlgorithm::Ec => import_ec_key(&key_buffer),
+ SigningAlgorithm::Rsa => import_rsa_key(&key_buffer),
+ }
}
pub(crate) fn get_cert_chain(key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error> {
@@ -467,6 +488,12 @@
// openssl ecparam -name prime256v1 -genkey -outform der -out eckey2.key
// openssl pkcs8 -topk8 -in eckey2.key -outform der -nocrypt -out eckey.key
const EC_KEY: &'static [u8] = include_bytes!("eckey.key");
+ // Generated by:
+ // openssl genpkey -out rsakey2.key -outform DER -algorithm RSA -pkeyopt rsa_keygen_bits:2048
+ const RSA_KEY_PKCS1: &'static [u8] = include_bytes!("rsakeyrfc3447.key");
+ // Generated by:
+ // openssl ecparam -name prime256v1 -genkey -outform der -out eckey2.key
+ const EC_PRIVATE_KEY_SEC1: &'static [u8] = include_bytes!("eckeysec1.key");
fn delete_key_file(algorithm: SigningAlgorithm) {
let file_name = get_key_slot_file_name(algorithm);
@@ -569,6 +596,13 @@
}
}
+ fn get_non_pkcs8_test_key_data(algorithm: SigningAlgorithm) -> &'static [u8] {
+ match algorithm {
+ SigningAlgorithm::Rsa => RSA_KEY_PKCS1,
+ SigningAlgorithm::Ec => EC_PRIVATE_KEY_SEC1,
+ }
+ }
+
fn get_test_attestation_key(algorithm: SigningAlgorithm) -> Result<KeyMaterial, Error> {
let key_buffer = get_test_key_data(algorithm);
let key = match algorithm {
@@ -655,6 +689,28 @@
read_key_test(SigningAlgorithm::Ec);
}
+ fn read_non_pkcs8_key_test(algorithm: SigningAlgorithm) {
+ let test_key = get_non_pkcs8_test_key_data(algorithm);
+
+ provision_attestation_key_file(algorithm, test_key).expect("Couldn't provision key");
+
+ let key_type = SigningKeyType { which: SigningKey::Batch, algo_hint: algorithm };
+ let att_key = read_attestation_key(key_type);
+ expect!(att_key.is_ok(), "Couldn't read a non-pkcs8 key from storage");
+
+ delete_key_file(algorithm);
+ }
+
+ #[test]
+ fn read_sec1_private_ec_key() {
+ read_non_pkcs8_key_test(SigningAlgorithm::Ec);
+ }
+
+ #[test]
+ fn read_pkcs1_rsa_key() {
+ read_non_pkcs8_key_test(SigningAlgorithm::Rsa);
+ }
+
#[test]
fn unprovisioned_keys_certs_reads_produces_error() {
if check_key_file_exists(SigningAlgorithm::Ec) {