Skip to content

Commit

Permalink
KMS signing support: cmd arguments
Browse files Browse the repository at this point in the history
Signed-off-by: Eugene Koira <[email protected]>
  • Loading branch information
eugkoira committed Apr 16, 2024
1 parent 1ce640c commit 0a4923b
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 36 deletions.
53 changes: 37 additions & 16 deletions enclave_build/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright 2019-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use clap::{App, AppSettings, Arg};
use std::fs::OpenOptions;

use aws_nitro_enclaves_image_format::{
generate_build_info,
utils::{SignKeyDataInfo, SignKeyInfo},
};
use aws_nitro_enclaves_image_format::generate_build_info;
use aws_nitro_enclaves_image_format::utils::{SignKeyDataInfo, SignKeyInfo};
use enclave_build::Docker2Eif;

fn main() {
Expand Down Expand Up @@ -89,6 +87,18 @@ fn main() {
.help("Specify the path to the private-key")
.takes_value(true),
)
.arg(
Arg::with_name("kms-key-id")
.long("kms-key-id")
.help("Specify id of the KMS key")
.takes_value(true),
)
.arg(
Arg::with_name("kms-key-region")
.long("kms-key-region")
.help("Specify region in which the KMS key resides")
.takes_value(true),
)
.arg(
Arg::with_name("build")
.short('b')
Expand Down Expand Up @@ -136,9 +146,27 @@ fn main() {
let signing_certificate = matches
.value_of("signing_certificate")
.map(|val| val.to_string());
let private_key = matches
.value_of("private_certificate")
.map(|val| val.to_string());
let kms_key_id = matches.value_of("kms-key-id");
let kms_key_region = matches.value_of("kms-key-region");
let private_key_path = matches.value_of("private_key").map(|val| val.to_string());

let sign_key_info = match (signing_certificate, kms_key_id, private_key_path) {
(None, None, None) => None,
(Some(cert_path), None, Some(key_path)) =>
Some(SignKeyDataInfo {
cert_path: cert_path.to_string(),
key_info: SignKeyInfo::LocalPrivateKeyInfo { path: key_path.to_string() }
}),
(Some(cert_path), Some(key_id), None) =>
Some(SignKeyDataInfo {
cert_path: cert_path.to_string(),
key_info: SignKeyInfo::KmsKeyInfo { id: key_id.to_string(), region: kms_key_region.map(str::to_string) }
}),
(Some(_), None, None) => panic!("signing-certificate can be used only together with kms-key-id or private-key parameters"),
(None, Some(_), None) => panic!("signing-certificate is required together with kms-key-id parameters"),
(None, None, Some(_)) => panic!("signing-certificate is required together with private-key parameters"),
(_, Some(_), Some(_)) => panic!("kms-key-id and private-key parameters are mutually exclusive")
};
let img_name = matches.value_of("image_name").map(|val| val.to_string());
let img_version = matches.value_of("image_version").map(|val| val.to_string());
let metadata = matches.value_of("metadata").map(|val| val.to_string());
Expand All @@ -151,13 +179,6 @@ fn main() {
.open(output)
.expect("Failed to create output file");

let sign_info = signing_certificate.as_ref().map(|cert| SignKeyDataInfo {
cert_path: cert.to_string(),
key_info: SignKeyInfo::LocalPrivateKeyInfo {
path: private_key.unwrap(),
},
});

let mut img = Docker2Eif::new(
docker_image.to_string(),
init_path.to_string(),
Expand All @@ -167,7 +188,7 @@ fn main() {
linuxkit_path.to_string(),
&mut output,
".".to_string(),
&sign_info,
&sign_key_info,
img_name,
img_version,
metadata,
Expand Down
55 changes: 42 additions & 13 deletions src/common/commands_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,29 +120,50 @@ impl BuildEnclavesArgs {
pub fn new_with(args: &ArgMatches) -> NitroCliResult<Self> {
let signing_certificate = parse_signing_certificate(args);
let private_key = parse_private_key(args);
let kms_key_id = parse_kms_key_id(args);
let kms_key_region = parse_kms_key_region(args);

let sign_info = match (&signing_certificate, &private_key) {
(Some(_), None) => {
let sign_info = match (signing_certificate, kms_key_id, private_key) {
(None, None, None) => None,
(Some(cert_path), None, Some(key_path)) => Some(SignKeyDataInfo {
cert_path: cert_path.to_string(),
key_info: SignKeyInfo::LocalPrivateKeyInfo {
path: key_path.to_string(),
},
}),
(Some(cert_path), Some(key_id), None) => Some(SignKeyDataInfo {
cert_path: cert_path.to_string(),
key_info: SignKeyInfo::KmsKeyInfo {
id: key_id.to_string(),
region: kms_key_region,
},
}),
(Some(_), None, None) => {
return Err(new_nitro_cli_failure!(
"`private-key` argument not found",
"`private-key` or `kms-key-id` argument not found",
NitroCliErrorEnum::MissingArgument
))
}
(None, Some(_), None) => {
return Err(new_nitro_cli_failure!(
"`signing-certificate` argument not found while `kms-key-id` is provided",
NitroCliErrorEnum::MissingArgument
)
.add_info(vec!["private-key"]))
.add_info(vec!["signing-certificate"]))
}
(None, Some(_)) => {
(None, None, Some(_)) => {
return Err(new_nitro_cli_failure!(
"`signing-certificate` argument not found",
"`signing-certificate` argument not found while `private-key` is provided",
NitroCliErrorEnum::MissingArgument
)
.add_info(vec!["signing-certificate"]))
}
(Some(cert_path), Some(key_path)) => Some(SignKeyDataInfo {
cert_path: cert_path.clone(),
key_info: SignKeyInfo::LocalPrivateKeyInfo {
path: key_path.clone(),
},
}),
(None, None) => None,
(_, Some(_), Some(_)) => {
return Err(new_nitro_cli_failure!(
"`kms-key-id` and `private-key` parameters are mutually exclusive",
NitroCliErrorEnum::ConflictingArgument
))
}
};

Ok(BuildEnclavesArgs {
Expand Down Expand Up @@ -576,6 +597,14 @@ fn parse_error_code_str(args: &ArgMatches) -> NitroCliResult<String> {
Ok(error_code_str.to_string())
}

fn parse_kms_key_region(args: &ArgMatches) -> Option<String> {
args.value_of("kms-key-region").map(|val| val.to_string())
}

fn parse_kms_key_id(args: &ArgMatches) -> Option<String> {
args.value_of("kms-key-id").map(|val| val.to_string())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
30 changes: 24 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,12 +734,6 @@ macro_rules! create_app {
.help("Local path to developer's X509 signing certificate.")
.takes_value(true),
)
.arg(
Arg::with_name("private-key")
.long("private-key")
.help("Local path to developer's Eliptic Curve private key.")
.takes_value(true),
)
.arg(
Arg::with_name("image_name")
.long("name")
Expand All @@ -757,6 +751,30 @@ macro_rules! create_app {
.long("metadata")
.help("Path to JSON containing the custom metadata provided by the user.")
.takes_value(true),
)
.arg(
Arg::with_name("private-key")
.long("private-key")
.help("Local path to developer's Eliptic Curve private key.")
.takes_value(true)
.conflicts_with("kms-key-id")
.conflicts_with("kms-key-region"),
)
.arg(
Arg::with_name("kms-key-region")
.long("kms-key-region")
.help("The region in which the KMS key resides.")
.takes_value(true)
.required(false)
.conflicts_with("private-key"),
)
.arg(
Arg::with_name("kms-key-id")
.long("kms-key-id")
.help("The KMS key ID")
.takes_value(true)
.required(false)
.conflicts_with("private-key"),
),
)
.subcommand(
Expand Down
50 changes: 49 additions & 1 deletion tests/test_nitro_cli_args.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright 2019-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#![deny(warnings)]

Expand Down Expand Up @@ -650,4 +650,52 @@ mod test_nitro_cli_args {

assert!(app.get_matches_from_safe(args).is_ok())
}

#[test]
fn build_kms_signed_enclave_correct_command() {
let app = create_app!();
let args = vec![
"nitro cli",
"build-enclave",
"--docker-uri",
"dkr.ecr.us-east-1.amazonaws.com/stronghold-develss",
"--docker-dir",
"dir/",
"--output-file",
"image.eif",
"--signing-certificate",
"cert.pem",
"--kms-key-id",
"a23f54c8-b2ce-1a5c-a2db-f444a5b3d22d",
"--kms-key-region",
"eu-west-1",
];

assert_eq!(app.get_matches_from_safe(args).is_err(), false)
}

#[test]
fn build_kms_signed_enclave_conflicting_arguments() {
let app = create_app!();
let args = vec![
"nitro cli",
"build-enclave",
"--docker-uri",
"dkr.ecr.us-east-1.amazonaws.com/stronghold-develss",
"--docker-dir",
"dir/",
"--output-file",
"image.eif",
"--signing-certificate",
"cert.pem",
"--kms-key-id",
"a23f54c8-b2ce-1a5c-a2db-f444a5b3d22d",
"--kms-key-region",
"eu-west-1",
"--private-key",
"key.pem",
];

assert_eq!(app.get_matches_from_safe(args).is_err(), true)
}
}

0 comments on commit 0a4923b

Please sign in to comment.