in key/aziot-keys/src/key_pair.rs [629:736]
fn create_inner(
locations: &[crate::implementation::Location],
preferred_algorithms: &[PreferredAlgorithm],
) -> Result<(), crate::AZIOT_KEYS_RC> {
let location = locations
.first()
.ok_or_else(|| crate::implementation::err_external("no valid location for key pair"))?;
match location {
crate::implementation::Location::Filesystem(path) => {
let preferred_algorithm =
preferred_algorithms.iter().copied().next().ok_or_else(|| {
crate::implementation::err_invalid_parameter(
"preferred_algorithms",
"none specified",
)
})?;
let private_key = match preferred_algorithm {
PreferredAlgorithm::NistP256 => {
let mut group =
openssl::ec::EcGroup::from_curve_name(openssl::nid::Nid::X9_62_PRIME256V1)?;
group.set_asn1_flag(openssl::ec::Asn1Flag::NAMED_CURVE);
let ec_key = openssl::ec::EcKey::generate(&group)?;
let private_key = openssl::pkey::PKey::from_ec_key(ec_key)?;
private_key
}
PreferredAlgorithm::Rsa2048 => {
let rsa = openssl::rsa::Rsa::generate(2048)?;
let private_key = openssl::pkey::PKey::from_rsa(rsa)?;
private_key
}
PreferredAlgorithm::Rsa4096 => {
let rsa = openssl::rsa::Rsa::generate(4096)?;
let private_key = openssl::pkey::PKey::from_rsa(rsa)?;
private_key
}
};
let private_key_pem = private_key.private_key_to_pem_pkcs8()?;
std::fs::write(path, private_key_pem).map_err(crate::implementation::err_external)?;
Ok(())
}
crate::implementation::Location::Pkcs11 { lib_path, uri } => {
let pkcs11_context = pkcs11::Context::load(lib_path.clone())
.map_err(crate::implementation::err_external)?;
let pkcs11_slot = pkcs11_context
.find_slot(&uri.slot_identifier)
.map_err(crate::implementation::err_external)?;
let pkcs11_session = pkcs11_context
.open_session(pkcs11_slot, uri.pin.clone())
.map_err(crate::implementation::err_external)?;
for preferred_algorithm in preferred_algorithms {
match preferred_algorithm {
PreferredAlgorithm::NistP256 => {
if pkcs11_session
.clone()
.generate_ec_key_pair(
openssl2::EcCurve::NistP256,
uri.object_label.as_deref(),
)
.is_ok()
{
return Ok(());
}
}
PreferredAlgorithm::Rsa2048 => {
let exponent = openssl_sys::RSA_F4;
let exponent = exponent.to_be_bytes();
let exponent = openssl::bn::BigNum::from_slice(&exponent)?;
if pkcs11_session
.clone()
.generate_rsa_key_pair(2048, &exponent, uri.object_label.as_deref())
.is_ok()
{
return Ok(());
}
}
PreferredAlgorithm::Rsa4096 => {
let exponent = openssl_sys::RSA_F4;
let exponent = exponent.to_be_bytes();
let exponent = openssl::bn::BigNum::from_slice(&exponent)?;
if pkcs11_session
.clone()
.generate_rsa_key_pair(4096, &exponent, uri.object_label.as_deref())
.is_ok()
{
return Ok(());
}
}
}
}
Err(crate::implementation::err_invalid_parameter(
"preferred_algorithms",
"no algorithm succeeded",
))
}
}
}