Snap for 10453563 from fe47b7a2c273caaea6c76a15abe25bd0bb501be9 to mainline-tzdata5-release

Change-Id: I2cfe2d2b023af8ff4192ab570133b2c5e3da0078
diff --git a/remote_provisioning/hwtrust/src/cbor/publickey.rs b/remote_provisioning/hwtrust/src/cbor/publickey.rs
index 69f9799..709daff 100644
--- a/remote_provisioning/hwtrust/src/cbor/publickey.rs
+++ b/remote_provisioning/hwtrust/src/cbor/publickey.rs
@@ -61,11 +61,14 @@
                 key.public_key()
                     .affine_coordinates_gfp(group, &mut x, &mut y, &mut ctx)
                     .context("Get EC coordinates")?;
-                let crv = match ec {
-                    EcKind::P256 => iana::EllipticCurve::P_256,
-                    EcKind::P384 => iana::EllipticCurve::P_384,
+                let (crv, coord_len) = match ec {
+                    EcKind::P256 => (iana::EllipticCurve::P_256, 32),
+                    EcKind::P384 => (iana::EllipticCurve::P_384, 48),
                 };
-                CoseKeyBuilder::new_ec2_pub_key(crv, x.to_vec(), y.to_vec())
+
+                let x = adjust_coord(x.to_vec(), coord_len);
+                let y = adjust_coord(y.to_vec(), coord_len);
+                CoseKeyBuilder::new_ec2_pub_key(crv, x, y)
             }
         };
         Ok(builder
@@ -75,6 +78,21 @@
     }
 }
 
+fn adjust_coord(mut coordinate: Vec<u8>, length: usize) -> Vec<u8> {
+    // Use loops "just in case". However we should never see a coordinate with more than one
+    // extra leading byte. The chances of more than one trailing byte is also quite small --
+    // roughly 1/65000.
+    while coordinate.len() > length && coordinate[0] == 00 {
+        coordinate.remove(0);
+    }
+
+    while coordinate.len() < length {
+        coordinate.insert(0, 0);
+    }
+
+    coordinate
+}
+
 fn pkey_from_okp_key(cose_key: &CoseKey) -> Result<PKey<Public>> {
     ensure!(cose_key.kty == KeyType::Assigned(iana::KeyType::OKP));
     ensure!(cose_key.alg == Some(Algorithm::Assigned(iana::Algorithm::EdDSA)));
@@ -158,7 +176,10 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::publickey::testkeys::{PrivateKey, ED25519_KEY_PEM, P256_KEY_PEM};
+    use crate::publickey::testkeys::{
+        PrivateKey, ED25519_KEY_PEM, P256_KEY_PEM, P256_KEY_WITH_LEADING_ZEROS_PEM,
+        P384_KEY_WITH_LEADING_ZEROS_PEM,
+    };
     use coset::{CoseSign1Builder, HeaderBuilder};
 
     impl PrivateKey {
@@ -269,4 +290,40 @@
         let new_key = PublicKey::from_cose_key(&value).unwrap();
         assert!(key.pkey().public_eq(new_key.pkey()));
     }
+
+    #[test]
+    fn from_p256_pkey_with_leading_zeros() {
+        for pem in P256_KEY_WITH_LEADING_ZEROS_PEM {
+            let key = PrivateKey::from_pem(pem).public_key();
+            let cose_key = key.to_cose_key().unwrap();
+
+            let x =
+                get_label_value_as_bytes(&cose_key, Label::Int(iana::Ec2KeyParameter::X.to_i64()))
+                    .unwrap();
+            assert_eq!(x.len(), 32, "X coordinate is the wrong size\n{}", pem);
+
+            let y =
+                get_label_value_as_bytes(&cose_key, Label::Int(iana::Ec2KeyParameter::Y.to_i64()))
+                    .unwrap();
+            assert_eq!(y.len(), 32, "Y coordinate is the wrong size\n{}", pem);
+        }
+    }
+
+    #[test]
+    fn from_p384_pkey_with_leading_zeros() {
+        for pem in P384_KEY_WITH_LEADING_ZEROS_PEM {
+            let key = PrivateKey::from_pem(pem).public_key();
+            let cose_key = key.to_cose_key().unwrap();
+
+            let x =
+                get_label_value_as_bytes(&cose_key, Label::Int(iana::Ec2KeyParameter::X.to_i64()))
+                    .unwrap();
+            assert_eq!(x.len(), 48, "X coordinate is the wrong size\n{}", pem);
+
+            let y =
+                get_label_value_as_bytes(&cose_key, Label::Int(iana::Ec2KeyParameter::Y.to_i64()))
+                    .unwrap();
+            assert_eq!(y.len(), 48, "Y coordinate is the wrong size\n{}", pem);
+        }
+    }
 }
diff --git a/remote_provisioning/hwtrust/src/publickey.rs b/remote_provisioning/hwtrust/src/publickey.rs
index 905d6ac..562ec37 100644
--- a/remote_provisioning/hwtrust/src/publickey.rs
+++ b/remote_provisioning/hwtrust/src/publickey.rs
@@ -211,6 +211,25 @@
         -----END PRIVATE KEY-----\n",
     ];
 
+    /// A selection of EC keys that should have leading zeros in their coordinates
+    pub const P256_KEY_WITH_LEADING_ZEROS_PEM: &[&str] = &[
+        // 31 byte Y coordinate:
+        "-----BEGIN PRIVATE KEY-----\n\
+        MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCWbRSB3imI03F5YNVq\n\
+        8AN8ZbyzW/h+5BQ53caD5VkWJg==\n\
+        -----END PRIVATE KEY-----\n",
+        // 31 byte X coordinate:
+        "-----BEGIN PRIVATE KEY-----\n\
+        MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDe5E5WqNmCLxtsCNTc\n\
+        UOb9CPXCn6l3CZpbrp0aivb+Bw==\n\
+        -----END PRIVATE KEY-----\n",
+        // X & Y both have MSB set, and some stacks will add a padding byte
+        "-----BEGIN PRIVATE KEY-----\n\
+        MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCWOWcXPDEVZ4Qz3EBK\n\
+        uvSqhD9HmxDGxcNe3yxKi9pazw==\n\
+        -----END PRIVATE KEY-----\n",
+    ];
+
     /// A selection of elliptic curve P-384 private keys.
     pub const P384_KEY_PEM: &[&str] = &["-----BEGIN PRIVATE KEY-----\n\
         MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBMZ414LiUpcuNTNq5W\n\
@@ -219,6 +238,25 @@
         uuHi+VayOreTX1/qlUoxgBT+XTI0nTdLn6WwO6vVO1NIkGEVnYvB2eM=\n\
         -----END PRIVATE KEY-----\n"];
 
+    /// A selection of EC keys that should have leading zeros in their coordinates
+    pub const P384_KEY_WITH_LEADING_ZEROS_PEM: &[&str] = &[
+        // 47 byte Y coordinate:
+        "-----BEGIN PRIVATE KEY-----\n\
+        ME4CAQAwEAYHKoZIzj0CAQYFK4EEACIENzA1AgEBBDCzgVHCz7wgmSdb7/IixYik\n\
+        3AuQceCtBTiFrJpgpGFluwgLUR0S2NpzIuty4M7xU74=\n\
+        -----END PRIVATE KEY-----\n",
+        // 47 byte X coordinate:
+        "-----BEGIN PRIVATE KEY-----\n\
+        ME4CAQAwEAYHKoZIzj0CAQYFK4EEACIENzA1AgEBBDBoW+8zbvwf5fYOS8YPyPEH\n\
+        jHP71Vr1MnRYRp/yG1wbthW2XEu0UWbp4qrZ5WTnZPg=\n\
+        -----END PRIVATE KEY-----\n",
+        // X & Y both have MSB set, and some stacks will add a padding byte
+        "-----BEGIN PRIVATE KEY-----\n\
+        ME4CAQAwEAYHKoZIzj0CAQYFK4EEACIENzA1AgEBBDD2A69j5M/6oc6/WGoYln4t\n\
+        Alnn0C6kpJz1EVC+eH6y0YNrcGamz8pPY4NkzUB/tj4=\n\
+        -----END PRIVATE KEY-----\n",
+    ];
+
     /// A selection of elliptic curve P-521 private keys.
     pub const P521_KEY_PEM: &[&str] = &["-----BEGIN PRIVATE KEY-----\n\
         MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBQuD8Db3jT2yPYR5t\n\