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) {