key: Add new decode-avb subcommand

This does the reverse of `avbroot key extract-avb`. It's useful for
reconstructing a PKCS8-encoded RSA public key when working with the
`public_key` fields in `avb.toml`.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit is contained in:
Andrew Gunnerson
2023-12-10 13:29:45 -05:00
parent b7028b13a2
commit adbe249edb
2 changed files with 40 additions and 0 deletions
+23
View File
@@ -71,6 +71,16 @@ pub fn key_main(cli: &KeyCli) -> Result<()> {
fs::write(&c.output, encoded)
.with_context(|| format!("Failed to write public key: {:?}", c.output))?;
}
KeyCommand::DecodeAvb(c) => {
let encoded = fs::read(&c.key)
.with_context(|| format!("Failed to load AVB public key: {:?}", c.key))?;
let public_key = avb::decode_public_key(&encoded)
.context("Failed to decode public key as AVB format")?;
crypto::write_pem_public_key_file(&c.output, &public_key)
.with_context(|| format!("Failed to write public key: {:?}", c.output))?;
}
}
Ok(())
@@ -152,11 +162,24 @@ struct ExtractAvbCli {
passphrase: PassphraseGroup,
}
/// Convert an AVB-encoded public key to a PKCS8-encoded public key.
#[derive(Debug, Parser)]
struct DecodeAvbCli {
/// Path to output PKCS8-encoded public key.
#[arg(short, long, value_name = "FILE", value_parser)]
output: PathBuf,
/// Path to AVB-encoded public key.
#[arg(short, long, value_name = "FILE", value_parser)]
key: PathBuf,
}
#[derive(Debug, Subcommand)]
enum KeyCommand {
GenerateKey(GenerateKeyCli),
GenerateCert(GenerateCertCli),
ExtractAvb(ExtractAvbCli),
DecodeAvb(DecodeAvbCli),
}
/// Generate and convert keys.
+17
View File
@@ -225,6 +225,23 @@ pub fn write_pem_cert_file(path: &Path, cert: &Certificate) -> Result<()> {
write_pem_cert(writer, cert)
}
/// Write PEM-encoded PKCS8 public key to a writer.
pub fn write_pem_public_key(mut writer: impl Write, key: &RsaPublicKey) -> Result<()> {
let data = key.to_public_key_pem(LineEnding::LF)?;
writer.write_all(data.as_bytes())?;
Ok(())
}
/// Write PEM-encoded PKCS8 public key to a file.
pub fn write_pem_public_key_file(path: &Path, key: &RsaPublicKey) -> Result<()> {
let file = File::create(path)?;
let writer = BufWriter::new(file);
write_pem_public_key(writer, key)
}
/// Read PEM-encoded PKCS8 private key from a reader.
pub fn read_pem_key(mut reader: impl Read, source: &PassphraseSource) -> Result<RsaPrivateKey> {
let mut data = String::new();