blob: c54b5eec11073d7776efaff75cb018000ff7f2e1 [file] [log] [blame]
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001// Copyright 2020, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! KeyParameter is used to express different characteristics of a key requested by the user
16//! and enforced by the OEMs. This module implements the internal representation of KeyParameter
17//! and the methods to work with KeyParameter.
18
Hasini Gunasingheaf993662020-07-24 18:40:20 +000019use crate::error::Error as KeystoreError;
20use crate::error::ResponseCode;
21pub use android_hardware_keymint::aidl::android::hardware::keymint::{
22 Algorithm, Algorithm::Algorithm as AlgorithmType, BlockMode,
23 BlockMode::BlockMode as BlockModeType, Digest, Digest::Digest as DigestType, EcCurve,
24 EcCurve::EcCurve as EcCurveType, HardwareAuthenticatorType,
25 HardwareAuthenticatorType::HardwareAuthenticatorType as HardwareAuthenticatorTypeType,
26 KeyOrigin, KeyOrigin::KeyOrigin as KeyOriginType, KeyPurpose,
27 KeyPurpose::KeyPurpose as KeyPurposeType, PaddingMode,
28 PaddingMode::PaddingMode as PaddingModeType, SecurityLevel,
29 SecurityLevel::SecurityLevel as SecurityLevelType, Tag, Tag::Tag as TagType,
Hasini Gunasinghe12486362020-07-24 18:40:20 +000030};
Hasini Gunasingheaf993662020-07-24 18:40:20 +000031use anyhow::{Context, Result};
32use rusqlite::types::{FromSql, Null, ToSql, ToSqlOutput};
33use rusqlite::{Result as SqlResult, Row};
Hasini Gunasinghe12486362020-07-24 18:40:20 +000034
35/// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced.
36pub struct KeyParameter {
37 key_parameter_value: KeyParameterValue,
Hasini Gunasingheaf993662020-07-24 18:40:20 +000038 security_level: SecurityLevelType,
Hasini Gunasinghe12486362020-07-24 18:40:20 +000039}
40
41/// KeyParameterValue holds a value corresponding to one of the Tags defined in
42/// the AIDL spec at hardware/interfaces/keymint
43#[derive(PartialEq, Debug)]
44pub enum KeyParameterValue {
45 /// Associated with Tag:INVALID
46 Invalid,
47 /// Set of purposes for which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +000048 KeyPurpose(KeyPurposeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000049 /// Cryptographic algorithm with which the key is used
Hasini Gunasingheaf993662020-07-24 18:40:20 +000050 Algorithm(AlgorithmType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000051 /// Size of the key , in bits
Hasini Gunasingheaf993662020-07-24 18:40:20 +000052 KeySize(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000053 /// Block cipher mode(s) with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +000054 BlockMode(BlockModeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000055 /// Digest algorithms that may be used with the key to perform signing and verification
Hasini Gunasingheaf993662020-07-24 18:40:20 +000056 Digest(DigestType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000057 /// Padding modes that may be used with the key. Relevant to RSA, AES and 3DES keys.
Hasini Gunasingheaf993662020-07-24 18:40:20 +000058 PaddingMode(PaddingModeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000059 /// Can the caller provide a nonce for nonce-requiring operations
60 CallerNonce,
61 /// Minimum length of MAC for HMAC keys and AES keys that support GCM mode
Hasini Gunasingheaf993662020-07-24 18:40:20 +000062 MinMacLength(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000063 /// The elliptic curve
Hasini Gunasingheaf993662020-07-24 18:40:20 +000064 EcCurve(EcCurveType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000065 /// Value of the public exponent for an RSA key pair
Hasini Gunasingheaf993662020-07-24 18:40:20 +000066 RSAPublicExponent(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000067 /// An attestation certificate for the generated key should contain an application-scoped
68 /// and time-bounded device-unique ID
69 IncludeUniqueID,
Hasini Gunasingheaf993662020-07-24 18:40:20 +000070 //TODO: find out about this
71 // /// Necessary system environment conditions for the generated key to be used
72 // KeyBlobUsageRequirements(KeyBlobUsageRequirements),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000073 /// Only the boot loader can use the key
74 BootLoaderOnly,
75 /// When deleted, the key is guaranteed to be permanently deleted and unusable
76 RollbackResistance,
Hasini Gunasinghe12486362020-07-24 18:40:20 +000077 /// The date and time at which the key becomes active
Hasini Gunasingheaf993662020-07-24 18:40:20 +000078 ActiveDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000079 /// The date and time at which the key expires for signing and encryption
Hasini Gunasingheaf993662020-07-24 18:40:20 +000080 OriginationExpireDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000081 /// The date and time at which the key expires for verification and decryption
Hasini Gunasingheaf993662020-07-24 18:40:20 +000082 UsageExpireDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000083 /// Minimum amount of time that elapses between allowed operations
Hasini Gunasingheaf993662020-07-24 18:40:20 +000084 MinSecondsBetweenOps(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000085 /// Maximum number of times that a key may be used between system reboots
Hasini Gunasingheaf993662020-07-24 18:40:20 +000086 MaxUsesPerBoot(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000087 /// ID of the Android user that is permitted to use the key
Hasini Gunasingheaf993662020-07-24 18:40:20 +000088 UserID(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000089 /// A key may only be used under a particular secure user authentication state
Hasini Gunasingheaf993662020-07-24 18:40:20 +000090 UserSecureID(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000091 /// No authentication is required to use this key
92 NoAuthRequired,
93 /// The types of user authenticators that may be used to authorize this key
Hasini Gunasingheaf993662020-07-24 18:40:20 +000094 HardwareAuthenticatorType(HardwareAuthenticatorTypeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000095 /// The time in seconds for which the key is authorized for use, after user authentication
Hasini Gunasingheaf993662020-07-24 18:40:20 +000096 AuthTimeout(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000097 /// The key may be used after authentication timeout if device is still on-body
98 AllowWhileOnBody,
99 /// The key must be unusable except when the user has provided proof of physical presence
100 TrustedUserPresenceRequired,
101 /// Applicable to keys with KeyPurpose SIGN, and specifies that this key must not be usable
102 /// unless the user provides confirmation of the data to be signed
103 TrustedConfirmationRequired,
104 /// The key may only be used when the device is unlocked
105 UnlockedDeviceRequired,
106 /// When provided to generateKey or importKey, this tag specifies data
107 /// that is necessary during all uses of the key
108 ApplicationID(Vec<u8>),
109 /// When provided to generateKey or importKey, this tag specifies data
110 /// that is necessary during all uses of the key
111 ApplicationData(Vec<u8>),
112 /// Specifies the date and time the key was created
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000113 CreationDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000114 /// Specifies where the key was created, if known
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000115 KeyOrigin(KeyOriginType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000116 /// The key used by verified boot to validate the operating system booted
117 RootOfTrust(Vec<u8>),
118 /// System OS version with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000119 OSVersion(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000120 /// Specifies the system security patch level with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000121 OSPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000122 /// Specifies a unique, time-based identifier
123 UniqueID(Vec<u8>),
124 /// Used to deliver a "challenge" value to the attestKey() method
125 AttestationChallenge(Vec<u8>),
126 /// The set of applications which may use a key, used only with attestKey()
127 AttestationApplicationID(Vec<u8>),
128 /// Provides the device's brand name, to attestKey()
129 AttestationIdBrand(Vec<u8>),
130 /// Provides the device's device name, to attestKey()
131 AttestationIdDevice(Vec<u8>),
132 /// Provides the device's product name, to attestKey()
133 AttestationIdProduct(Vec<u8>),
134 /// Provides the device's serial number, to attestKey()
135 AttestationIdSerial(Vec<u8>),
136 /// Provides the IMEIs for all radios on the device, to attestKey()
137 AttestationIdIMEI(Vec<u8>),
138 /// Provides the MEIDs for all radios on the device, to attestKey()
139 AttestationIdMEID(Vec<u8>),
140 /// Provides the device's manufacturer name, to attestKey()
141 AttestationIdManufacturer(Vec<u8>),
142 /// Provides the device's model name, to attestKey()
143 AttestationIdModel(Vec<u8>),
144 /// Specifies the vendor image security patch level with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000145 VendorPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000146 /// Specifies the boot image (kernel) security patch level with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000147 BootPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000148 /// Provides "associated data" for AES-GCM encryption or decryption
149 AssociatedData(Vec<u8>),
150 /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM,
151 /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption
152 Nonce(Vec<u8>),
153 /// Provides the requested length of a MAC or GCM authentication tag, in bits
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000154 MacLength(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000155 /// Specifies whether the device has been factory reset since the
156 /// last unique ID rotation. Used for key attestation
157 ResetSinceIdRotation,
158 /// Used to deliver a cryptographic token proving that the user
159 /// confirmed a signing request
160 ConfirmationToken(Vec<u8>),
161}
162
163impl KeyParameter {
164 /// Create an instance of KeyParameter, given the value and the security level.
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000165 pub fn new(key_parameter_value: KeyParameterValue, security_level: SecurityLevelType) -> Self {
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000166 KeyParameter { key_parameter_value, security_level }
167 }
168
169 /// Returns the tag given the KeyParameter instance.
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000170 pub fn get_tag(&self) -> TagType {
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000171 match self.key_parameter_value {
172 KeyParameterValue::Invalid => Tag::INVALID,
173 KeyParameterValue::KeyPurpose(_) => Tag::PURPOSE,
174 KeyParameterValue::Algorithm(_) => Tag::ALGORITHM,
175 KeyParameterValue::KeySize(_) => Tag::KEY_SIZE,
176 KeyParameterValue::BlockMode(_) => Tag::BLOCK_MODE,
177 KeyParameterValue::Digest(_) => Tag::DIGEST,
178 KeyParameterValue::PaddingMode(_) => Tag::PADDING,
179 KeyParameterValue::CallerNonce => Tag::CALLER_NONCE,
180 KeyParameterValue::MinMacLength(_) => Tag::MIN_MAC_LENGTH,
181 KeyParameterValue::EcCurve(_) => Tag::EC_CURVE,
182 KeyParameterValue::RSAPublicExponent(_) => Tag::RSA_PUBLIC_EXPONENT,
183 KeyParameterValue::IncludeUniqueID => Tag::INCLUDE_UNIQUE_ID,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000184 KeyParameterValue::BootLoaderOnly => Tag::BOOTLOADER_ONLY,
185 KeyParameterValue::RollbackResistance => Tag::ROLLBACK_RESISTANCE,
186 KeyParameterValue::ActiveDateTime(_) => Tag::ACTIVE_DATETIME,
187 KeyParameterValue::OriginationExpireDateTime(_) => Tag::ORIGINATION_EXPIRE_DATETIME,
188 KeyParameterValue::UsageExpireDateTime(_) => Tag::USAGE_EXPIRE_DATETIME,
189 KeyParameterValue::MinSecondsBetweenOps(_) => Tag::MIN_SECONDS_BETWEEN_OPS,
190 KeyParameterValue::MaxUsesPerBoot(_) => Tag::MAX_USES_PER_BOOT,
191 KeyParameterValue::UserID(_) => Tag::USER_ID,
192 KeyParameterValue::UserSecureID(_) => Tag::USER_SECURE_ID,
193 KeyParameterValue::NoAuthRequired => Tag::NO_AUTH_REQUIRED,
194 KeyParameterValue::HardwareAuthenticatorType(_) => Tag::USER_AUTH_TYPE,
195 KeyParameterValue::AuthTimeout(_) => Tag::AUTH_TIMEOUT,
196 KeyParameterValue::AllowWhileOnBody => Tag::ALLOW_WHILE_ON_BODY,
197 KeyParameterValue::TrustedUserPresenceRequired => Tag::TRUSTED_USER_PRESENCE_REQUIRED,
198 KeyParameterValue::TrustedConfirmationRequired => Tag::TRUSTED_CONFIRMATION_REQUIRED,
199 KeyParameterValue::UnlockedDeviceRequired => Tag::UNLOCKED_DEVICE_REQUIRED,
200 KeyParameterValue::ApplicationID(_) => Tag::APPLICATION_ID,
201 KeyParameterValue::ApplicationData(_) => Tag::APPLICATION_DATA,
202 KeyParameterValue::CreationDateTime(_) => Tag::CREATION_DATETIME,
203 KeyParameterValue::KeyOrigin(_) => Tag::ORIGIN,
204 KeyParameterValue::RootOfTrust(_) => Tag::ROOT_OF_TRUST,
205 KeyParameterValue::OSVersion(_) => Tag::OS_VERSION,
206 KeyParameterValue::OSPatchLevel(_) => Tag::OS_PATCHLEVEL,
207 KeyParameterValue::UniqueID(_) => Tag::UNIQUE_ID,
208 KeyParameterValue::AttestationChallenge(_) => Tag::ATTESTATION_CHALLENGE,
209 KeyParameterValue::AttestationApplicationID(_) => Tag::ATTESTATION_APPLICATION_ID,
210 KeyParameterValue::AttestationIdBrand(_) => Tag::ATTESTATION_ID_BRAND,
211 KeyParameterValue::AttestationIdDevice(_) => Tag::ATTESTATION_ID_DEVICE,
212 KeyParameterValue::AttestationIdProduct(_) => Tag::ATTESTATION_ID_PRODUCT,
213 KeyParameterValue::AttestationIdSerial(_) => Tag::ATTESTATION_ID_SERIAL,
214 KeyParameterValue::AttestationIdIMEI(_) => Tag::ATTESTATION_ID_IMEI,
215 KeyParameterValue::AttestationIdMEID(_) => Tag::ATTESTATION_ID_MEID,
216 KeyParameterValue::AttestationIdManufacturer(_) => Tag::ATTESTATION_ID_MANUFACTURER,
217 KeyParameterValue::AttestationIdModel(_) => Tag::ATTESTATION_ID_MODEL,
218 KeyParameterValue::VendorPatchLevel(_) => Tag::VENDOR_PATCHLEVEL,
219 KeyParameterValue::BootPatchLevel(_) => Tag::BOOT_PATCHLEVEL,
220 KeyParameterValue::AssociatedData(_) => Tag::ASSOCIATED_DATA,
221 KeyParameterValue::Nonce(_) => Tag::NONCE,
222 KeyParameterValue::MacLength(_) => Tag::MAC_LENGTH,
223 KeyParameterValue::ResetSinceIdRotation => Tag::RESET_SINCE_ID_ROTATION,
224 KeyParameterValue::ConfirmationToken(_) => Tag::CONFIRMATION_TOKEN,
225 }
226 }
227
228 /// Returns key parameter value.
229 pub fn key_parameter_value(&self) -> &KeyParameterValue {
230 &self.key_parameter_value
231 }
232
233 /// Returns the security level of a KeyParameter.
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000234 pub fn security_level(&self) -> &SecurityLevelType {
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000235 &self.security_level
236 }
237}
238
239#[cfg(test)]
240mod basic_tests {
241 use crate::key_parameter::*;
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000242
243 // Test basic functionality of KeyParameter.
244 #[test]
245 fn test_key_parameter() {
246 let key_parameter = KeyParameter::new(
247 KeyParameterValue::Algorithm(Algorithm::RSA),
248 SecurityLevel::STRONGBOX,
249 );
250
251 assert_eq!(key_parameter.get_tag(), Tag::ALGORITHM);
252
253 assert_eq!(
254 *key_parameter.key_parameter_value(),
255 KeyParameterValue::Algorithm(Algorithm::RSA)
256 );
257
258 assert_eq!(*key_parameter.security_level(), SecurityLevel::STRONGBOX);
259 }
260}
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000261
262/// This struct is defined to postpone converting rusqlite column value to the
263/// appropriate key parameter value until we know the corresponding tag value.
264/// Wraps the column index and a rusqlite row.
265pub struct SqlField<'a>(usize, &'a Row<'a>);
266
267impl<'a> SqlField<'a> {
268 /// Returns the column value from the row, when we know the expected type.
269 pub fn get<T: FromSql>(&self) -> SqlResult<T> {
270 self.1.get(self.0)
271 }
272}
273
274impl ToSql for KeyParameterValue {
275 /// Converts KeyParameterValue to be stored in rusqlite database.
276 /// Note that following variants of KeyParameterValue should not be stored:
277 /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID,
278 /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken.
279 /// This filtering is enforced at a higher level (i.e. enforcement module) and here we support
280 /// conversion for all the variants, to keep error handling simple.
281 fn to_sql(&self) -> SqlResult<ToSqlOutput> {
282 match self {
283 KeyParameterValue::Invalid => Ok(ToSqlOutput::from(Null)),
284 KeyParameterValue::KeyPurpose(k) => Ok(ToSqlOutput::from(*k as u32)),
285 KeyParameterValue::Algorithm(a) => Ok(ToSqlOutput::from(*a as u32)),
286 KeyParameterValue::KeySize(k) => Ok(ToSqlOutput::from(*k)),
287 KeyParameterValue::BlockMode(b) => Ok(ToSqlOutput::from(*b as u32)),
288 KeyParameterValue::Digest(d) => Ok(ToSqlOutput::from(*d as u32)),
289 KeyParameterValue::PaddingMode(p) => Ok(ToSqlOutput::from(*p as u32)),
290 KeyParameterValue::CallerNonce => Ok(ToSqlOutput::from(Null)),
291 KeyParameterValue::MinMacLength(m) => Ok(ToSqlOutput::from(*m)),
292 KeyParameterValue::EcCurve(e) => Ok(ToSqlOutput::from(*e as u32)),
293 KeyParameterValue::RSAPublicExponent(r) => Ok(ToSqlOutput::from(*r as i64)),
294 KeyParameterValue::IncludeUniqueID => Ok(ToSqlOutput::from(Null)),
295 KeyParameterValue::BootLoaderOnly => Ok(ToSqlOutput::from(Null)),
296 KeyParameterValue::RollbackResistance => Ok(ToSqlOutput::from(Null)),
297 KeyParameterValue::ActiveDateTime(a) => Ok(ToSqlOutput::from(*a as i64)),
298 KeyParameterValue::OriginationExpireDateTime(o) => Ok(ToSqlOutput::from(*o as i64)),
299 KeyParameterValue::UsageExpireDateTime(u) => Ok(ToSqlOutput::from(*u as i64)),
300 KeyParameterValue::MinSecondsBetweenOps(m) => Ok(ToSqlOutput::from(*m)),
301 KeyParameterValue::MaxUsesPerBoot(m) => Ok(ToSqlOutput::from(*m)),
302 KeyParameterValue::UserID(u) => Ok(ToSqlOutput::from(*u)),
303 KeyParameterValue::UserSecureID(u) => Ok(ToSqlOutput::from(*u as i64)),
304 KeyParameterValue::NoAuthRequired => Ok(ToSqlOutput::from(Null)),
305 KeyParameterValue::HardwareAuthenticatorType(h) => Ok(ToSqlOutput::from(*h as u32)),
306 KeyParameterValue::AuthTimeout(m) => Ok(ToSqlOutput::from(*m)),
307 KeyParameterValue::AllowWhileOnBody => Ok(ToSqlOutput::from(Null)),
308 KeyParameterValue::TrustedUserPresenceRequired => Ok(ToSqlOutput::from(Null)),
309 KeyParameterValue::TrustedConfirmationRequired => Ok(ToSqlOutput::from(Null)),
310 KeyParameterValue::UnlockedDeviceRequired => Ok(ToSqlOutput::from(Null)),
311 KeyParameterValue::ApplicationID(a) => Ok(ToSqlOutput::from(a.to_vec())),
312 KeyParameterValue::ApplicationData(a) => Ok(ToSqlOutput::from(a.to_vec())),
313 KeyParameterValue::CreationDateTime(c) => Ok(ToSqlOutput::from(*c as i64)),
314 KeyParameterValue::KeyOrigin(k) => Ok(ToSqlOutput::from(*k as u32)),
315 KeyParameterValue::RootOfTrust(r) => Ok(ToSqlOutput::from(r.to_vec())),
316 KeyParameterValue::OSVersion(o) => Ok(ToSqlOutput::from(*o)),
317 KeyParameterValue::OSPatchLevel(o) => Ok(ToSqlOutput::from(*o)),
318 KeyParameterValue::UniqueID(u) => Ok(ToSqlOutput::from(u.to_vec())),
319 KeyParameterValue::AttestationChallenge(a) => Ok(ToSqlOutput::from(a.to_vec())),
320 KeyParameterValue::AttestationApplicationID(a) => Ok(ToSqlOutput::from(a.to_vec())),
321 KeyParameterValue::AttestationIdBrand(a) => Ok(ToSqlOutput::from(a.to_vec())),
322 KeyParameterValue::AttestationIdDevice(a) => Ok(ToSqlOutput::from(a.to_vec())),
323 KeyParameterValue::AttestationIdProduct(a) => Ok(ToSqlOutput::from(a.to_vec())),
324 KeyParameterValue::AttestationIdSerial(a) => Ok(ToSqlOutput::from(a.to_vec())),
325 KeyParameterValue::AttestationIdIMEI(a) => Ok(ToSqlOutput::from(a.to_vec())),
326 KeyParameterValue::AttestationIdMEID(a) => Ok(ToSqlOutput::from(a.to_vec())),
327 KeyParameterValue::AttestationIdManufacturer(a) => Ok(ToSqlOutput::from(a.to_vec())),
328 KeyParameterValue::AttestationIdModel(a) => Ok(ToSqlOutput::from(a.to_vec())),
329 KeyParameterValue::VendorPatchLevel(v) => Ok(ToSqlOutput::from(*v)),
330 KeyParameterValue::BootPatchLevel(b) => Ok(ToSqlOutput::from(*b)),
331 KeyParameterValue::AssociatedData(a) => Ok(ToSqlOutput::from(a.to_vec())),
332 KeyParameterValue::Nonce(n) => Ok(ToSqlOutput::from(n.to_vec())),
333 KeyParameterValue::MacLength(m) => Ok(ToSqlOutput::from(*m)),
334 KeyParameterValue::ResetSinceIdRotation => Ok(ToSqlOutput::from(Null)),
335 KeyParameterValue::ConfirmationToken(c) => Ok(ToSqlOutput::from(c.to_vec())),
336 }
337 }
338}
339
340fn format_context_for_enums(enum_name: &'static str) -> impl FnOnce() -> String {
341 move || format!("Failed to decode {} enum from value.", enum_name)
342}
343
344fn format_context_for_sql_data(tag_name: &'static str) -> impl FnOnce() -> String {
345 move || format!("Failed to read sql data for tag: {}.", tag_name)
346}
347
348impl KeyParameter {
349 /// Construct a KeyParameter from the data from a rusqlite row.
350 /// Note that following variants of KeyParameterValue should not be stored:
351 /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID,
352 /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken.
353 /// This filtering is enforced at a higher level and here we support conversion for all the
354 /// variants.
355 pub fn new_from_sql(
356 tag_val: TagType,
357 data: &SqlField,
358 security_level_val: SecurityLevelType,
359 ) -> Result<Self> {
360 let key_param_value = match tag_val {
361 Tag::INVALID => KeyParameterValue::Invalid,
362 Tag::PURPOSE => {
363 let key_purpose: KeyPurposeType = data
364 .get()
365 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
366 .with_context(format_context_for_sql_data("PURPOSE"))?;
367 KeyParameterValue::KeyPurpose(key_purpose)
368 }
369 Tag::ALGORITHM => {
370 let algorithm: AlgorithmType = data
371 .get()
372 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
373 .with_context(format_context_for_sql_data("ALGORITHM"))?;
374 KeyParameterValue::Algorithm(algorithm)
375 }
376 Tag::KEY_SIZE => {
377 let key_size: i32 =
378 data.get().with_context(format_context_for_sql_data("KEY_SIZE"))?;
379 KeyParameterValue::KeySize(key_size)
380 }
381 Tag::BLOCK_MODE => {
382 let block_mode: BlockModeType = data
383 .get()
384 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
385 .with_context(format_context_for_sql_data("BLOCK_MODE"))?;
386 KeyParameterValue::BlockMode(block_mode)
387 }
388 Tag::DIGEST => {
389 let digest: DigestType = data
390 .get()
391 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
392 .with_context(format_context_for_sql_data("DIGEST"))?;
393 KeyParameterValue::Digest(digest)
394 }
395 Tag::PADDING => {
396 let padding: PaddingModeType = data
397 .get()
398 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
399 .with_context(format_context_for_sql_data("PADDING"))?;
400 KeyParameterValue::PaddingMode(padding)
401 }
402 Tag::CALLER_NONCE => KeyParameterValue::CallerNonce,
403 Tag::MIN_MAC_LENGTH => {
404 let min_mac_length: i32 =
405 data.get().with_context(format_context_for_sql_data("MIN_MAC_LENGTH"))?;
406 KeyParameterValue::MinMacLength(min_mac_length)
407 }
408 Tag::EC_CURVE => {
409 let ec_curve: EcCurveType = data
410 .get()
411 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
412 .with_context(format_context_for_sql_data("EC_CURVE"))?;
413 KeyParameterValue::EcCurve(ec_curve)
414 }
415 Tag::RSA_PUBLIC_EXPONENT => {
416 let rsa_pub_exponent: i64 =
417 data.get().with_context(format_context_for_sql_data("RSA_PUBLIC_EXPONENT"))?;
418
419 KeyParameterValue::RSAPublicExponent(rsa_pub_exponent)
420 }
421 Tag::INCLUDE_UNIQUE_ID => KeyParameterValue::IncludeUniqueID,
422 Tag::BOOTLOADER_ONLY => KeyParameterValue::BootLoaderOnly,
423 Tag::ROLLBACK_RESISTANCE => KeyParameterValue::RollbackResistance,
424 Tag::ACTIVE_DATETIME => {
425 let active_datetime: i64 =
426 data.get().with_context(format_context_for_sql_data("ACTIVE_DATETIME"))?;
427 KeyParameterValue::ActiveDateTime(active_datetime)
428 }
429 Tag::ORIGINATION_EXPIRE_DATETIME => {
430 let origination_expire_datetime: i64 = data
431 .get()
432 .with_context(format_context_for_sql_data("ORIGINATION_EXPIRE_DATETIME"))?;
433 KeyParameterValue::OriginationExpireDateTime(origination_expire_datetime)
434 }
435 Tag::USAGE_EXPIRE_DATETIME => {
436 let usage_expire_datetime: i64 = data
437 .get()
438 .with_context(format_context_for_sql_data("USAGE_EXPIRE_DATETIME"))?;
439 KeyParameterValue::UsageExpireDateTime(usage_expire_datetime)
440 }
441 Tag::MIN_SECONDS_BETWEEN_OPS => {
442 let min_secs_between_ops: i32 = data
443 .get()
444 .with_context(format_context_for_sql_data("MIN_SECONDS_BETWEEN_OPS"))?;
445 KeyParameterValue::MinSecondsBetweenOps(min_secs_between_ops)
446 }
447 Tag::MAX_USES_PER_BOOT => {
448 let max_uses_per_boot: i32 =
449 data.get().with_context(format_context_for_sql_data("MAX_USES_PER_BOOT"))?;
450 KeyParameterValue::MaxUsesPerBoot(max_uses_per_boot)
451 }
452 Tag::USER_ID => {
453 let user_id: i32 =
454 data.get().with_context(format_context_for_sql_data("USER_ID"))?;
455 KeyParameterValue::UserID(user_id)
456 }
457 Tag::USER_SECURE_ID => {
458 let user_secure_id: i64 =
459 data.get().with_context(format_context_for_sql_data("USER_SECURE_ID"))?;
460 KeyParameterValue::UserSecureID(user_secure_id)
461 }
462 Tag::NO_AUTH_REQUIRED => KeyParameterValue::NoAuthRequired,
463 Tag::USER_AUTH_TYPE => {
464 let user_auth_type: HardwareAuthenticatorTypeType = data
465 .get()
466 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
467 .with_context(format_context_for_sql_data("USER_AUTH_TYPE"))?;
468 KeyParameterValue::HardwareAuthenticatorType(user_auth_type)
469 }
470 Tag::AUTH_TIMEOUT => {
471 let auth_timeout: i32 =
472 data.get().with_context(format_context_for_sql_data("AUTH_TIMEOUT"))?;
473 KeyParameterValue::AuthTimeout(auth_timeout)
474 }
475 Tag::ALLOW_WHILE_ON_BODY => KeyParameterValue::AllowWhileOnBody,
476 Tag::TRUSTED_USER_PRESENCE_REQUIRED => KeyParameterValue::TrustedUserPresenceRequired,
477 Tag::TRUSTED_CONFIRMATION_REQUIRED => KeyParameterValue::TrustedConfirmationRequired,
478 Tag::UNLOCKED_DEVICE_REQUIRED => KeyParameterValue::UnlockedDeviceRequired,
479 Tag::APPLICATION_ID => {
480 let app_id: Vec<u8> =
481 data.get().with_context(format_context_for_sql_data("APPLICATION_ID"))?;
482 KeyParameterValue::ApplicationID(app_id)
483 }
484 Tag::APPLICATION_DATA => {
485 let app_data: Vec<u8> =
486 data.get().with_context(format_context_for_sql_data("APPLICATION_DATA"))?;
487 KeyParameterValue::ApplicationData(app_data)
488 }
489 Tag::CREATION_DATETIME => {
490 let creation_datetime: i64 =
491 data.get().with_context(format_context_for_sql_data("CREATION_DATETIME"))?;
492 KeyParameterValue::CreationDateTime(creation_datetime)
493 }
494 Tag::ORIGIN => {
495 let origin: KeyOriginType = data
496 .get()
497 .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
498 .with_context(format_context_for_sql_data("ORIGIN"))?;
499 KeyParameterValue::KeyOrigin(origin)
500 }
501 Tag::ROOT_OF_TRUST => {
502 let root_of_trust: Vec<u8> =
503 data.get().with_context(format_context_for_sql_data("ROOT_OF_TRUST"))?;
504 KeyParameterValue::RootOfTrust(root_of_trust)
505 }
506 Tag::OS_VERSION => {
507 let os_version: i32 =
508 data.get().with_context(format_context_for_sql_data("OS_VERSION"))?;
509 KeyParameterValue::OSVersion(os_version)
510 }
511 Tag::OS_PATCHLEVEL => {
512 let os_patch_level: i32 =
513 data.get().with_context(format_context_for_sql_data("OS_PATCHLEVEL"))?;
514 KeyParameterValue::OSPatchLevel(os_patch_level)
515 }
516 Tag::UNIQUE_ID => {
517 let unique_id: Vec<u8> =
518 data.get().with_context(format_context_for_sql_data("UNIQUE_ID"))?;
519 KeyParameterValue::UniqueID(unique_id)
520 }
521 Tag::ATTESTATION_CHALLENGE => {
522 let attestation_challenge: Vec<u8> = data
523 .get()
524 .with_context(format_context_for_sql_data("ATTESTATION_CHALLENGE"))?;
525 KeyParameterValue::AttestationChallenge(attestation_challenge)
526 }
527 Tag::ATTESTATION_APPLICATION_ID => {
528 let attestation_app_id: Vec<u8> = data
529 .get()
530 .with_context(format_context_for_sql_data("ATTESTATION_APPLICATION_ID"))?;
531 KeyParameterValue::AttestationApplicationID(attestation_app_id)
532 }
533 Tag::ATTESTATION_ID_BRAND => {
534 let attestation_id_brand: Vec<u8> =
535 data.get().with_context(format_context_for_sql_data("ATTESTATION_ID_BRAND"))?;
536 KeyParameterValue::AttestationIdBrand(attestation_id_brand)
537 }
538 Tag::ATTESTATION_ID_DEVICE => {
539 let attestation_id_device: Vec<u8> = data
540 .get()
541 .with_context(format_context_for_sql_data("ATTESTATION_ID_DEVICE"))?;
542 KeyParameterValue::AttestationIdDevice(attestation_id_device)
543 }
544 Tag::ATTESTATION_ID_PRODUCT => {
545 let attestation_id_product: Vec<u8> = data
546 .get()
547 .with_context(format_context_for_sql_data("ATTESTATION_ID_PRODUCT"))?;
548 KeyParameterValue::AttestationIdProduct(attestation_id_product)
549 }
550 Tag::ATTESTATION_ID_SERIAL => {
551 let attestation_id_serial: Vec<u8> = data
552 .get()
553 .with_context(format_context_for_sql_data("ATTESTATION_ID_SERIAL"))?;
554 KeyParameterValue::AttestationIdSerial(attestation_id_serial)
555 }
556 Tag::ATTESTATION_ID_IMEI => {
557 let attestation_id_imei: Vec<u8> =
558 data.get().with_context(format_context_for_sql_data("ATTESTATION_ID_IMEI"))?;
559 KeyParameterValue::AttestationIdIMEI(attestation_id_imei)
560 }
561 Tag::ATTESTATION_ID_MEID => {
562 let attestation_id_meid: Vec<u8> =
563 data.get().with_context(format_context_for_sql_data("ATTESTATION_ID_MEID"))?;
564 KeyParameterValue::AttestationIdMEID(attestation_id_meid)
565 }
566 Tag::ATTESTATION_ID_MANUFACTURER => {
567 let attestation_id_manufacturer: Vec<u8> = data
568 .get()
569 .with_context(format_context_for_sql_data("ATTESTATION_ID_MANUFACTURER"))?;
570 KeyParameterValue::AttestationIdManufacturer(attestation_id_manufacturer)
571 }
572 Tag::ATTESTATION_ID_MODEL => {
573 let attestation_id_model: Vec<u8> =
574 data.get().with_context(format_context_for_sql_data("ATTESTATION_ID_MODEL"))?;
575 KeyParameterValue::AttestationIdModel(attestation_id_model)
576 }
577 Tag::VENDOR_PATCHLEVEL => {
578 let vendor_patch_level: i32 =
579 data.get().with_context(format_context_for_sql_data("VENDOR_PATCHLEVEL"))?;
580 KeyParameterValue::VendorPatchLevel(vendor_patch_level)
581 }
582 Tag::BOOT_PATCHLEVEL => {
583 let boot_patch_level: i32 =
584 data.get().with_context(format_context_for_sql_data("BOOT_PATCHLEVEL"))?;
585 KeyParameterValue::BootPatchLevel(boot_patch_level)
586 }
587 Tag::ASSOCIATED_DATA => {
588 let associated_data: Vec<u8> =
589 data.get().with_context(format_context_for_sql_data("ASSOCIATED_DATA"))?;
590 KeyParameterValue::AssociatedData(associated_data)
591 }
592 Tag::NONCE => {
593 let nonce: Vec<u8> =
594 data.get().with_context(format_context_for_sql_data("NONCE"))?;
595 KeyParameterValue::Nonce(nonce)
596 }
597 Tag::MAC_LENGTH => {
598 let mac_length: i32 =
599 data.get().with_context(format_context_for_sql_data("MAC_LENGTH"))?;
600 KeyParameterValue::MacLength(mac_length)
601 }
602 Tag::RESET_SINCE_ID_ROTATION => KeyParameterValue::ResetSinceIdRotation,
603 Tag::CONFIRMATION_TOKEN => {
604 let confirmation_token: Vec<u8> =
605 data.get().with_context(format_context_for_sql_data("CONFIRMATION_TOKEN"))?;
606 KeyParameterValue::ConfirmationToken(confirmation_token)
607 }
608 _ => {
609 return Err(KeystoreError::Rc(ResponseCode::ValueCorrupted))
610 .with_context(format_context_for_enums("Tag"))?
611 }
612 };
613 Ok(KeyParameter::new(key_param_value, security_level_val))
614 }
615}
616
617/// The storage_tests module first tests the 'new_from_sql' method for KeyParameters of different
618/// data types and then tests 'to_sql' method for KeyParameters of those
619/// different data types. The five different data types for KeyParameter values are:
620/// i) enums of u32
621/// ii) u32
622/// iii) u64
623/// iv) Vec<u8>
624/// v) bool
625#[cfg(test)]
626mod storage_tests {
627 use crate::error::*;
628 use crate::key_parameter::*;
629 use anyhow::Result;
630 use rusqlite::types::ToSql;
631 use rusqlite::{params, Connection, NO_PARAMS};
632
633 /// Test initializing a KeyParameter (with key parameter value corresponding to an enum of i32)
634 /// from a database table row.
635 #[test]
636 fn test_new_from_sql_enum_i32() -> Result<()> {
637 let db = init_db()?;
638 insert_into_keyparameter(
639 &db,
640 1,
641 Tag::ALGORITHM,
642 &Algorithm::RSA,
643 SecurityLevel::STRONGBOX,
644 )?;
645 let key_param = query_from_keyparameter(&db)?;
646 assert_eq!(Tag::ALGORITHM, key_param.get_tag());
647 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::Algorithm(Algorithm::RSA));
648 assert_eq!(*key_param.security_level(), SecurityLevel::STRONGBOX);
649 Ok(())
650 }
651
652 /// Test initializing a KeyParameter (with key parameter value which is of i32)
653 /// from a database table row.
654 #[test]
655 fn test_new_from_sql_i32() -> Result<()> {
656 let db = init_db()?;
657 insert_into_keyparameter(&db, 1, Tag::KEY_SIZE, &1024, SecurityLevel::STRONGBOX)?;
658 let key_param = query_from_keyparameter(&db)?;
659 assert_eq!(Tag::KEY_SIZE, key_param.get_tag());
660 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::KeySize(1024));
661 Ok(())
662 }
663
664 /// Test initializing a KeyParameter (with key parameter value which is of i64)
665 /// from a database table row.
666 #[test]
667 fn test_new_from_sql_i64() -> Result<()> {
668 let db = init_db()?;
669 // max value for i64, just to test corner cases
670 insert_into_keyparameter(
671 &db,
672 1,
673 Tag::RSA_PUBLIC_EXPONENT,
674 &(i64::MAX),
675 SecurityLevel::STRONGBOX,
676 )?;
677 let key_param = query_from_keyparameter(&db)?;
678 assert_eq!(Tag::RSA_PUBLIC_EXPONENT, key_param.get_tag());
679 assert_eq!(
680 *key_param.key_parameter_value(),
681 KeyParameterValue::RSAPublicExponent(i64::MAX)
682 );
683 Ok(())
684 }
685
686 /// Test initializing a KeyParameter (with key parameter value which is of bool)
687 /// from a database table row.
688 #[test]
689 fn test_new_from_sql_bool() -> Result<()> {
690 let db = init_db()?;
691 insert_into_keyparameter(&db, 1, Tag::CALLER_NONCE, &Null, SecurityLevel::STRONGBOX)?;
692 let key_param = query_from_keyparameter(&db)?;
693 assert_eq!(Tag::CALLER_NONCE, key_param.get_tag());
694 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::CallerNonce);
695 Ok(())
696 }
697
698 /// Test initializing a KeyParameter (with key parameter value which is of Vec<u8>)
699 /// from a database table row.
700 #[test]
701 fn test_new_from_sql_vec_u8() -> Result<()> {
702 let db = init_db()?;
703 let app_id = String::from("MyAppID");
704 let app_id_bytes = app_id.into_bytes();
705 insert_into_keyparameter(
706 &db,
707 1,
708 Tag::APPLICATION_ID,
709 &app_id_bytes,
710 SecurityLevel::STRONGBOX,
711 )?;
712 let key_param = query_from_keyparameter(&db)?;
713 assert_eq!(Tag::APPLICATION_ID, key_param.get_tag());
714 assert_eq!(
715 *key_param.key_parameter_value(),
716 KeyParameterValue::ApplicationID(app_id_bytes)
717 );
718 Ok(())
719 }
720
721 /// Test storing a KeyParameter (with key parameter value which corresponds to an enum of i32)
722 /// in the database
723 #[test]
724 fn test_to_sql_enum_i32() -> Result<()> {
725 let db = init_db()?;
726 let kp = KeyParameter::new(
727 KeyParameterValue::Algorithm(Algorithm::RSA),
728 SecurityLevel::STRONGBOX,
729 );
730 store_keyparameter(&db, 1, &kp)?;
731 let key_param = query_from_keyparameter(&db)?;
732 assert_eq!(kp.get_tag(), key_param.get_tag());
733 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
734 assert_eq!(kp.security_level(), key_param.security_level());
735 Ok(())
736 }
737
738 /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
739 #[test]
740 fn test_to_sql_i32() -> Result<()> {
741 let db = init_db()?;
742 let kp = KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::STRONGBOX);
743 store_keyparameter(&db, 1, &kp)?;
744 let key_param = query_from_keyparameter(&db)?;
745 assert_eq!(kp.get_tag(), key_param.get_tag());
746 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
747 assert_eq!(kp.security_level(), key_param.security_level());
748 Ok(())
749 }
750
751 /// Test storing a KeyParameter (with key parameter value which is of i64) in the database
752 #[test]
753 fn test_to_sql_i64() -> Result<()> {
754 let db = init_db()?;
755 // max value for i64, just to test corner cases
756 let kp = KeyParameter::new(
757 KeyParameterValue::RSAPublicExponent(i64::MAX),
758 SecurityLevel::STRONGBOX,
759 );
760 store_keyparameter(&db, 1, &kp)?;
761 let key_param = query_from_keyparameter(&db)?;
762 assert_eq!(kp.get_tag(), key_param.get_tag());
763 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
764 assert_eq!(kp.security_level(), key_param.security_level());
765 Ok(())
766 }
767
768 /// Test storing a KeyParameter (with key parameter value which is of Vec<u8>) in the database
769 #[test]
770 fn test_to_sql_vec_u8() -> Result<()> {
771 let db = init_db()?;
772 let kp = KeyParameter::new(
773 KeyParameterValue::ApplicationID(String::from("MyAppID").into_bytes()),
774 SecurityLevel::STRONGBOX,
775 );
776 store_keyparameter(&db, 1, &kp)?;
777 let key_param = query_from_keyparameter(&db)?;
778 assert_eq!(kp.get_tag(), key_param.get_tag());
779 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
780 assert_eq!(kp.security_level(), key_param.security_level());
781 Ok(())
782 }
783
784 /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
785 #[test]
786 fn test_to_sql_bool() -> Result<()> {
787 let db = init_db()?;
788 let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
789 store_keyparameter(&db, 1, &kp)?;
790 let key_param = query_from_keyparameter(&db)?;
791 assert_eq!(kp.get_tag(), key_param.get_tag());
792 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
793 assert_eq!(kp.security_level(), key_param.security_level());
794 Ok(())
795 }
796
797 #[test]
798 /// Test Tag::Invalid
799 fn test_invalid_tag() -> Result<()> {
800 let db = init_db()?;
801 insert_into_keyparameter(&db, 1, 0, &123, 1)?;
802 let key_param = query_from_keyparameter(&db)?;
803 assert_eq!(Tag::INVALID, key_param.get_tag());
804 Ok(())
805 }
806
807 #[test]
808 fn test_non_existing_enum_variant() -> Result<()> {
809 let db = init_db()?;
810 insert_into_keyparameter(&db, 1, 100, &123, 1)?;
811 tests::check_result_contains_error_string(
812 query_from_keyparameter(&db),
813 "Failed to decode Tag enum from value.",
814 );
815 Ok(())
816 }
817
818 #[test]
819 fn test_invalid_conversion_from_sql() -> Result<()> {
820 let db = init_db()?;
821 insert_into_keyparameter(&db, 1, Tag::ALGORITHM, &Null, 1)?;
822 tests::check_result_contains_error_string(
823 query_from_keyparameter(&db),
824 "Failed to read sql data for tag: ALGORITHM.",
825 );
826 Ok(())
827 }
828
829 /// Helper method to init database table for key parameter
830 fn init_db() -> Result<Connection> {
831 let db = Connection::open_in_memory().context("Failed to initialize sqlite connection.")?;
832 db.execute("ATTACH DATABASE ? as 'persistent';", params![""])
833 .context("Failed to attach databases.")?;
834 db.execute(
835 "CREATE TABLE IF NOT EXISTS persistent.keyparameter (
836 keyentryid INTEGER,
837 tag INTEGER,
838 data ANY,
839 security_level INTEGER);",
840 NO_PARAMS,
841 )
842 .context("Failed to initialize \"keyparameter\" table.")?;
843 Ok(db)
844 }
845
846 /// Helper method to insert an entry into key parameter table, with individual parameters
847 fn insert_into_keyparameter<T: ToSql>(
848 db: &Connection,
849 key_id: i64,
850 tag: i32,
851 value: &T,
852 security_level: i32,
853 ) -> Result<()> {
854 db.execute(
855 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
856VALUES(?, ?, ?, ?);",
857 params![key_id, tag, *value, security_level],
858 )?;
859 Ok(())
860 }
861
862 /// Helper method to store a key parameter instance.
863 fn store_keyparameter(db: &Connection, key_id: i64, kp: &KeyParameter) -> Result<()> {
864 db.execute(
865 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
866VALUES(?, ?, ?, ?);",
867 params![key_id, kp.get_tag(), kp.key_parameter_value(), kp.security_level()],
868 )?;
869 Ok(())
870 }
871
872 /// Helper method to query a row from keyparameter table
873 fn query_from_keyparameter(db: &Connection) -> Result<KeyParameter> {
874 let mut stmt = db.prepare(
875 "SELECT tag, data, security_level FROM
876persistent.keyparameter",
877 )?;
878 let mut rows = stmt.query(NO_PARAMS)?;
879 let row = rows.next()?.unwrap();
880 Ok(KeyParameter::new_from_sql(row.get(0)?, &SqlField(1, row), row.get(2)?)?)
881 }
882}