kanidmd_lib/plugins/
eckeygen.rs1use openssl::ec::{EcGroup, EcKey};
2use openssl::nid::Nid;
3
4use crate::prelude::*;
5use std::sync::Arc;
6
7use super::Plugin;
8
9lazy_static! {
10    static ref DEFAULT_KEY_GROUP: EcGroup = {
13        let nid = Nid::X9_62_PRIME256V1; #[allow(clippy::unwrap_used)]
15        EcGroup::from_curve_name(nid).unwrap()
16    };
17}
18
19pub struct EcdhKeyGen {}
20
21impl EcdhKeyGen {
22    fn generate_key<STATE: Clone>(
24        qs: &mut QueryServerWriteTransaction,
25        cands: &mut [Entry<EntryInvalid, STATE>],
26    ) -> Result<(), OperationError> {
27        let domain_level = qs.get_domain_version();
28        if domain_level >= DOMAIN_LEVEL_12 {
29            trace!("Skipping id key generation");
30            return Ok(());
31        }
32
33        for cand in cands.iter_mut() {
34            if cand.attribute_equality(Attribute::Class, &EntryClass::Person.to_partialvalue())
35                && !cand.attribute_pres(Attribute::IdVerificationEcKey)
36            {
37                debug!(
38                    "Generating {} for {}",
39                    Attribute::IdVerificationEcKey,
40                    cand.get_display_id()
41                );
42
43                let new_private_key = EcKey::generate(&DEFAULT_KEY_GROUP).map_err(|e| {
44                    error!(err = ?e, "Unable to generate id verification ECDH private key");
45                    OperationError::CryptographyError
46                })?;
47                cand.add_ava_if_not_exist(
48                    Attribute::IdVerificationEcKey,
49                    crate::value::Value::EcKeyPrivate(new_private_key),
50                )
51            }
52        }
53        Ok(())
54    }
55}
56
57impl Plugin for EcdhKeyGen {
58    fn id() -> &'static str {
59        "plugin_ecdhkey_gen"
60    }
61
62    #[instrument(level = "debug", name = "ecdhkeygen::pre_create_transform", skip_all)]
63    fn pre_create_transform(
64        qs: &mut QueryServerWriteTransaction,
65        cand: &mut Vec<EntryInvalidNew>,
66        _ce: &CreateEvent,
67    ) -> Result<(), OperationError> {
68        Self::generate_key(qs, cand)
69    }
70
71    #[instrument(level = "debug", name = "ecdhkeygen::pre_modify", skip_all)]
72    fn pre_modify(
73        qs: &mut QueryServerWriteTransaction,
74        _pre_cand: &[Arc<EntrySealedCommitted>],
75        cand: &mut Vec<EntryInvalidCommitted>,
76        _me: &ModifyEvent,
77    ) -> Result<(), OperationError> {
78        Self::generate_key(qs, cand)
79    }
80
81    #[instrument(level = "debug", name = "ecdhkeygen::pre_batch_modify", skip_all)]
82    fn pre_batch_modify(
83        qs: &mut QueryServerWriteTransaction,
84        _pre_cand: &[Arc<EntrySealedCommitted>],
85        cand: &mut Vec<EntryInvalidCommitted>,
86        _me: &BatchModifyEvent,
87    ) -> Result<(), OperationError> {
88        Self::generate_key(qs, cand)
89    }
90}