Merge "Add rustfmt preupload hook"
diff --git a/fuzzing/orphans/libexif/libexif_fuzzer.cpp b/fuzzing/orphans/libexif/libexif_fuzzer.cpp
index c010bbe..6bfbbca 100644
--- a/fuzzing/orphans/libexif/libexif_fuzzer.cpp
+++ b/fuzzing/orphans/libexif/libexif_fuzzer.cpp
@@ -2,6 +2,9 @@
 #include <libexif/exif-loader.h>
 #include <stddef.h>
 #include <stdlib.h>
+#include <string.h>
+
+constexpr size_t kMaxDataSize = 32;
 
 /* Extract all MakerNote tags */
 static void mnote_dump(ExifData *data) {
@@ -32,8 +35,15 @@
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  if (!data) {
+    return 0;
+  }
+
+  size = (size % kMaxDataSize);
+  uint8_t *buffer = (uint8_t *)malloc(size * sizeof(uint8_t));
+  memcpy(buffer, data, size);
   // Parse tags using (ultimately) exif_data_load_data()
-  auto image = exif_data_new_from_data(data, size);
+  auto image = exif_data_new_from_data(buffer, size);
   if (image) {
     // Exercise the EXIF tag manipulation code
     exif_data_get_mnote_data(image);
@@ -52,14 +62,15 @@
   // be identical to what has been loaded (and fuzzed) above.
   ExifLoader *loader = exif_loader_new();
   if (!loader) {
+    free(buffer);
     return 0;
   }
-  exif_loader_write(loader, const_cast<unsigned char *>(data), size);
+  exif_loader_write(loader, const_cast<unsigned char *>(buffer), size);
   image = exif_loader_get_data(loader);
   if (image) {
     exif_data_unref(image);
   }
   exif_loader_unref(loader);
-
+  free(buffer);
   return 0;
 }
diff --git a/remote_provisioning/cert_validator/src/bcc/entry.rs b/remote_provisioning/cert_validator/src/bcc/entry.rs
index 2ebc12e..12f4435 100644
--- a/remote_provisioning/cert_validator/src/bcc/entry.rs
+++ b/remote_provisioning/cert_validator/src/bcc/entry.rs
@@ -2,14 +2,14 @@
 
 use super::{cose_error, get_label_value};
 use crate::dice;
-use crate::publickey;
+use crate::display::write_value;
+use crate::publickey::PublicKey;
 use crate::valueas::ValueAs;
 use anyhow::{anyhow, bail, ensure, Context, Result};
 use coset::AsCborValue;
 use coset::{
     cbor::value::Value,
-    iana::{self, EnumI64},
-    Algorithm, CborSerializable,
+    iana, Algorithm, CborSerializable,
     CoseError::{self, EncodeFailed, UnexpectedItem},
     CoseKey, CoseSign1, Header, RegisteredLabel,
 };
@@ -140,7 +140,7 @@
     ) -> Result<Payload> {
         check_protected_header(&pkey.0.alg, &sign1.protected.header)
             .context("Validation of bcc entry protected header failed.")?;
-        let v = publickey::PublicKey::from_cose_key(&pkey.0)
+        let v = PublicKey::from_cose_key(&pkey.0)
             .context("Extracting the Public key from coseKey failed.")?;
         sign1
             .verify_signature(b"", |s, m| v.verify(s, m, &pkey.0.alg))
@@ -264,48 +264,14 @@
         dice::COMPONENT_NAME => f.write_str("Component Name"),
         dice::FIRMWARE_VERSION => f.write_str("Firmware Version"),
         dice::RESETTABLE => f.write_str("Resettable"),
-        _ => write!(f, "{}", label),
+        _ => label.fmt(f),
     }
 }
 
 impl Display for SubjectPublicKey {
     fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
-        let pkey = &self.0;
-        if pkey.kty != coset::KeyType::Assigned(iana::KeyType::OKP)
-            || pkey.alg != Some(coset::Algorithm::Assigned(iana::Algorithm::EdDSA))
-        {
-            return Err(fmt::Error);
-        }
-
-        let mut separator = "";
-        for (label, value) in &pkey.params {
-            use coset::Label;
-            use iana::OkpKeyParameter;
-            if let Label::Int(i) = label {
-                match OkpKeyParameter::from_i64(*i) {
-                    Some(OkpKeyParameter::Crv) => {
-                        if let Some(crv) =
-                            value.as_i64().ok().and_then(iana::EllipticCurve::from_i64)
-                        {
-                            f.write_str(separator)?;
-                            write!(f, "Curve: {:?}", crv)?;
-                            separator = " ";
-                        }
-                    }
-                    Some(OkpKeyParameter::X) => {
-                        if let Ok(x) = ValueAs::as_bytes(value) {
-                            f.write_str(separator)?;
-                            f.write_str("X: ")?;
-                            write_bytes_in_hex(f, x)?;
-                            separator = " ";
-                        }
-                    }
-                    _ => (),
-                }
-            }
-        }
-
-        Ok(())
+        let pkey = PublicKey::from_cose_key(&self.0).map_err(|_| fmt::Error)?;
+        pkey.fmt(f)
     }
 }
 
@@ -347,37 +313,18 @@
         dice::MODE => f.write_str("Mode"),
         dice::SUBJECT_PUBLIC_KEY => f.write_str("Subject Public Key"),
         dice::KEY_USAGE => f.write_str("Key Usage"),
-        _ => write!(f, "{}", label),
+        _ => label.fmt(f),
     }
 }
 
 fn write_config_desc(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
     let bytes = value.as_bytes().ok_or(fmt::Error)?;
     let config_desc = ConfigDesc::from_slice(bytes).map_err(|_| fmt::Error)?;
-    write!(f, "{}", config_desc)
+    config_desc.fmt(f)
 }
 
 fn write_subject_public_key(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
     let bytes = value.as_bytes().ok_or(fmt::Error)?;
     let subject_public_key = SubjectPublicKey::from_slice(bytes).map_err(|_| fmt::Error)?;
-    write!(f, "{}", subject_public_key)
-}
-
-fn write_value(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
-    if let Some(bytes) = value.as_bytes() {
-        write_bytes_in_hex(f, bytes)
-    } else if let Some(text) = value.as_text() {
-        write!(f, "\"{}\"", text)
-    } else if let Ok(integer) = value.as_i64() {
-        write!(f, "{}", integer)
-    } else {
-        write!(f, "{:?}", value)
-    }
-}
-
-fn write_bytes_in_hex(f: &mut Formatter, bytes: &[u8]) -> Result<(), fmt::Error> {
-    for b in bytes {
-        write!(f, "{:02x}", b)?
-    }
-    Ok(())
+    writeln!(f, "{}", subject_public_key)
 }
diff --git a/remote_provisioning/cert_validator/src/display.rs b/remote_provisioning/cert_validator/src/display.rs
new file mode 100644
index 0000000..25877fb
--- /dev/null
+++ b/remote_provisioning/cert_validator/src/display.rs
@@ -0,0 +1,24 @@
+//! Helper functions for implementing Display for our types.
+
+use crate::valueas::ValueAs;
+use coset::cbor::value::Value;
+use std::fmt::{self, Formatter};
+
+pub fn write_bytes_in_hex(f: &mut Formatter, bytes: &[u8]) -> Result<(), fmt::Error> {
+    for b in bytes {
+        write!(f, "{:02x}", b)?
+    }
+    Ok(())
+}
+
+pub fn write_value(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
+    if let Some(bytes) = value.as_bytes() {
+        write_bytes_in_hex(f, bytes)
+    } else if let Some(text) = value.as_text() {
+        write!(f, "\"{}\"", text)
+    } else if let Ok(integer) = value.as_i64() {
+        write!(f, "{}", integer)
+    } else {
+        write!(f, "{:?}", value)
+    }
+}
diff --git a/remote_provisioning/cert_validator/src/lib.rs b/remote_provisioning/cert_validator/src/lib.rs
index 35cf7f7..b961832 100644
--- a/remote_provisioning/cert_validator/src/lib.rs
+++ b/remote_provisioning/cert_validator/src/lib.rs
@@ -5,6 +5,7 @@
 pub mod bcc;
 pub mod deviceinfo;
 pub mod dice;
+mod display;
 pub mod publickey;
 pub mod valueas;
 
diff --git a/remote_provisioning/cert_validator/src/publickey.rs b/remote_provisioning/cert_validator/src/publickey.rs
index 280e1dd..dcc04b3 100644
--- a/remote_provisioning/cert_validator/src/publickey.rs
+++ b/remote_provisioning/cert_validator/src/publickey.rs
@@ -1,10 +1,12 @@
 //! This module describes the public key (PubKeyEd25519 or PubKeyECDSA256)
 //! used in the BccPayload. The key itself is stored as a simple byte array in
-//! a vector. For now, only PubKeyEd25519 types of cbor public keys are supported.
+//! a vector.
 
 use crate::bcc::get_label_value_as_bytes;
+use crate::display::write_bytes_in_hex;
 use anyhow::{bail, ensure, Context, Result};
 use coset::{iana, Algorithm, CoseKey};
+use std::fmt::{self, Display, Formatter};
 use std::ptr;
 
 /// Length of an Ed25519 public key.
@@ -219,3 +221,21 @@
         Ok(())
     }
 }
+
+impl Display for PublicKey {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
+        match self.key {
+            PubKey::Ed25519 { pub_key } => {
+                f.write_str("Ed25519 X: ")?;
+                write_bytes_in_hex(f, &pub_key)?;
+            }
+            PubKey::P256 { x_coord, y_coord } => {
+                f.write_str("P256 X: ")?;
+                write_bytes_in_hex(f, &x_coord)?;
+                f.write_str(" Y: ")?;
+                write_bytes_in_hex(f, &y_coord)?;
+            }
+        }
+        Ok(())
+    }
+}