kanidmd_lib/valueset/
eckey.rs
1use super::ValueSet;
2use crate::be::dbvalue::DbValueSetV2;
3use crate::prelude::*;
4use crate::value::{PartialValue, SyntaxType, Value};
5use crate::valueset::ScimResolveStatus;
6use openssl::ec::EcKey;
7use openssl::pkey::{Private, Public};
8use std::iter::{self};
9
10#[derive(Debug, Clone)]
11struct EcKeyPrivate {
12 priv_key: EcKey<Private>,
13 pub_key: EcKey<Public>,
14}
15
16#[derive(Debug, Clone)]
17pub struct ValueSetEcKeyPrivate {
18 set: Option<EcKeyPrivate>,
19}
20
21impl ValueSetEcKeyPrivate {
22 pub fn new(key: &EcKey<Private>) -> Box<Self> {
23 #[allow(clippy::expect_used)]
24 let pub_key = Self::private_key_to_public_key(key).expect(
25 "Unable to retrieve public key from private key, likely corrupted. You must restore from backup.",
26 );
27
28 Box::new(ValueSetEcKeyPrivate {
29 set: Some(EcKeyPrivate {
30 priv_key: key.clone(),
31 pub_key,
32 }),
33 })
34 }
35
36 fn push(&mut self, key: &EcKey<Private>) -> bool {
37 #[allow(clippy::expect_used)]
38 let pub_key = Self::private_key_to_public_key(key).expect(
39 "Unable to retrieve public key from private key, likely corrupted. You must restore from backup.",
40 );
41 self.set = Some(EcKeyPrivate {
42 priv_key: key.clone(),
43 pub_key,
44 });
45 true
46 }
47
48 fn valueset_from_key_der(key_der: &[u8]) -> Result<ValueSet, OperationError> {
49 let option_key = EcKey::private_key_from_der(key_der);
50 if let Ok(key) = option_key {
51 Ok(Self::new(&key))
52 } else {
53 Err(OperationError::InvalidDbState)
54 }
55 }
56
57 fn private_key_to_public_key(private_key: &EcKey<Private>) -> Option<EcKey<Public>> {
58 let public_key = private_key.public_key();
59 let group = private_key.group();
60 EcKey::from_public_key(group, public_key).ok()
61 }
62
63 pub fn from_dbvs2(key_der: &[u8]) -> Result<ValueSet, OperationError> {
64 Self::valueset_from_key_der(key_der)
65 }
66}
67
68impl ValueSetT for ValueSetEcKeyPrivate {
69 fn insert_checked(&mut self, value: crate::value::Value) -> Result<bool, OperationError> {
70 match value {
71 Value::EcKeyPrivate(k) => Ok(self.push(&k)),
72 _ => {
73 debug_assert!(false);
74 Err(OperationError::InvalidValueState)
75 }
76 }
77 }
78
79 fn clear(&mut self) {
80 self.set = None;
81 }
82
83 fn remove(&mut self, _pv: &crate::value::PartialValue, _cid: &Cid) -> bool {
84 false
85 }
86
87 fn contains(&self, _pv: &crate::value::PartialValue) -> bool {
88 false
89 }
90
91 fn substring(&self, _pv: &crate::value::PartialValue) -> bool {
92 false
93 }
94
95 fn startswith(&self, _pv: &PartialValue) -> bool {
96 false
97 }
98
99 fn endswith(&self, _pv: &PartialValue) -> bool {
100 false
101 }
102
103 fn lessthan(&self, _pv: &crate::value::PartialValue) -> bool {
104 false
105 }
106
107 fn len(&self) -> usize {
108 1
109 }
110
111 fn generate_idx_eq_keys(&self) -> Vec<String> {
112 Vec::with_capacity(0)
113 }
114
115 fn syntax(&self) -> SyntaxType {
116 SyntaxType::EcKeyPrivate
117 }
118
119 fn validate(&self, _schema_attr: &crate::schema::SchemaAttribute) -> bool {
120 match self.set.as_ref() {
121 Some(key) => key.priv_key.check_key().is_ok() && key.pub_key.check_key().is_ok(),
122 None => false,
123 }
124 }
125
126 fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
127 Box::new(iter::once(String::from("hidden")))
128 }
129
130 fn to_scim_value(&self) -> Option<ScimResolveStatus> {
131 None
132 }
133
134 fn to_db_valueset_v2(&self) -> DbValueSetV2 {
135 #[allow(clippy::expect_used)]
136 let key_der = self
137 .set
138 .as_ref()
139 .map(|key| {
140 key.priv_key.private_key_to_der().expect(
141 "Unable to process eckey to der, likely corrupted. You must restore from backup.",
142 )
143 })
144 .unwrap_or_default();
145 DbValueSetV2::EcKeyPrivate(key_der)
146 }
147
148 fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = crate::value::PartialValue> + '_> {
149 Box::new(iter::once(PartialValue::SecretValue))
150 }
151
152 fn to_value_iter(&self) -> Box<dyn Iterator<Item = crate::value::Value> + '_> {
153 match &self.set {
154 Some(key) => Box::new(iter::once(Value::EcKeyPrivate(key.priv_key.clone()))),
155 None => Box::new(iter::empty::<Value>()),
156 }
157 }
158
159 fn equal(&self, other: &super::ValueSet) -> bool {
160 #[allow(clippy::expect_used)]
161 other.as_ec_key_private().is_some_and(|other_key| {
162 self.set.as_ref().is_some_and(|key| {
163 key.priv_key
164 .private_key_to_der()
165 .expect("Failed to retrieve key der")
166 == other_key
167 .private_key_to_der()
168 .expect("Failed to retrieve key der")
169 })
170 })
171 }
172
173 fn merge(&mut self, other: &super::ValueSet) -> Result<(), OperationError> {
174 if let Some(other_key) = other.as_ec_key_private() {
175 let priv_key = other_key.clone();
176 let pub_key = Self::private_key_to_public_key(&priv_key)
177 .ok_or(OperationError::CryptographyError)?;
178 self.set = Some(EcKeyPrivate { pub_key, priv_key });
179 Ok(())
180 } else {
181 debug_assert!(false);
182 Err(OperationError::InvalidValueState)
183 }
184 }
185
186 fn as_ec_key_private(&self) -> Option<&EcKey<Private>> {
187 match self.set.as_ref() {
188 Some(key) => Some(&key.priv_key),
189 None => None,
190 }
191 }
192
193 fn to_eckey_private_single(&self) -> Option<&EcKey<Private>> {
194 match self.set.as_ref() {
195 Some(key) => Some(&key.priv_key),
196 None => None,
197 }
198 }
199
200 fn to_eckey_public_single(&self) -> Option<&EcKey<Public>> {
201 match self.set.as_ref() {
202 Some(key) => Some(&key.pub_key),
203 None => None,
204 }
205 }
206}