Skip to content

Commit

Permalink
Better handling of OpenSSL generated keys.
Browse files Browse the repository at this point in the history
It seems that ECC keys generated by OpenSSL can be between 30 and 33
bytes long whereas OpenSK code expects a fixed size of 32 bytes.
This variation could cause Travis CI to fail but also invalid ECC keys
to be flashed, causing the authenticator to not work.
  • Loading branch information
jmichelp committed Feb 20, 2020
1 parent ef414bc commit 6c36398
Showing 1 changed file with 28 additions and 6 deletions.
34 changes: 28 additions & 6 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,37 @@ fn main() {
pkey.check_key().unwrap();
assert_eq!(pkey.group().curve_name(), Some(Nid::X9_62_PRIME256V1));

let mut priv_key = pkey.private_key().to_vec();
if priv_key.len() == 33 && priv_key[0] == 0 {
priv_key.remove(0);
}
assert_eq!(priv_key.len(), 32);
// Private keys generated by OpenSSL have variable size but we only handle
// constant size. Serialization is done in big endian so if the size is less
// than 32 bytes, we need to prepend with null bytes.
// If the size is 33 bytes, this means the serialized BigInt is negative.
// Any other size is invalid.
let priv_key_hex = pkey.private_key().to_hex_str().unwrap();
let priv_key_vec = pkey.private_key().to_vec();
let key_len = priv_key_vec.len();

assert!(
key_len >= 30,
"Invalid private key (too small): {} ({:#?})",
priv_key_hex,
priv_key_vec,
);
assert!(
key_len <= 33,
"Invalid private key (too big): {} ({:#?})",
priv_key_hex,
priv_key_vec,
);

// Copy OpenSSL generated key to our vec, starting from the end
let mut output_vec = [0u8; 32];
let min_key_len = std::cmp::min(key_len, 32);
output_vec[32usize.saturating_sub(min_key_len)..]
.copy_from_slice(&priv_key_vec[key_len.saturating_sub(min_key_len)..]);

// Create the raw private key out of the OpenSSL data
let mut priv_key_bin_file = File::create(&priv_key_bin_path).unwrap();
priv_key_bin_file.write_all(&priv_key).unwrap();
priv_key_bin_file.write_all(&output_vec).unwrap();

// Convert the PEM certificate to DER and extract the serial for AAGUID
let input_pem_cert = include_bytes!("crypto_data/opensk_cert.pem");
Expand Down

0 comments on commit 6c36398

Please sign in to comment.