Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: retrieve certificate/public key from private key attributes #279

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions crate/server/src/core/certificate/find.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use cosmian_kmip::kmip::{
kmip_objects::Object,
kmip_types::{LinkType, LinkedObjectIdentifier},
};
use cosmian_kmip::kmip::kmip_types::{LinkType, LinkedObjectIdentifier};
use cosmian_kms_client::access::ObjectOperationType;
use tracing::trace;

use crate::{
core::{extra_database_params::ExtraDatabaseParams, KMS},
Expand All @@ -26,6 +24,11 @@ pub(crate) async fn retrieve_issuer_private_key_and_certificate(
user: &str,
params: Option<&ExtraDatabaseParams>,
) -> KResult<(ObjectWithMetadata, ObjectWithMetadata)> {
trace!(
"Retrieving issuer private key and certificate: private_key_id: {:?}, certificate_id: {:?}",
private_key_id,
certificate_id
);
if let (Some(private_key_id), Some(certificate_id)) = (&private_key_id, &certificate_id) {
// Retrieve the certificate
let certificate = retrieve_object_for_operation(
Expand Down Expand Up @@ -57,7 +60,7 @@ pub(crate) async fn retrieve_issuer_private_key_and_certificate(
)
.await?;
let certificate = retrieve_certificate_for_private_key(
&private_key.object,
&private_key,
ObjectOperationType::Certify,
kms,
user,
Expand Down Expand Up @@ -96,27 +99,25 @@ pub(crate) async fn retrieve_issuer_private_key_and_certificate(

/// Retrieve the certificate associated to the given private key
pub(crate) async fn retrieve_certificate_for_private_key(
private_key: &Object,
private_key: &ObjectWithMetadata,
operation_type: ObjectOperationType,
kms: &KMS,
user: &str,
params: Option<&ExtraDatabaseParams>,
) -> Result<ObjectWithMetadata, KmsError> {
// recover the Certificate Link inside the Private Key
let attributes = private_key.attributes().map_err(|_| {
KmsError::InvalidRequest(
"PKCS#12 export: no attributes found in the Private Key".to_string(),
)
})?;
let certificate_id = attributes
trace!("Private Key attributes: {:?}", private_key.attributes);
let certificate_id = private_key
.attributes
.get_link(LinkType::PKCS12CertificateLink)
.or_else(|| attributes.get_link(LinkType::CertificateLink));
.or_else(|| private_key.attributes.get_link(LinkType::CertificateLink));

let certificate_id = if let Some(certificate_id) = certificate_id {
certificate_id
} else {
// check if there is a link to a public key
let public_key_id = attributes
let public_key_id = private_key
.attributes
.get_link(LinkType::PublicKeyLink)
.ok_or_else(|| {
KmsError::InvalidRequest("No public key link found for the private key".to_string())
Expand Down Expand Up @@ -222,9 +223,8 @@ async fn find_link_in_public_key(
params,
)
.await?;
let public_key_attributes = public_key_owm.object.attributes().with_context(|| {
format!("could not retrieve the public key attributes: {public_key_id}")
})?;
trace!("Public Key attributes: {:?}", public_key_owm.attributes);
let public_key_attributes = public_key_owm.attributes;
// retrieve the private key linked to the public key
public_key_attributes.get_link(link_type).ok_or_else(|| {
KmsError::InvalidRequest(format!("No {link_type:?} found in the public key"))
Expand Down
20 changes: 9 additions & 11 deletions crate/server/src/core/operations/certify/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,26 +132,24 @@ pub async fn certify(
unique_identifier,
)
}
Subject::KeypairAndSubjectName(unique_identifier, keypair_data, _) => {
Subject::KeypairAndSubjectName(unique_identifier, mut keypair_data, _) => {
// update the private key attributes with the public key identifier
let mut private_key_attributes = keypair_data.private_key_object.attributes()?.clone();
private_key_attributes.add_link(
keypair_data.private_key_object.attributes_mut()?.add_link(
LinkType::PublicKeyLink,
LinkedObjectIdentifier::from(keypair_data.public_key_id.clone()),
);
// update the private key attributes with a link to the certificate
private_key_attributes.add_link(
keypair_data.private_key_object.attributes_mut()?.add_link(
LinkType::CertificateLink,
LinkedObjectIdentifier::from(unique_identifier.clone()),
);
// update the public key attributes with a link to the private key
let mut public_key_attributes = keypair_data.public_key_object.attributes()?.clone();
public_key_attributes.add_link(
keypair_data.public_key_object.attributes_mut()?.add_link(
LinkType::PrivateKeyLink,
LinkedObjectIdentifier::from(keypair_data.private_key_id.clone()),
);
// update the public key attributes with a link to the certificate
public_key_attributes.add_link(
keypair_data.public_key_object.attributes_mut()?.add_link(
LinkType::CertificateLink,
LinkedObjectIdentifier::from(unique_identifier.clone()),
);
Expand All @@ -171,16 +169,16 @@ pub async fn certify(
// upsert the private key
AtomicOperation::Upsert((
keypair_data.private_key_id.to_string(),
keypair_data.private_key_object,
private_key_attributes,
keypair_data.private_key_object.clone(),
keypair_data.private_key_object.attributes()?.clone(),
Some(keypair_data.private_key_tags),
StateEnumeration::Active,
)),
// upsert the public key
AtomicOperation::Upsert((
keypair_data.public_key_id.to_string(),
keypair_data.public_key_object,
public_key_attributes,
keypair_data.public_key_object.clone(),
keypair_data.public_key_object.attributes()?.clone(),
Some(keypair_data.public_key_tags),
StateEnumeration::Active,
)),
Expand Down
3 changes: 1 addition & 2 deletions crate/server/src/core/operations/export_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,7 @@ async fn post_process_pkcs12_for_private_key(
.context("export: unable to parse the private key to openssl")?;

let mut cert_owm =
retrieve_certificate_for_private_key(&owm.object, operation_type, kms, user, params)
.await?;
retrieve_certificate_for_private_key(owm, operation_type, kms, user, params).await?;
let certificate = kmip_certificate_to_openssl(&cert_owm.object)?;

// retrieve the certificate chain
Expand Down
5 changes: 5 additions & 0 deletions crate/server/src/core/operations/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,11 @@ fn single_operation(
attributes: Attributes,
uid: String,
) -> AtomicOperation {
// Sync the Object::Attributes with input Attributes
let mut object = object;
if let Ok(object_attributes) = object.attributes_mut() {
object_attributes.clone_from(&attributes);
}
if replace_existing {
AtomicOperation::Upsert((
uid,
Expand Down
6 changes: 1 addition & 5 deletions crate/server/src/core/operations/wrapping/unwrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ pub async fn unwrap_key(
ObjectType::PrivateKey | ObjectType::SymmetricKey => unwrapping_key,
ObjectType::PublicKey | ObjectType::Certificate => {
let attributes = match object_type {
ObjectType::PublicKey => unwrapping_key
.object
.attributes()
.with_context(|| format!("no attributes found for the {object_type}"))?
.clone(),
ObjectType::PublicKey => unwrapping_key.attributes,
ObjectType::Certificate => unwrapping_key.attributes,
_ => unreachable!("unwrap_key: unsupported object type: {object_type}"),
};
Expand Down
2 changes: 1 addition & 1 deletion crate/server/src/core/operations/wrapping/wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub async fn wrap_key(
let wrapping_key = match object_type {
ObjectType::PublicKey | ObjectType::Certificate | ObjectType::SymmetricKey => wrapping_key,
ObjectType::PrivateKey => {
let attributes = wrapping_key.object.attributes()?;
let attributes = wrapping_key.attributes;
let public_key_uid = attributes
.get_link(LinkType::PublicKeyLink)
.or_else(|| attributes.get_link(LinkType::CertificateLink))
Expand Down
2 changes: 1 addition & 1 deletion crate/server/src/database/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ where
let mut res: HashMap<String, ObjectWithMetadata> = HashMap::new();
for row in rows {
let object_with_metadata = ObjectWithMetadata::try_from(&row)?;
trace!("row = {object_with_metadata:?}");
trace!("row = {:?}", serde_json::to_string(&object_with_metadata));

// check if the user, who is not an owner, has the right permissions
if (user != object_with_metadata.owner)
Expand Down
Loading