Implementing RetrieveCertSigningInfo and RetrieveAttestationIds traits
Implementing RetrieveCertSigningInfo and RetrieveAttestationIds traits
purely in Rust. For this we now depend on the protobuf crate.
Bug: 253906012, 253926844
Test: Build.py, run keymint TA unittests
Change-Id: I72fc1a5e282f3d3b0e8e8b599ecb287dfad5bbe9
diff --git a/eckey.key b/eckey.key
new file mode 100644
index 0000000..a2f245f
--- /dev/null
+++ b/eckey.key
Binary files differ
diff --git a/keymaster_attributes.rs b/keymaster_attributes.rs
new file mode 100644
index 0000000..be8ecbc
--- /dev/null
+++ b/keymaster_attributes.rs
@@ -0,0 +1,1298 @@
+// This file is generated by rust-protobuf 2.27.1. Do not edit
+// @generated
+
+// https://github.com/rust-lang/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![allow(unused_attributes)]
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `keymaster_attributes.proto`
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_27_1;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct KeymasterAttributes {
+ // message fields
+ uuid: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ product_id: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ // special fields
+ pub unknown_fields: ::protobuf::UnknownFields,
+ pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a KeymasterAttributes {
+ fn default() -> &'a KeymasterAttributes {
+ <KeymasterAttributes as ::protobuf::Message>::default_instance()
+ }
+}
+
+impl KeymasterAttributes {
+ pub fn new() -> KeymasterAttributes {
+ ::std::default::Default::default()
+ }
+
+ // optional bytes uuid = 1;
+
+
+ pub fn get_uuid(&self) -> &[u8] {
+ match self.uuid.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_uuid(&mut self) {
+ self.uuid.clear();
+ }
+
+ pub fn has_uuid(&self) -> bool {
+ self.uuid.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_uuid(&mut self, v: ::std::vec::Vec<u8>) {
+ self.uuid = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_uuid(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.uuid.is_none() {
+ self.uuid.set_default();
+ }
+ self.uuid.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_uuid(&mut self) -> ::std::vec::Vec<u8> {
+ self.uuid.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes product_id = 2;
+
+
+ pub fn get_product_id(&self) -> &[u8] {
+ match self.product_id.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_product_id(&mut self) {
+ self.product_id.clear();
+ }
+
+ pub fn has_product_id(&self) -> bool {
+ self.product_id.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_product_id(&mut self, v: ::std::vec::Vec<u8>) {
+ self.product_id = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_product_id(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.product_id.is_none() {
+ self.product_id.set_default();
+ }
+ self.product_id.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_product_id(&mut self) -> ::std::vec::Vec<u8> {
+ self.product_id.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+}
+
+impl ::protobuf::Message for KeymasterAttributes {
+ fn is_initialized(&self) -> bool {
+ true
+ }
+
+ fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ while !is.eof()? {
+ let (field_number, wire_type) = is.read_tag_unpack()?;
+ match field_number {
+ 1 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.uuid)?;
+ },
+ 2 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.product_id)?;
+ },
+ _ => {
+ ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+ },
+ };
+ }
+ ::std::result::Result::Ok(())
+ }
+
+ // Compute sizes of nested messages
+ #[allow(unused_variables)]
+ fn compute_size(&self) -> u32 {
+ let mut my_size = 0;
+ if let Some(ref v) = self.uuid.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(1, &v);
+ }
+ if let Some(ref v) = self.product_id.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(2, &v);
+ }
+ my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+ self.cached_size.set(my_size);
+ my_size
+ }
+
+ fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ if let Some(ref v) = self.uuid.as_ref() {
+ os.write_bytes(1, &v)?;
+ }
+ if let Some(ref v) = self.product_id.as_ref() {
+ os.write_bytes(2, &v)?;
+ }
+ os.write_unknown_fields(self.get_unknown_fields())?;
+ ::std::result::Result::Ok(())
+ }
+
+ fn get_cached_size(&self) -> u32 {
+ self.cached_size.get()
+ }
+
+ fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+ &self.unknown_fields
+ }
+
+ fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+ &mut self.unknown_fields
+ }
+
+ fn as_any(&self) -> &dyn (::std::any::Any) {
+ self as &dyn (::std::any::Any)
+ }
+ fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+ self as &mut dyn (::std::any::Any)
+ }
+ fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+ self
+ }
+
+ fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+ Self::descriptor_static()
+ }
+
+ fn new() -> KeymasterAttributes {
+ KeymasterAttributes::new()
+ }
+
+ fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+ static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+ descriptor.get(|| {
+ let mut fields = ::std::vec::Vec::new();
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "uuid",
+ |m: &KeymasterAttributes| { &m.uuid },
+ |m: &mut KeymasterAttributes| { &mut m.uuid },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "product_id",
+ |m: &KeymasterAttributes| { &m.product_id },
+ |m: &mut KeymasterAttributes| { &mut m.product_id },
+ ));
+ ::protobuf::reflect::MessageDescriptor::new_pb_name::<KeymasterAttributes>(
+ "KeymasterAttributes",
+ fields,
+ file_descriptor_proto()
+ )
+ })
+ }
+
+ fn default_instance() -> &'static KeymasterAttributes {
+ static instance: ::protobuf::rt::LazyV2<KeymasterAttributes> = ::protobuf::rt::LazyV2::INIT;
+ instance.get(KeymasterAttributes::new)
+ }
+}
+
+impl ::protobuf::Clear for KeymasterAttributes {
+ fn clear(&mut self) {
+ self.uuid.clear();
+ self.product_id.clear();
+ self.unknown_fields.clear();
+ }
+}
+
+impl ::std::fmt::Debug for KeymasterAttributes {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::protobuf::text_format::fmt(self, f)
+ }
+}
+
+impl ::protobuf::reflect::ProtobufValue for KeymasterAttributes {
+ fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+ ::protobuf::reflect::ReflectValueRef::Message(self)
+ }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct AttestationIds {
+ // message fields
+ brand: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ device: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ product: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ serial: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ imei: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ meid: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ manufacturer: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ model: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ // special fields
+ pub unknown_fields: ::protobuf::UnknownFields,
+ pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a AttestationIds {
+ fn default() -> &'a AttestationIds {
+ <AttestationIds as ::protobuf::Message>::default_instance()
+ }
+}
+
+impl AttestationIds {
+ pub fn new() -> AttestationIds {
+ ::std::default::Default::default()
+ }
+
+ // optional bytes brand = 1;
+
+
+ pub fn get_brand(&self) -> &[u8] {
+ match self.brand.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_brand(&mut self) {
+ self.brand.clear();
+ }
+
+ pub fn has_brand(&self) -> bool {
+ self.brand.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_brand(&mut self, v: ::std::vec::Vec<u8>) {
+ self.brand = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_brand(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.brand.is_none() {
+ self.brand.set_default();
+ }
+ self.brand.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_brand(&mut self) -> ::std::vec::Vec<u8> {
+ self.brand.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes device = 2;
+
+
+ pub fn get_device(&self) -> &[u8] {
+ match self.device.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_device(&mut self) {
+ self.device.clear();
+ }
+
+ pub fn has_device(&self) -> bool {
+ self.device.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_device(&mut self, v: ::std::vec::Vec<u8>) {
+ self.device = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_device(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.device.is_none() {
+ self.device.set_default();
+ }
+ self.device.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_device(&mut self) -> ::std::vec::Vec<u8> {
+ self.device.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes product = 3;
+
+
+ pub fn get_product(&self) -> &[u8] {
+ match self.product.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_product(&mut self) {
+ self.product.clear();
+ }
+
+ pub fn has_product(&self) -> bool {
+ self.product.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_product(&mut self, v: ::std::vec::Vec<u8>) {
+ self.product = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_product(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.product.is_none() {
+ self.product.set_default();
+ }
+ self.product.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_product(&mut self) -> ::std::vec::Vec<u8> {
+ self.product.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes serial = 4;
+
+
+ pub fn get_serial(&self) -> &[u8] {
+ match self.serial.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_serial(&mut self) {
+ self.serial.clear();
+ }
+
+ pub fn has_serial(&self) -> bool {
+ self.serial.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_serial(&mut self, v: ::std::vec::Vec<u8>) {
+ self.serial = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_serial(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.serial.is_none() {
+ self.serial.set_default();
+ }
+ self.serial.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_serial(&mut self) -> ::std::vec::Vec<u8> {
+ self.serial.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes imei = 5;
+
+
+ pub fn get_imei(&self) -> &[u8] {
+ match self.imei.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_imei(&mut self) {
+ self.imei.clear();
+ }
+
+ pub fn has_imei(&self) -> bool {
+ self.imei.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_imei(&mut self, v: ::std::vec::Vec<u8>) {
+ self.imei = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_imei(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.imei.is_none() {
+ self.imei.set_default();
+ }
+ self.imei.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_imei(&mut self) -> ::std::vec::Vec<u8> {
+ self.imei.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes meid = 6;
+
+
+ pub fn get_meid(&self) -> &[u8] {
+ match self.meid.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_meid(&mut self) {
+ self.meid.clear();
+ }
+
+ pub fn has_meid(&self) -> bool {
+ self.meid.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_meid(&mut self, v: ::std::vec::Vec<u8>) {
+ self.meid = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_meid(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.meid.is_none() {
+ self.meid.set_default();
+ }
+ self.meid.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_meid(&mut self) -> ::std::vec::Vec<u8> {
+ self.meid.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes manufacturer = 7;
+
+
+ pub fn get_manufacturer(&self) -> &[u8] {
+ match self.manufacturer.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_manufacturer(&mut self) {
+ self.manufacturer.clear();
+ }
+
+ pub fn has_manufacturer(&self) -> bool {
+ self.manufacturer.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_manufacturer(&mut self, v: ::std::vec::Vec<u8>) {
+ self.manufacturer = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_manufacturer(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.manufacturer.is_none() {
+ self.manufacturer.set_default();
+ }
+ self.manufacturer.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_manufacturer(&mut self) -> ::std::vec::Vec<u8> {
+ self.manufacturer.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // optional bytes model = 8;
+
+
+ pub fn get_model(&self) -> &[u8] {
+ match self.model.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_model(&mut self) {
+ self.model.clear();
+ }
+
+ pub fn has_model(&self) -> bool {
+ self.model.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_model(&mut self, v: ::std::vec::Vec<u8>) {
+ self.model = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_model(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.model.is_none() {
+ self.model.set_default();
+ }
+ self.model.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_model(&mut self) -> ::std::vec::Vec<u8> {
+ self.model.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+}
+
+impl ::protobuf::Message for AttestationIds {
+ fn is_initialized(&self) -> bool {
+ true
+ }
+
+ fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ while !is.eof()? {
+ let (field_number, wire_type) = is.read_tag_unpack()?;
+ match field_number {
+ 1 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.brand)?;
+ },
+ 2 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.device)?;
+ },
+ 3 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.product)?;
+ },
+ 4 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.serial)?;
+ },
+ 5 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.imei)?;
+ },
+ 6 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.meid)?;
+ },
+ 7 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.manufacturer)?;
+ },
+ 8 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.model)?;
+ },
+ _ => {
+ ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+ },
+ };
+ }
+ ::std::result::Result::Ok(())
+ }
+
+ // Compute sizes of nested messages
+ #[allow(unused_variables)]
+ fn compute_size(&self) -> u32 {
+ let mut my_size = 0;
+ if let Some(ref v) = self.brand.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(1, &v);
+ }
+ if let Some(ref v) = self.device.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(2, &v);
+ }
+ if let Some(ref v) = self.product.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(3, &v);
+ }
+ if let Some(ref v) = self.serial.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(4, &v);
+ }
+ if let Some(ref v) = self.imei.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(5, &v);
+ }
+ if let Some(ref v) = self.meid.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(6, &v);
+ }
+ if let Some(ref v) = self.manufacturer.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(7, &v);
+ }
+ if let Some(ref v) = self.model.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(8, &v);
+ }
+ my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+ self.cached_size.set(my_size);
+ my_size
+ }
+
+ fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ if let Some(ref v) = self.brand.as_ref() {
+ os.write_bytes(1, &v)?;
+ }
+ if let Some(ref v) = self.device.as_ref() {
+ os.write_bytes(2, &v)?;
+ }
+ if let Some(ref v) = self.product.as_ref() {
+ os.write_bytes(3, &v)?;
+ }
+ if let Some(ref v) = self.serial.as_ref() {
+ os.write_bytes(4, &v)?;
+ }
+ if let Some(ref v) = self.imei.as_ref() {
+ os.write_bytes(5, &v)?;
+ }
+ if let Some(ref v) = self.meid.as_ref() {
+ os.write_bytes(6, &v)?;
+ }
+ if let Some(ref v) = self.manufacturer.as_ref() {
+ os.write_bytes(7, &v)?;
+ }
+ if let Some(ref v) = self.model.as_ref() {
+ os.write_bytes(8, &v)?;
+ }
+ os.write_unknown_fields(self.get_unknown_fields())?;
+ ::std::result::Result::Ok(())
+ }
+
+ fn get_cached_size(&self) -> u32 {
+ self.cached_size.get()
+ }
+
+ fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+ &self.unknown_fields
+ }
+
+ fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+ &mut self.unknown_fields
+ }
+
+ fn as_any(&self) -> &dyn (::std::any::Any) {
+ self as &dyn (::std::any::Any)
+ }
+ fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+ self as &mut dyn (::std::any::Any)
+ }
+ fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+ self
+ }
+
+ fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+ Self::descriptor_static()
+ }
+
+ fn new() -> AttestationIds {
+ AttestationIds::new()
+ }
+
+ fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+ static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+ descriptor.get(|| {
+ let mut fields = ::std::vec::Vec::new();
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "brand",
+ |m: &AttestationIds| { &m.brand },
+ |m: &mut AttestationIds| { &mut m.brand },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "device",
+ |m: &AttestationIds| { &m.device },
+ |m: &mut AttestationIds| { &mut m.device },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "product",
+ |m: &AttestationIds| { &m.product },
+ |m: &mut AttestationIds| { &mut m.product },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "serial",
+ |m: &AttestationIds| { &m.serial },
+ |m: &mut AttestationIds| { &mut m.serial },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "imei",
+ |m: &AttestationIds| { &m.imei },
+ |m: &mut AttestationIds| { &mut m.imei },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "meid",
+ |m: &AttestationIds| { &m.meid },
+ |m: &mut AttestationIds| { &mut m.meid },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "manufacturer",
+ |m: &AttestationIds| { &m.manufacturer },
+ |m: &mut AttestationIds| { &mut m.manufacturer },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "model",
+ |m: &AttestationIds| { &m.model },
+ |m: &mut AttestationIds| { &mut m.model },
+ ));
+ ::protobuf::reflect::MessageDescriptor::new_pb_name::<AttestationIds>(
+ "AttestationIds",
+ fields,
+ file_descriptor_proto()
+ )
+ })
+ }
+
+ fn default_instance() -> &'static AttestationIds {
+ static instance: ::protobuf::rt::LazyV2<AttestationIds> = ::protobuf::rt::LazyV2::INIT;
+ instance.get(AttestationIds::new)
+ }
+}
+
+impl ::protobuf::Clear for AttestationIds {
+ fn clear(&mut self) {
+ self.brand.clear();
+ self.device.clear();
+ self.product.clear();
+ self.serial.clear();
+ self.imei.clear();
+ self.meid.clear();
+ self.manufacturer.clear();
+ self.model.clear();
+ self.unknown_fields.clear();
+ }
+}
+
+impl ::std::fmt::Debug for AttestationIds {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::protobuf::text_format::fmt(self, f)
+ }
+}
+
+impl ::protobuf::reflect::ProtobufValue for AttestationIds {
+ fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+ ::protobuf::reflect::ReflectValueRef::Message(self)
+ }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct AttestationKey {
+ // message fields
+ key: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ pub certs: ::protobuf::RepeatedField<AttestationCert>,
+ // special fields
+ pub unknown_fields: ::protobuf::UnknownFields,
+ pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a AttestationKey {
+ fn default() -> &'a AttestationKey {
+ <AttestationKey as ::protobuf::Message>::default_instance()
+ }
+}
+
+impl AttestationKey {
+ pub fn new() -> AttestationKey {
+ ::std::default::Default::default()
+ }
+
+ // optional bytes key = 1;
+
+
+ pub fn get_key(&self) -> &[u8] {
+ match self.key.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_key(&mut self) {
+ self.key.clear();
+ }
+
+ pub fn has_key(&self) -> bool {
+ self.key.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_key(&mut self, v: ::std::vec::Vec<u8>) {
+ self.key = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_key(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.key.is_none() {
+ self.key.set_default();
+ }
+ self.key.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_key(&mut self) -> ::std::vec::Vec<u8> {
+ self.key.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
+ // repeated .AttestationCert certs = 2;
+
+
+ pub fn get_certs(&self) -> &[AttestationCert] {
+ &self.certs
+ }
+ pub fn clear_certs(&mut self) {
+ self.certs.clear();
+ }
+
+ // Param is passed by value, moved
+ pub fn set_certs(&mut self, v: ::protobuf::RepeatedField<AttestationCert>) {
+ self.certs = v;
+ }
+
+ // Mutable pointer to the field.
+ pub fn mut_certs(&mut self) -> &mut ::protobuf::RepeatedField<AttestationCert> {
+ &mut self.certs
+ }
+
+ // Take field
+ pub fn take_certs(&mut self) -> ::protobuf::RepeatedField<AttestationCert> {
+ ::std::mem::replace(&mut self.certs, ::protobuf::RepeatedField::new())
+ }
+}
+
+impl ::protobuf::Message for AttestationKey {
+ fn is_initialized(&self) -> bool {
+ for v in &self.certs {
+ if !v.is_initialized() {
+ return false;
+ }
+ };
+ true
+ }
+
+ fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ while !is.eof()? {
+ let (field_number, wire_type) = is.read_tag_unpack()?;
+ match field_number {
+ 1 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.key)?;
+ },
+ 2 => {
+ ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.certs)?;
+ },
+ _ => {
+ ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+ },
+ };
+ }
+ ::std::result::Result::Ok(())
+ }
+
+ // Compute sizes of nested messages
+ #[allow(unused_variables)]
+ fn compute_size(&self) -> u32 {
+ let mut my_size = 0;
+ if let Some(ref v) = self.key.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(1, &v);
+ }
+ for value in &self.certs {
+ let len = value.compute_size();
+ my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+ };
+ my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+ self.cached_size.set(my_size);
+ my_size
+ }
+
+ fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ if let Some(ref v) = self.key.as_ref() {
+ os.write_bytes(1, &v)?;
+ }
+ for v in &self.certs {
+ os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+ os.write_raw_varint32(v.get_cached_size())?;
+ v.write_to_with_cached_sizes(os)?;
+ };
+ os.write_unknown_fields(self.get_unknown_fields())?;
+ ::std::result::Result::Ok(())
+ }
+
+ fn get_cached_size(&self) -> u32 {
+ self.cached_size.get()
+ }
+
+ fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+ &self.unknown_fields
+ }
+
+ fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+ &mut self.unknown_fields
+ }
+
+ fn as_any(&self) -> &dyn (::std::any::Any) {
+ self as &dyn (::std::any::Any)
+ }
+ fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+ self as &mut dyn (::std::any::Any)
+ }
+ fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+ self
+ }
+
+ fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+ Self::descriptor_static()
+ }
+
+ fn new() -> AttestationKey {
+ AttestationKey::new()
+ }
+
+ fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+ static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+ descriptor.get(|| {
+ let mut fields = ::std::vec::Vec::new();
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "key",
+ |m: &AttestationKey| { &m.key },
+ |m: &mut AttestationKey| { &mut m.key },
+ ));
+ fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<AttestationCert>>(
+ "certs",
+ |m: &AttestationKey| { &m.certs },
+ |m: &mut AttestationKey| { &mut m.certs },
+ ));
+ ::protobuf::reflect::MessageDescriptor::new_pb_name::<AttestationKey>(
+ "AttestationKey",
+ fields,
+ file_descriptor_proto()
+ )
+ })
+ }
+
+ fn default_instance() -> &'static AttestationKey {
+ static instance: ::protobuf::rt::LazyV2<AttestationKey> = ::protobuf::rt::LazyV2::INIT;
+ instance.get(AttestationKey::new)
+ }
+}
+
+impl ::protobuf::Clear for AttestationKey {
+ fn clear(&mut self) {
+ self.key.clear();
+ self.certs.clear();
+ self.unknown_fields.clear();
+ }
+}
+
+impl ::std::fmt::Debug for AttestationKey {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::protobuf::text_format::fmt(self, f)
+ }
+}
+
+impl ::protobuf::reflect::ProtobufValue for AttestationKey {
+ fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+ ::protobuf::reflect::ReflectValueRef::Message(self)
+ }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct AttestationCert {
+ // message fields
+ content: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+ // special fields
+ pub unknown_fields: ::protobuf::UnknownFields,
+ pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a AttestationCert {
+ fn default() -> &'a AttestationCert {
+ <AttestationCert as ::protobuf::Message>::default_instance()
+ }
+}
+
+impl AttestationCert {
+ pub fn new() -> AttestationCert {
+ ::std::default::Default::default()
+ }
+
+ // required bytes content = 1;
+
+
+ pub fn get_content(&self) -> &[u8] {
+ match self.content.as_ref() {
+ Some(v) => &v,
+ None => &[],
+ }
+ }
+ pub fn clear_content(&mut self) {
+ self.content.clear();
+ }
+
+ pub fn has_content(&self) -> bool {
+ self.content.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_content(&mut self, v: ::std::vec::Vec<u8>) {
+ self.content = ::protobuf::SingularField::some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_content(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.content.is_none() {
+ self.content.set_default();
+ }
+ self.content.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_content(&mut self) -> ::std::vec::Vec<u8> {
+ self.content.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+}
+
+impl ::protobuf::Message for AttestationCert {
+ fn is_initialized(&self) -> bool {
+ if self.content.is_none() {
+ return false;
+ }
+ true
+ }
+
+ fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ while !is.eof()? {
+ let (field_number, wire_type) = is.read_tag_unpack()?;
+ match field_number {
+ 1 => {
+ ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.content)?;
+ },
+ _ => {
+ ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+ },
+ };
+ }
+ ::std::result::Result::Ok(())
+ }
+
+ // Compute sizes of nested messages
+ #[allow(unused_variables)]
+ fn compute_size(&self) -> u32 {
+ let mut my_size = 0;
+ if let Some(ref v) = self.content.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(1, &v);
+ }
+ my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+ self.cached_size.set(my_size);
+ my_size
+ }
+
+ fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+ if let Some(ref v) = self.content.as_ref() {
+ os.write_bytes(1, &v)?;
+ }
+ os.write_unknown_fields(self.get_unknown_fields())?;
+ ::std::result::Result::Ok(())
+ }
+
+ fn get_cached_size(&self) -> u32 {
+ self.cached_size.get()
+ }
+
+ fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+ &self.unknown_fields
+ }
+
+ fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+ &mut self.unknown_fields
+ }
+
+ fn as_any(&self) -> &dyn (::std::any::Any) {
+ self as &dyn (::std::any::Any)
+ }
+ fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+ self as &mut dyn (::std::any::Any)
+ }
+ fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+ self
+ }
+
+ fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+ Self::descriptor_static()
+ }
+
+ fn new() -> AttestationCert {
+ AttestationCert::new()
+ }
+
+ fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+ static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+ descriptor.get(|| {
+ let mut fields = ::std::vec::Vec::new();
+ fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+ "content",
+ |m: &AttestationCert| { &m.content },
+ |m: &mut AttestationCert| { &mut m.content },
+ ));
+ ::protobuf::reflect::MessageDescriptor::new_pb_name::<AttestationCert>(
+ "AttestationCert",
+ fields,
+ file_descriptor_proto()
+ )
+ })
+ }
+
+ fn default_instance() -> &'static AttestationCert {
+ static instance: ::protobuf::rt::LazyV2<AttestationCert> = ::protobuf::rt::LazyV2::INIT;
+ instance.get(AttestationCert::new)
+ }
+}
+
+impl ::protobuf::Clear for AttestationCert {
+ fn clear(&mut self) {
+ self.content.clear();
+ self.unknown_fields.clear();
+ }
+}
+
+impl ::std::fmt::Debug for AttestationCert {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::protobuf::text_format::fmt(self, f)
+ }
+}
+
+impl ::protobuf::reflect::ProtobufValue for AttestationCert {
+ fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+ ::protobuf::reflect::ReflectValueRef::Message(self)
+ }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+ \n\x1akeymaster_attributes.proto\x1a\x0cnanopb.proto\"V\n\x13KeymasterAt\
+ tributes\x12\x19\n\x04uuid\x18\x01\x20\x01(\x0cR\x04uuidB\x05\x92?\x02\
+ \x08\x20\x12$\n\nproduct_id\x18\x02\x20\x01(\x0cR\tproductIdB\x05\x92?\
+ \x02\x08\x10\"\x8a\x02\n\x0eAttestationIds\x12\x1b\n\x05brand\x18\x01\
+ \x20\x01(\x0cR\x05brandB\x05\x92?\x02\x08@\x12\x1d\n\x06device\x18\x02\
+ \x20\x01(\x0cR\x06deviceB\x05\x92?\x02\x08@\x12\x1f\n\x07product\x18\x03\
+ \x20\x01(\x0cR\x07productB\x05\x92?\x02\x08@\x12\x1d\n\x06serial\x18\x04\
+ \x20\x01(\x0cR\x06serialB\x05\x92?\x02\x08@\x12\x19\n\x04imei\x18\x05\
+ \x20\x01(\x0cR\x04imeiB\x05\x92?\x02\x08@\x12\x19\n\x04meid\x18\x06\x20\
+ \x01(\x0cR\x04meidB\x05\x92?\x02\x08@\x12)\n\x0cmanufacturer\x18\x07\x20\
+ \x01(\x0cR\x0cmanufacturerB\x05\x92?\x02\x08@\x12\x1b\n\x05model\x18\x08\
+ \x20\x01(\x0cR\x05modelB\x05\x92?\x02\x08@\"Y\n\x0eAttestationKey\x12\
+ \x18\n\x03key\x18\x01\x20\x01(\x0cR\x03keyB\x06\x92?\x03\x08\x80\x10\x12\
+ -\n\x05certs\x18\x02\x20\x03(\x0b2\x10.AttestationCertR\x05certsB\x05\
+ \x92?\x02\x10\x03\"3\n\x0fAttestationCert\x12\x20\n\x07content\x18\x01\
+ \x20\x02(\x0cR\x07contentB\x06\x92?\x03\x08\x80\x10J\xb0\x17\n\x06\x12\
+ \x04%\0@\x02\n\xa6\x0c\n\x01\x0c\x12\x03%\0\x122\xcc\x04\n\x20Copyright\
+ \x20(C)\x202018\x20The\x20Android\x20Open\x20Source\x20Project\n\n\x20Li\
+ censed\x20under\x20the\x20Apache\x20License,\x20Version\x202.0\x20(the\
+ \x20\"License\");\n\x20you\x20may\x20not\x20use\x20this\x20file\x20excep\
+ t\x20in\x20compliance\x20with\x20the\x20License.\n\x20You\x20may\x20obta\
+ in\x20a\x20copy\x20of\x20the\x20License\x20at\n\n\x20\x20\x20\x20\x20\
+ \x20http://www.apache.org/licenses/LICENSE-2.0\n\n\x20Unless\x20required\
+ \x20by\x20applicable\x20law\x20or\x20agreed\x20to\x20in\x20writing,\x20s\
+ oftware\n\x20distributed\x20under\x20the\x20License\x20is\x20distributed\
+ \x20on\x20an\x20\"AS\x20IS\"\x20BASIS,\n\x20WITHOUT\x20WARRANTIES\x20OR\
+ \x20CONDITIONS\x20OF\x20ANY\x20KIND,\x20either\x20express\x20or\x20impli\
+ ed.\n\x20See\x20the\x20License\x20for\x20the\x20specific\x20language\x20\
+ governing\x20permissions\x20and\n\x20limitations\x20under\x20the\x20Lice\
+ nse.\n2\xcc\x07\x20We\x20check\x20in\x20the\x20prebuilt\x20nanopb\x20pro\
+ tobuf\x20file\x20under\x20the\x20current\x20folder\n\x20because\x20the\
+ \x20compile\x20tool\x20chain\x20using\x20trusty/user/base/make/compile_p\
+ roto.mk\n\x20might\x20not\x20work\x20under\x20certain\x20environment\x20\
+ with\x20lower\x20version\x20of\x20python\n\x20protobuf\x20installed.\x20\
+ You\x20need\x20to\x20generate\x20and\x20check\x20in\x20the\x20new\x20pro\
+ tobuf\x20file\n\x20if\x20you\x20change\x20this\x20file\x20in\x20order\
+ \x20for\x20the\x20change\x20to\x20take\x20effect!\n\n\x20To\x20generate\
+ \x20the\x20file\x20using\x20the\x20tool\x20chain\x20in\x20trusty\x20tree\
+ ,\x20add\x20the\x20following\n\x20command\x20to\x20rules.mk:\n\n\x20PB_G\
+ EN_DIR\x20:=\x20[Your\x20generation\x20folder]\n\x20include\x20trusty/us\
+ er/base/make/compile_proto.mk\n\x20$(eval\x20$(call\x20compile_proto,$(K\
+ EYMASTER_DIR)/keymaster_attributes.proto,$(PB_GEN_DIR)))\n\n\x20The\x20g\
+ enerated\x20.pb.c\x20and\x20.pb.h\x20file\x20would\x20be\x20under\x20PB_\
+ GEN_DIR,\x20include\x20them\n\x20to\x20the\x20source\x20path.\n\n\x20To\
+ \x20generate\x20the\x20file\x20using\x20your\x20own\x20tool\x20chain,\
+ \x20please\x20follow\x20the\x20guide\x20at\n\x20https://github.com/nanop\
+ b/nanopb.\n\x20Please\x20check\x20the\x20nanopb\x20version\x20in\x20trus\
+ ty\x20tree\x20at\x20external/nanopb-c\x20to\x20make\n\x20sure\x20you\x20\
+ are\x20using\x20the\x20same\x20nanopb\x20version.\n\n\t\n\x02\x03\0\x12\
+ \x03'\x07\x15\n\n\n\x02\x04\0\x12\x04)\0,\x01\n\n\n\x03\x04\0\x01\x12\
+ \x03)\x08\x1b\n\x0b\n\x04\x04\0\x02\0\x12\x03*\x021\n\x0c\n\x05\x04\0\
+ \x02\0\x04\x12\x03*\x02\n\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03*\x0b\x10\n\
+ \x0c\n\x05\x04\0\x02\0\x01\x12\x03*\x11\x15\n\x0c\n\x05\x04\0\x02\0\x03\
+ \x12\x03*\x18\x19\n\x0c\n\x05\x04\0\x02\0\x08\x12\x03*\x1a0\n\x0f\n\x08\
+ \x04\0\x02\0\x08\xf2\x07\x01\x12\x03*\x1b/\n\x0b\n\x04\x04\0\x02\x01\x12\
+ \x03+\x027\n\x0c\n\x05\x04\0\x02\x01\x04\x12\x03+\x02\n\n\x0c\n\x05\x04\
+ \0\x02\x01\x05\x12\x03+\x0b\x10\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03+\
+ \x11\x1b\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03+\x1e\x1f\n\x0c\n\x05\x04\
+ \0\x02\x01\x08\x12\x03+\x206\n\x0f\n\x08\x04\0\x02\x01\x08\xf2\x07\x01\
+ \x12\x03+!5\n\n\n\x02\x04\x01\x12\x04.\07\x01\n\n\n\x03\x04\x01\x01\x12\
+ \x03.\x08\x16\n\x0b\n\x04\x04\x01\x02\0\x12\x03/\x044\n\x0c\n\x05\x04\
+ \x01\x02\0\x04\x12\x03/\x04\x0c\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03/\r\
+ \x12\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03/\x13\x18\n\x0c\n\x05\x04\x01\
+ \x02\0\x03\x12\x03/\x1b\x1c\n\x0c\n\x05\x04\x01\x02\0\x08\x12\x03/\x1d3\
+ \n\x0f\n\x08\x04\x01\x02\0\x08\xf2\x07\x01\x12\x03/\x1e2\n\x0b\n\x04\x04\
+ \x01\x02\x01\x12\x030\x045\n\x0c\n\x05\x04\x01\x02\x01\x04\x12\x030\x04\
+ \x0c\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x030\r\x12\n\x0c\n\x05\x04\x01\
+ \x02\x01\x01\x12\x030\x13\x19\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x030\
+ \x1c\x1d\n\x0c\n\x05\x04\x01\x02\x01\x08\x12\x030\x1e4\n\x0f\n\x08\x04\
+ \x01\x02\x01\x08\xf2\x07\x01\x12\x030\x1f3\n\x0b\n\x04\x04\x01\x02\x02\
+ \x12\x031\x046\n\x0c\n\x05\x04\x01\x02\x02\x04\x12\x031\x04\x0c\n\x0c\n\
+ \x05\x04\x01\x02\x02\x05\x12\x031\r\x12\n\x0c\n\x05\x04\x01\x02\x02\x01\
+ \x12\x031\x13\x1a\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x031\x1d\x1e\n\x0c\
+ \n\x05\x04\x01\x02\x02\x08\x12\x031\x1f5\n\x0f\n\x08\x04\x01\x02\x02\x08\
+ \xf2\x07\x01\x12\x031\x204\n\x0b\n\x04\x04\x01\x02\x03\x12\x032\x045\n\
+ \x0c\n\x05\x04\x01\x02\x03\x04\x12\x032\x04\x0c\n\x0c\n\x05\x04\x01\x02\
+ \x03\x05\x12\x032\r\x12\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x032\x13\x19\
+ \n\x0c\n\x05\x04\x01\x02\x03\x03\x12\x032\x1c\x1d\n\x0c\n\x05\x04\x01\
+ \x02\x03\x08\x12\x032\x1e4\n\x0f\n\x08\x04\x01\x02\x03\x08\xf2\x07\x01\
+ \x12\x032\x1f3\n\x0b\n\x04\x04\x01\x02\x04\x12\x033\x043\n\x0c\n\x05\x04\
+ \x01\x02\x04\x04\x12\x033\x04\x0c\n\x0c\n\x05\x04\x01\x02\x04\x05\x12\
+ \x033\r\x12\n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x033\x13\x17\n\x0c\n\x05\
+ \x04\x01\x02\x04\x03\x12\x033\x1a\x1b\n\x0c\n\x05\x04\x01\x02\x04\x08\
+ \x12\x033\x1c2\n\x0f\n\x08\x04\x01\x02\x04\x08\xf2\x07\x01\x12\x033\x1d1\
+ \n\x0b\n\x04\x04\x01\x02\x05\x12\x034\x043\n\x0c\n\x05\x04\x01\x02\x05\
+ \x04\x12\x034\x04\x0c\n\x0c\n\x05\x04\x01\x02\x05\x05\x12\x034\r\x12\n\
+ \x0c\n\x05\x04\x01\x02\x05\x01\x12\x034\x13\x17\n\x0c\n\x05\x04\x01\x02\
+ \x05\x03\x12\x034\x1a\x1b\n\x0c\n\x05\x04\x01\x02\x05\x08\x12\x034\x1c2\
+ \n\x0f\n\x08\x04\x01\x02\x05\x08\xf2\x07\x01\x12\x034\x1d1\n\x0b\n\x04\
+ \x04\x01\x02\x06\x12\x035\x04;\n\x0c\n\x05\x04\x01\x02\x06\x04\x12\x035\
+ \x04\x0c\n\x0c\n\x05\x04\x01\x02\x06\x05\x12\x035\r\x12\n\x0c\n\x05\x04\
+ \x01\x02\x06\x01\x12\x035\x13\x1f\n\x0c\n\x05\x04\x01\x02\x06\x03\x12\
+ \x035\"#\n\x0c\n\x05\x04\x01\x02\x06\x08\x12\x035$:\n\x0f\n\x08\x04\x01\
+ \x02\x06\x08\xf2\x07\x01\x12\x035%9\n\x0b\n\x04\x04\x01\x02\x07\x12\x036\
+ \x044\n\x0c\n\x05\x04\x01\x02\x07\x04\x12\x036\x04\x0c\n\x0c\n\x05\x04\
+ \x01\x02\x07\x05\x12\x036\r\x12\n\x0c\n\x05\x04\x01\x02\x07\x01\x12\x036\
+ \x13\x18\n\x0c\n\x05\x04\x01\x02\x07\x03\x12\x036\x1b\x1c\n\x0c\n\x05\
+ \x04\x01\x02\x07\x08\x12\x036\x1d3\n\x0f\n\x08\x04\x01\x02\x07\x08\xf2\
+ \x07\x01\x12\x036\x1e2\n\n\n\x02\x04\x02\x12\x049\0<\x01\n\n\n\x03\x04\
+ \x02\x01\x12\x039\x08\x16\n\x0b\n\x04\x04\x02\x02\0\x12\x03:\x022\n\x0c\
+ \n\x05\x04\x02\x02\0\x04\x12\x03:\x02\n\n\x0c\n\x05\x04\x02\x02\0\x05\
+ \x12\x03:\x0b\x10\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03:\x11\x14\n\x0c\n\
+ \x05\x04\x02\x02\0\x03\x12\x03:\x17\x18\n\x0c\n\x05\x04\x02\x02\0\x08\
+ \x12\x03:\x191\n\x0f\n\x08\x04\x02\x02\0\x08\xf2\x07\x01\x12\x03:\x1a0\n\
+ \x0b\n\x04\x04\x02\x02\x01\x12\x03;\x02<\n\x0c\n\x05\x04\x02\x02\x01\x04\
+ \x12\x03;\x02\n\n\x0c\n\x05\x04\x02\x02\x01\x06\x12\x03;\x0b\x1a\n\x0c\n\
+ \x05\x04\x02\x02\x01\x01\x12\x03;\x1b\x20\n\x0c\n\x05\x04\x02\x02\x01\
+ \x03\x12\x03;#$\n\x0c\n\x05\x04\x02\x02\x01\x08\x12\x03;%;\n\x0f\n\x08\
+ \x04\x02\x02\x01\x08\xf2\x07\x02\x12\x03;&:\n\n\n\x02\x04\x03\x12\x04>\0\
+ @\x01\n\n\n\x03\x04\x03\x01\x12\x03>\x08\x17\n\x0b\n\x04\x04\x03\x02\0\
+ \x12\x03?\x026\n\x0c\n\x05\x04\x03\x02\0\x04\x12\x03?\x02\n\n\x0c\n\x05\
+ \x04\x03\x02\0\x05\x12\x03?\x0b\x10\n\x0c\n\x05\x04\x03\x02\0\x01\x12\
+ \x03?\x11\x18\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03?\x1b\x1c\n\x0c\n\x05\
+ \x04\x03\x02\0\x08\x12\x03?\x1d5\n\x0f\n\x08\x04\x03\x02\0\x08\xf2\x07\
+ \x01\x12\x03?\x1e4\
+";
+
+static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+ ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+ file_descriptor_proto_lazy.get(|| {
+ parse_descriptor_proto()
+ })
+}
diff --git a/lib.rs b/lib.rs
index 94980ba..e93003d 100644
--- a/lib.rs
+++ b/lib.rs
@@ -20,9 +20,12 @@
use kmr_ta;
+mod keymaster_attributes;
mod keys;
+mod secure_storage_manager;
pub use keys::TrustyKeys;
+pub use secure_storage_manager::{AttestationIds, CertSignInfo};
// TODO: maintain the bootloader status and update it as the bootloader informs
// Trusty when it is done.
diff --git a/main.rs b/main.rs
index fd6ec4b..3648a06 100644
--- a/main.rs
+++ b/main.rs
@@ -15,6 +15,7 @@
*/
use alloc::vec::Vec;
use core::cell::RefCell;
+use keymint::{AttestationIds, CertSignInfo, TrustyKeys};
use kmr_common::crypto;
use kmr_crypto_boring::{
aes::BoringAes, aes_cmac::BoringAesCmac, des::BoringDes, ec::BoringEc, eq::BoringEq,
@@ -126,12 +127,14 @@
ckdf: &BoringAesCmac,
hkdf: &BoringHmac,
};
-
+ let sign_info = CertSignInfo;
+ let mut att_ids = AttestationIds;
+ let trusty_keys = TrustyKeys;
// TODO: replace no-ops with actual implementations
let dev = kmr_ta::device::Implementation {
- keys: &kmr_ta::device::NoOpRetrieveKeyMaterial,
- sign_info: &kmr_ta::device::NoOpRetrieveCertSigningInfo,
- attest_ids: None,
+ keys: &trusty_keys,
+ sign_info: &sign_info,
+ attest_ids: Some(&mut att_ids),
sdd_mgr: None,
bootloader: &kmr_ta::device::BootloaderDone,
sk_wrapper: None,
diff --git a/rsakey.key b/rsakey.key
new file mode 100644
index 0000000..f39d187
--- /dev/null
+++ b/rsakey.key
Binary files differ
diff --git a/rules.mk b/rules.mk
index 28353f4..17796ac 100644
--- a/rules.mk
+++ b/rules.mk
@@ -30,6 +30,8 @@
trusty/user/base/lib/keymint-rust/common \
trusty/user/base/lib/keymint-rust/ta \
trusty/user/base/lib/log-rust \
+ trusty/user/base/lib/protobuf-rust \
+ trusty/user/base/lib/storage/rust \
trusty/user/base/lib/tipc/rust \
trusty/user/base/lib/trusty-log \
trusty/user/base/lib/trusty-std \
diff --git a/secure_storage_manager.rs b/secure_storage_manager.rs
new file mode 100644
index 0000000..a1e3bb5
--- /dev/null
+++ b/secure_storage_manager.rs
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+//! Module used to interact with keymint secure storage data.
+use alloc::{format, string::String, vec::Vec};
+use kmr_common::{
+ crypto::{self, KeyMaterial},
+ km_err, vec_try, vec_try_with_capacity,
+ wire::keymint::{self, ErrorCode},
+ wire::AttestationIdInfo,
+ Error,
+};
+use kmr_ta::device::{
+ RetrieveAttestationIds, RetrieveCertSigningInfo, SigningAlgorithm, SigningKeyType,
+};
+use storage::{OpenMode, Port, SecureFile, Session};
+
+use protobuf::{self, Message};
+
+use crate::keymaster_attributes;
+
+const KM_ATTESTATION_ID_FILENAME: &'static str = "AttestationIds";
+
+const KM_ATTESTATION_KEY_CERT_PREFIX: &'static str = "AttestKeyCert";
+
+fn get_key_slot_file_name(algorithm: SigningAlgorithm) -> String {
+ let suffix = match algorithm {
+ SigningAlgorithm::Ec => "ec",
+ SigningAlgorithm::Rsa => "rsa",
+ };
+ format!("{}.{}", KM_ATTESTATION_KEY_CERT_PREFIX, suffix)
+}
+
+pub(crate) fn delete_attestation_ids() -> Result<(), Error> {
+ let mut session = Session::new(Port::TamperProof, true)
+ .map_err(|_| km_err!(SecureHwCommunicationFailed, "Failed to connect to storage port"))?;
+ session
+ .remove(KM_ATTESTATION_ID_FILENAME)
+ .map_err(|_| km_err!(SecureHwCommunicationFailed, "Couldn't delete atestation IDs file"))?;
+ Ok(())
+}
+
+fn get_file_contents(file_name: &str) -> Result<Vec<u8>, Error> {
+ let mut session = Session::new(Port::TamperProof, true)
+ .map_err(|_| km_err!(SecureHwCommunicationFailed, "Failed to connect to storage port"))?;
+ let file = session
+ .open_file(file_name, OpenMode::Open)
+ .map_err(|_| km_err!(SecureHwCommunicationFailed, "Couldn't open {}", file_name))?;
+ let size = session
+ .get_size(&file)
+ .map_err(|_| km_err!(SecureHwCommunicationFailed, "Couldn't get {} size", file_name))?;
+ let mut buffer = vec_try![0; size]?;
+ let content = session
+ .read_all(&file, buffer.as_mut_slice())
+ .map_err(|_| km_err!(SecureHwCommunicationFailed, "Couldn't read {}", file_name))?;
+ let total_size = content.len();
+ buffer.resize(total_size, 0);
+ Ok(buffer)
+}
+
+pub(crate) fn read_attestation_ids() -> Result<AttestationIdInfo, Error> {
+ let content = get_file_contents(KM_ATTESTATION_ID_FILENAME)?;
+ let mut attestation_ids_pb: keymaster_attributes::AttestationIds =
+ Message::parse_from_bytes(content.as_slice())
+ .map_err(|_| km_err!(UnknownError, "Couldn't parse attestation IDs proto"))?;
+
+ let brand = attestation_ids_pb.take_brand();
+ let device = attestation_ids_pb.take_device();
+ let product = attestation_ids_pb.take_product();
+ let serial = attestation_ids_pb.take_serial();
+ let imei = attestation_ids_pb.take_imei();
+ let meid = attestation_ids_pb.take_meid();
+ let manufacturer = attestation_ids_pb.take_manufacturer();
+ let model = attestation_ids_pb.take_model();
+
+ Ok(AttestationIdInfo { brand, device, product, serial, imei, meid, manufacturer, model })
+}
+
+fn read_attestation_key_content(
+ key_type: SigningKeyType,
+) -> Result<keymaster_attributes::AttestationKey, Error> {
+ let file_name = get_key_slot_file_name(key_type.algo_hint);
+ let content = get_file_contents(&file_name)?;
+
+ let pb = Message::parse_from_bytes(content.as_slice())
+ .map_err(|_| km_err!(UnknownError, "Couldn't parse attestation key proto"))?;
+ Ok(pb)
+}
+
+pub(crate) fn read_attestation_key(key_type: SigningKeyType) -> Result<KeyMaterial, Error> {
+ let mut attestation_key_pb: keymaster_attributes::AttestationKey =
+ read_attestation_key_content(key_type)?;
+
+ if !(attestation_key_pb.has_key()) {
+ 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
+ }
+ };
+ // TODO: Do we need to support KEYMASTER_SOFT_ATTESTATION_FALLBACK flow?
+ Ok(key)
+}
+
+pub(crate) fn get_cert_chain(key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error> {
+ let mut attestation_certs_pb: keymaster_attributes::AttestationKey =
+ read_attestation_key_content(key_type)?;
+ let certs = attestation_certs_pb.take_certs();
+
+ let num_certs = certs.len();
+ if (num_certs == 0) {
+ return Err(km_err!(UnknownError, "Attestation Key file found but it had no certs"));
+ }
+ let mut certificates = vec_try_with_capacity!(num_certs)?;
+ for mut cert in certs {
+ let certificate = keymint::Certificate { encoded_certificate: cert.take_content() };
+ certificates.push(certificate);
+ }
+ // TODO: Do we need to support KEYMASTER_SOFT_ATTESTATION_FALLBACK flow?
+ Ok(certificates)
+}
+
+pub struct AttestationIds;
+
+impl RetrieveAttestationIds for AttestationIds {
+ fn get(&self) -> Result<AttestationIdInfo, Error> {
+ read_attestation_ids()
+ }
+
+ /// Destroy all attestation IDs associated with the device.
+ fn destroy_all(&mut self) -> Result<(), Error> {
+ delete_attestation_ids()
+ }
+}
+
+pub struct CertSignInfo;
+
+impl RetrieveCertSigningInfo for CertSignInfo {
+ fn signing_key(&self, key_type: SigningKeyType) -> Result<KeyMaterial, Error> {
+ read_attestation_key(key_type)
+ }
+
+ fn cert_chain(&self, key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error> {
+ get_cert_chain(key_type)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use alloc::vec;
+ use core::iter::zip;
+ use kmr_common::wire::AttestationIdInfo;
+ use kmr_ta::device::{SigningAlgorithm, SigningKey, SigningKeyType};
+ use log::info;
+ use protobuf::RepeatedField;
+ use test::{expect, expect_eq, expect_ne};
+
+ // Generated by:
+ // openssl genpkey -out rsakey2.key -outform DER -algorithm RSA -pkeyopt rsa_keygen_bits:2048
+ // openssl pkcs8 -topk8 -in rsakey2.key -outform der -nocrypt -out rsakey.key
+ const RSA_KEY: &'static [u8] = include_bytes!("rsakey.key");
+ // Generated by:
+ // 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");
+
+ fn create_file(file_name: &str) -> (Session, SecureFile) {
+ let mut session =
+ Session::new(Port::TamperProof, true).expect("Couldn't connect to storage");
+ let file = session
+ .open_file(file_name, OpenMode::Create)
+ .expect("Couldn't create attestation file.");
+ (session, file)
+ }
+
+ fn create_attestation_id_file() -> (Session, SecureFile) {
+ create_file(KM_ATTESTATION_ID_FILENAME)
+ }
+
+ fn create_attestation_key_file(algorithm: SigningAlgorithm) -> (Session, SecureFile) {
+ let file_name = get_key_slot_file_name(algorithm);
+ create_file(&file_name)
+ }
+
+ fn delete_key_file(algorithm: SigningAlgorithm) {
+ let file_name = get_key_slot_file_name(algorithm);
+ let mut session =
+ Session::new(Port::TamperProof, true).expect("Couldn't connect to storage");
+ session.remove(&file_name).expect("Couldn't delete attestation file.");
+ }
+
+ fn delete_attestation_id_file() {
+ let mut session =
+ Session::new(Port::TamperProof, true).expect("Couldn't connect to storage");
+ session.remove(KM_ATTESTATION_ID_FILENAME).expect("Couldn't delete attestation IDs file.");
+ }
+
+ fn check_attestation_id_file_exists() -> bool {
+ let mut session =
+ Session::new(Port::TamperProof, true).expect("Couldn't connect to storage");
+ session.open_file(KM_ATTESTATION_ID_FILENAME, OpenMode::Open).is_ok()
+ }
+
+ fn compare_attestation_ids(lhs: &AttestationIdInfo, rhs: &AttestationIdInfo) {
+ expect_eq!(lhs.brand, rhs.brand, "brand doesn't match");
+ expect_eq!(lhs.device, rhs.device, "device doesn't match");
+ expect_eq!(lhs.product, rhs.product, "product doesn't match");
+ expect_eq!(lhs.serial, rhs.serial, "serial doesn't match");
+ expect_eq!(lhs.imei, rhs.imei, "imei doesn't match");
+ expect_eq!(lhs.meid, rhs.meid, "meid doesn't match");
+ expect_eq!(lhs.manufacturer, rhs.manufacturer, "manufacturer doesn't match");
+ expect_eq!(lhs.model, rhs.model, "model doesn't match");
+ }
+
+ fn read_certificates_test(algorithm: SigningAlgorithm) {
+ let (mut session, mut file) = create_attestation_key_file(algorithm);
+ let mut key_cert = keymaster_attributes::AttestationKey::new();
+ let certs_data = [[b'a'; 2048], [b'\0'; 2048], [b'c'; 2048]];
+
+ let mut certs = protobuf::RepeatedField::<keymaster_attributes::AttestationCert>::new();
+
+ for cert_data in certs_data.iter() {
+ let mut cert = keymaster_attributes::AttestationCert::new();
+ cert.set_content(cert_data.to_vec());
+ certs.push(cert);
+ }
+
+ key_cert.set_certs(certs);
+
+ let serialized_buffer = key_cert.write_to_bytes().expect("Couldn't serialize certs");
+
+ session.write_all(&mut file, &serialized_buffer).unwrap();
+
+ file.close();
+ session.close();
+
+ let key_type = SigningKeyType { which: SigningKey::Batch, algo_hint: algorithm };
+ let certs = get_cert_chain(key_type).expect("Couldn't get certificates from storage");
+ delete_key_file(algorithm);
+
+ expect_eq!(certs.len(), 3, "Didn't recover all certificates");
+ for (cert, cert_data) in zip(certs.iter(), certs_data.iter()) {
+ expect_eq!(cert.encoded_certificate, cert_data.to_vec(), "Wrong certificate retrieved");
+ }
+
+ // Trying now using just a raw protobuf with same data
+ let field_header = [18, 131, 16, 10, 128, 16];
+ let mut raw_protobuf = Vec::new();
+ for cert_data in certs_data.iter() {
+ raw_protobuf.extend_from_slice(&field_header);
+ raw_protobuf.extend_from_slice(cert_data);
+ }
+ let (mut session, mut file) = create_attestation_key_file(algorithm);
+ session.write_all(&mut file, &raw_protobuf).unwrap();
+
+ file.close();
+ session.close();
+ let certs_comp = get_cert_chain(key_type).expect("Couldn't get certificates from storage");
+
+ expect_eq!(certs, certs_comp, "Retrieved certificates didn't match");
+
+ delete_key_file(algorithm);
+ }
+
+ #[test]
+ fn read_ec_rsa_certificates() {
+ read_certificates_test(SigningAlgorithm::Rsa);
+ read_certificates_test(SigningAlgorithm::Ec);
+ }
+
+ fn read_key_test(algorithm: SigningAlgorithm) {
+ let (mut session, mut file) = create_attestation_key_file(algorithm);
+
+ let mut key_cert = keymaster_attributes::AttestationKey::new();
+
+ let test_key = match algorithm {
+ SigningAlgorithm::Rsa => RSA_KEY,
+ SigningAlgorithm::Ec => EC_KEY,
+ };
+
+ key_cert.set_key(test_key.to_vec());
+
+ let serialized_buffer = key_cert.write_to_bytes().expect("Couldn't serialize key");
+ session.write_all(&mut file, &serialized_buffer).unwrap();
+ file.close();
+ session.close();
+
+ let key_type = SigningKeyType { which: SigningKey::Batch, algo_hint: algorithm };
+ let att_key = read_attestation_key(key_type).expect("Couldn't read key from storage");
+
+ delete_key_file(algorithm);
+
+ // Trying now using just a raw protobuf with same data
+ let key_header = match algorithm {
+ SigningAlgorithm::Rsa => [10, 191, 9],
+ SigningAlgorithm::Ec => [10, 138, 1],
+ };
+ let mut raw_protobuf = Vec::new();
+ raw_protobuf.extend_from_slice(&key_header);
+ raw_protobuf.extend_from_slice(&test_key);
+
+ let (mut session, mut file) = create_attestation_key_file(algorithm);
+ session.write_all(&mut file, &raw_protobuf).unwrap();
+ file.close();
+ session.close();
+
+ let att_key_comp = read_attestation_key(key_type).expect("Couldn't read key from storage");
+
+ expect_eq!(att_key, att_key_comp);
+
+ delete_key_file(algorithm);
+ }
+
+ #[test]
+ fn read_ec_rsa_key() {
+ read_key_test(SigningAlgorithm::Rsa);
+ read_key_test(SigningAlgorithm::Ec);
+ }
+
+ #[test]
+ fn single_attestation_id_field() {
+ let (mut session, mut file) = create_attestation_id_file();
+
+ let mut attestation_ids = keymaster_attributes::AttestationIds::new();
+ let brand = b"new brand";
+
+ attestation_ids.set_brand(brand.to_vec());
+
+ let serialized_buffer =
+ attestation_ids.write_to_bytes().expect("Couldn't serialize attestationIds");
+
+ session.write_all(&mut file, &serialized_buffer).unwrap();
+
+ file.close();
+ session.close();
+
+ let attestation_ids_info =
+ read_attestation_ids().expect("Couldn't read attestation IDs from storage");
+
+ delete_attestation_id_file();
+ expect_eq!(
+ check_attestation_id_file_exists(),
+ false,
+ "Couldn't delete attestation IDs file"
+ );
+
+ expect_eq!(attestation_ids_info.brand, brand.to_vec(), "brand doesn't match");
+ expect_eq!(attestation_ids_info.device.len(), 0, "shouldn't have a device");
+ expect_eq!(attestation_ids_info.product.len(), 0, "shouldn't have a product");
+ expect_eq!(attestation_ids_info.serial.len(), 0, "shouldn't have a serial");
+ expect_eq!(attestation_ids_info.imei.len(), 0, "shouldn't have a imei");
+ expect_eq!(attestation_ids_info.meid.len(), 0, "shouldn't have a meid");
+ expect_eq!(attestation_ids_info.manufacturer.len(), 0, "shouldn't have a manufacturer");
+ expect_eq!(attestation_ids_info.model.len(), 0, "shouldn't have a model");
+
+ // Now using a raw protobuf
+ let raw_protobuf = [10, 9, 110, 101, 119, 32, 98, 114, 97, 110, 100];
+ let (mut session, mut file) = create_attestation_id_file();
+ session.write_all(&mut file, &raw_protobuf).unwrap();
+ file.close();
+ session.close();
+ let attestation_ids_comp = read_attestation_ids()
+ .expect("Couldn't read comparison set of attestation IDs from storage");
+
+ compare_attestation_ids(&attestation_ids_info, &attestation_ids_comp);
+
+ delete_attestation_id_file();
+ expect_eq!(
+ check_attestation_id_file_exists(),
+ false,
+ "Couldn't delete attestation IDs file"
+ );
+ }
+
+ #[test]
+ fn all_attestation_id_fields() {
+ let (mut session, mut file) = create_attestation_id_file();
+
+ let mut attestation_ids = keymaster_attributes::AttestationIds::new();
+ let brand = b"unknown brand";
+ let device = b"my brand new device";
+ let product = b"";
+ let serial = vec![b'9'; 64];
+ let imei = b" ";
+ let meid = b"\0";
+ let manufacturer = b"manufacturer #$%%^";
+ let model = b"working one";
+
+ attestation_ids.set_brand(brand.to_vec());
+ attestation_ids.set_device(device.to_vec());
+ attestation_ids.set_product(product.to_vec());
+ attestation_ids.set_serial(serial.clone());
+ attestation_ids.set_imei(imei.to_vec());
+ attestation_ids.set_meid(meid.to_vec());
+ attestation_ids.set_manufacturer(manufacturer.to_vec());
+ attestation_ids.set_model(model.to_vec());
+
+ let serialized_buffer =
+ attestation_ids.write_to_bytes().expect("Couldn't serialize attestationIds");
+
+ session.write_all(&mut file, &serialized_buffer).unwrap();
+
+ file.close();
+ session.close();
+
+ let attestation_ids_info =
+ read_attestation_ids().expect("Couldn't read attestation IDs from storage");
+
+ delete_attestation_id_file();
+ expect_eq!(
+ check_attestation_id_file_exists(),
+ false,
+ "Couldn't delete attestation IDs file"
+ );
+
+ expect_eq!(attestation_ids_info.brand, brand.to_vec(), "brand doesn't match");
+ expect_eq!(attestation_ids_info.device, device.to_vec(), "device doesn't match");
+ expect_eq!(attestation_ids_info.product, product.to_vec(), "product doesn't match");
+ expect_eq!(attestation_ids_info.serial, serial, "serial doesn't match");
+ expect_eq!(attestation_ids_info.imei, imei.to_vec(), "imei doesn't match");
+ expect_eq!(attestation_ids_info.meid, meid.to_vec(), "meid doesn't match");
+ expect_eq!(
+ attestation_ids_info.manufacturer,
+ manufacturer.to_vec(),
+ "manufacturer doesn't match"
+ );
+ expect_eq!(attestation_ids_info.model, model.to_vec(), "model doesn't match");
+
+ // Now trying the same from a raw protobuf
+ let raw_protobuf = [
+ 10, 13, 117, 110, 107, 110, 111, 119, 110, 32, 98, 114, 97, 110, 100, 18, 19, 109, 121,
+ 32, 98, 114, 97, 110, 100, 32, 110, 101, 119, 32, 100, 101, 118, 105, 99, 101, 26, 0,
+ 34, 64, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 42, 1, 32, 50, 1, 0, 58, 18, 109, 97, 110, 117, 102, 97, 99, 116, 117, 114, 101, 114,
+ 32, 35, 36, 37, 37, 94, 66, 11, 119, 111, 114, 107, 105, 110, 103, 32, 111, 110, 101,
+ ];
+
+ let (mut session, mut file) = create_attestation_id_file();
+ session.write_all(&mut file, &raw_protobuf).unwrap();
+ file.close();
+ session.close();
+
+ let attestation_ids_comp = read_attestation_ids()
+ .expect("Couldn't read comparison set of attestation IDs from storage");
+
+ compare_attestation_ids(&attestation_ids_info, &attestation_ids_comp);
+
+ delete_attestation_id_file();
+ expect_eq!(
+ check_attestation_id_file_exists(),
+ false,
+ "Couldn't delete attestation IDs file"
+ );
+ }
+
+ #[test]
+ fn delete_attestation_ids_file() {
+ let (mut session, mut file) = create_attestation_id_file();
+ let raw_protobuf = [10, 9, 110, 101, 119, 32, 98, 114, 97, 110, 100];
+ session.write_all(&mut file, &raw_protobuf).unwrap();
+ file.close();
+ session.close();
+ expect!(check_attestation_id_file_exists(), "Couldn't create attestation IDs file");
+ expect!(delete_attestation_ids().is_ok(), "Couldn't delete attestation IDs file");
+ expect_eq!(
+ check_attestation_id_file_exists(),
+ false,
+ "Attestation IDs file was not deleted"
+ );
+ }
+
+ #[test]
+ fn protobuf_lib_version() {
+ // We are generating the protobuf rust files out of tree because we cannot do it in-tree yet
+ // Because the version of the tool used to autogenerate the files has to match the protobuf
+ // library version, we check it here.
+ expect_eq!("2.27.1", protobuf::VERSION, "autogenerated files version mistmatch");
+ }
+}