in eif_build/src/main.rs [42:315]
fn main() {
let now = Utc::now().to_rfc3339();
let build_tool = env!("CARGO_PKG_NAME").to_string();
let build_tool_version = env!("CARGO_PKG_VERSION").to_string();
let img_os = "OS".to_string();
let img_kernel = "kernel".to_string();
let matches = App::new("Enclave image format builder")
.about("Builds an eif file")
.arg(
Arg::with_name("kernel")
.long("kernel")
.value_name("FILE")
.required(true)
.help("Sets path to a bzImage/Image file for x86_64/aarch64 architecture")
.takes_value(true),
)
.arg(
Arg::with_name("kernel_config")
.long("kernel_config")
.value_name("FILE")
.help("Sets path to a bzImage.config/Image.config file for x86_64/aarch64 architecture")
.takes_value(true),
)
.arg(
Arg::with_name("cmdline")
.long("cmdline")
.help("Sets the cmdline")
.value_name("String")
.required(true)
.takes_value(true),
)
.arg(
Arg::with_name("output")
.long("output")
.help("Specify output file path")
.value_name("FILE")
.required(true)
.takes_value(true),
)
.arg(
Arg::with_name("ramdisk")
.long("ramdisk")
.value_name("FILE")
.required(true)
.help("Sets path to a ramdisk file representing a cpio.gz archive")
.takes_value(true)
.multiple(true)
.number_of_values(1),
)
.arg(
Arg::with_name("signing-certificate")
.long("signing-certificate")
.help("Specify the path to the signing certificate")
.takes_value(true)
.requires("private-key"),
)
.arg(
Arg::with_name("private-key")
.long("private-key")
.help("Path to a local key or KMS key ARN")
.takes_value(true)
.requires("signing-certificate"),
)
.arg(
Arg::with_name("image_name")
.long("name")
.help("Name for enclave image")
.takes_value(true),
)
.arg(
Arg::with_name("image_version")
.long("version")
.help("Version of the enclave image")
.takes_value(true),
)
.arg(
Arg::with_name("metadata")
.long("metadata")
.help("Path to JSON containing the custom metadata provided by the user.")
.takes_value(true),
)
.arg(
Arg::with_name("arch")
.long("arch")
.help("Sets image architecture")
.default_value("x86_64")
.value_parser(["x86_64", "aarch64"])
.takes_value(true),
)
.arg(
Arg::with_name("build_time")
.long("build-time")
.help("Overrides image build time.")
.default_value(&now)
.takes_value(true),
)
.arg(
Arg::with_name("build_tool")
.long("build-tool")
.help("Image build tool name.")
.default_value(&build_tool)
.takes_value(true),
)
.arg(
Arg::with_name("build_tool_version")
.long("build-tool-version")
.help("Overrides image build tool version.")
.default_value(&build_tool_version)
.takes_value(true),
)
.arg(
Arg::with_name("img_os")
.long("img-os")
.help("Overrides image Operating System name.")
.default_value(&img_os)
.takes_value(true),
)
.arg(
Arg::with_name("img_kernel")
.long("img-kernel")
.help("Overrides image Operating System kernel version.")
.default_value(&img_kernel)
.takes_value(true),
)
.arg(
Arg::with_name("algo")
.long("algo")
.help("Sets algorithm to be used for measuring the image")
.possible_values(["sha256", "sha384", "sha512"])
.default_value("sha384")
)
.get_matches();
let arch = matches.value_of("arch").expect("default value");
let kernel_path = matches
.value_of("kernel")
.expect("Kernel path is a mandatory option");
let cmdline = matches
.value_of("cmdline")
.expect("Cmdline is a mandatory option");
let ramdisks: Vec<&str> = matches
.values_of("ramdisk")
.expect("At least one ramdisk should be specified")
.collect();
let output_path = matches
.value_of("output")
.expect("Output file should be provided");
let signing_certificate = matches.value_of("signing-certificate");
let private_key = matches.value_of("private-key");
let sign_info = match (private_key, signing_certificate) {
(Some(key), Some(cert)) => SignKeyData::new(key, Path::new(&cert)).map_or_else(
|e| {
eprintln!("Could not read signing info: {:?}", e);
None
},
Some,
),
_ => None,
};
let img_name = matches.value_of("image_name").map(|val| val.to_string());
let img_version = matches.value_of("image_name").map(|val| val.to_string());
let metadata_path = matches.value_of("metadata").map(|val| val.to_string());
let metadata = match metadata_path {
Some(ref path) => {
parse_custom_metadata(path).expect("Can not parse specified metadata file")
}
None => json!(null),
};
let mut build_info = EifBuildInfo {
build_time: matches
.get_one::<String>("build_time")
.expect("default value")
.to_string(),
build_tool: matches
.get_one::<String>("build_tool")
.expect("default value")
.to_string(),
build_tool_version: matches
.get_one::<String>("build_tool_version")
.expect("default value")
.to_string(),
img_os: matches
.get_one::<String>("img_os")
.expect("default value")
.to_string(),
img_kernel: matches
.get_one::<String>("img_kernel")
.expect("default value")
.to_string(),
};
if let Some(kernel_config) = matches.get_one::<String>("kernel_config") {
build_info = generate_build_info!(kernel_config).expect("Can not generate build info");
}
if matches.value_source("build_time") == Some(CommandLine) {
build_info.build_time = matches
.get_one::<String>("build_time")
.expect("default value")
.to_string();
}
if matches.value_source("build_tool") == Some(CommandLine) {
build_info.build_tool = matches
.get_one::<String>("build_tool")
.expect("default_value")
.to_string();
}
if matches.value_source("build_tool_version") == Some(CommandLine) {
build_info.build_tool_version = matches
.get_one::<String>("build_tool_version")
.expect("default value")
.to_string();
}
if matches.value_source("img_os") == Some(CommandLine) {
build_info.img_os = matches
.get_one::<String>("img_os")
.expect("default value")
.to_string();
}
if matches.value_source("img_kernel") == Some(CommandLine) {
build_info.img_kernel = matches
.get_one::<String>("img_kernel")
.expect("default value")
.to_string();
}
let eif_info = EifIdentityInfo {
img_name: img_name.unwrap_or_else(|| {
// Set default value to kernel file name
Path::new(kernel_path)
.file_name()
.expect("Valid kernel file path should be provided")
.to_str()
.unwrap()
.to_string()
}),
img_version: img_version.unwrap_or_else(|| "1.0".to_string()),
build_info,
docker_info: json!(null),
custom_info: metadata,
};
let params = EifBuildParameters {
kernel_path,
cmdline,
ramdisks,
output_path,
sign_info,
eif_info,
arch,
};
let algo = matches
.value_of("algo")
.expect("Clap must specify default value");
match algo {
"sha256" => build_eif(params, Sha256::new()),
"sha512" => build_eif(params, Sha512::new()),
"sha384" => build_eif(params, Sha384::new()),
_ => unreachable!("Clap guarantees that we get only the specified values"),
}
}