tss_esapi/context/tpm_commands/duplication_commands.rs
1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::Context;
4use crate::{
5 handles::ObjectHandle,
6 structures::{Data, EncryptedSecret, Private, Public, SymmetricDefinitionObject},
7 tss2_esys::{Esys_Duplicate, Esys_Import},
8 Error, Result,
9};
10use log::error;
11
12use std::convert::{TryFrom, TryInto};
13use std::ptr::null_mut;
14
15impl Context {
16 /// Duplicate a loaded object so that it may be used in a different hierarchy.
17 ///
18 /// # Details
19 /// This command duplicates a loaded object so that it may be used in a different hierarchy.
20 /// The new parent key for the duplicate may be on the same or different TPM or the Null hierarchy.
21 /// Only the public area of `new_parent_handle` is required to be loaded.
22 ///
23 /// # Arguments
24 /// * `object_to_duplicate` - An [ObjectHandle] of the object that will be duplicated.
25 /// * `new_parent_handle` - An [ObjectHandle] of the new parent.
26 /// * `encryption_key_in` - An optional encryption key. If this parameter is `None`
27 /// then a [default value][Default::default] is used.
28 /// * `symmetric_alg` - Symmetric algorithm to be used for the inner wrapper.
29 ///
30 /// The `object_to_duplicate` need to be have Fixed TPM and Fixed Parent attributes set to `false`.
31 ///
32 /// # Returns
33 /// The command returns a tuple consisting of:
34 /// * `encryption_key_out` - TPM generated, symmetric encryption key for the inner wrapper if
35 /// `symmetric_alg` is not `Null`.
36 /// * `duplicate` - Private area that may be encrypted.
37 /// * `out_sym_seed` - Seed protected by the asymmetric algorithms of new parent.
38 ///
39 /// # Example
40 ///
41 /// ```rust
42 /// # use std::convert::{TryFrom, TryInto};
43 /// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
44 /// # use tss_esapi::constants::{CommandCode, SessionType};
45 /// # use tss_esapi::handles::ObjectHandle;
46 /// # use tss_esapi::interface_types::{
47 /// # algorithm::{HashingAlgorithm, PublicAlgorithm},
48 /// # key_bits::RsaKeyBits,
49 /// # resource_handles::Hierarchy,
50 /// # session_handles::PolicySession,
51 /// # };
52 /// # use tss_esapi::structures::SymmetricDefinition;
53 /// # use tss_esapi::structures::{
54 /// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
55 /// # RsaExponent,
56 /// # };
57 /// use tss_esapi::structures::SymmetricDefinitionObject;
58 /// # use tss_esapi::abstraction::cipher::Cipher;
59 /// # use tss_esapi::{Context, TctiNameConf};
60 /// #
61 /// # let mut context = // ...
62 /// # Context::new(
63 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
64 /// # ).expect("Failed to create Context");
65 /// #
66 /// # let trial_session = context
67 /// # .start_auth_session(
68 /// # None,
69 /// # None,
70 /// # None,
71 /// # SessionType::Trial,
72 /// # SymmetricDefinition::AES_256_CFB,
73 /// # HashingAlgorithm::Sha256,
74 /// # )
75 /// # .expect("Start auth session failed")
76 /// # .expect("Start auth session returned a NONE handle");
77 /// #
78 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
79 /// # SessionAttributesBuilder::new()
80 /// # .with_decrypt(true)
81 /// # .with_encrypt(true)
82 /// # .build();
83 /// # context
84 /// # .tr_sess_set_attributes(
85 /// # trial_session,
86 /// # policy_auth_session_attributes,
87 /// # policy_auth_session_attributes_mask,
88 /// # )
89 /// # .expect("tr_sess_set_attributes call failed");
90 /// #
91 /// # let policy_session = PolicySession::try_from(trial_session)
92 /// # .expect("Failed to convert auth session into policy session");
93 /// #
94 /// # context
95 /// # .policy_auth_value(policy_session)
96 /// # .expect("Policy auth value");
97 /// #
98 /// # context
99 /// # .policy_command_code(policy_session, CommandCode::Duplicate)
100 /// # .expect("Policy command code");
101 /// #
102 /// # /// Digest of the policy that allows duplication
103 /// # let digest = context
104 /// # .policy_get_digest(policy_session)
105 /// # .expect("Could retrieve digest");
106 /// #
107 /// # drop(context);
108 /// # let mut context = // ...
109 /// # Context::new(
110 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
111 /// # ).expect("Failed to create Context");
112 /// #
113 /// # let session = context
114 /// # .start_auth_session(
115 /// # None,
116 /// # None,
117 /// # None,
118 /// # SessionType::Hmac,
119 /// # SymmetricDefinition::AES_256_CFB,
120 /// # HashingAlgorithm::Sha256,
121 /// # )
122 /// # .expect("Start auth session failed")
123 /// # .expect("Start auth session returned a NONE handle");
124 /// #
125 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
126 /// # .with_decrypt(true)
127 /// # .with_encrypt(true)
128 /// # .build();
129 /// #
130 /// # context.tr_sess_set_attributes(
131 /// # session,
132 /// # session_attributes,
133 /// # session_attributes_mask,
134 /// # ).unwrap();
135 /// #
136 /// # context.set_sessions((Some(session), None, None));
137 /// #
138 /// # // Attributes of parent objects. The `restricted` attribute need
139 /// # // to be `true` so that parents can act as storage keys.
140 /// # let parent_object_attributes = ObjectAttributesBuilder::new()
141 /// # .with_fixed_tpm(true)
142 /// # .with_fixed_parent(true)
143 /// # .with_sensitive_data_origin(true)
144 /// # .with_user_with_auth(true)
145 /// # .with_decrypt(true)
146 /// # .with_sign_encrypt(false)
147 /// # .with_restricted(true)
148 /// # .build()
149 /// # .unwrap();
150 /// #
151 /// # let parent_public = PublicBuilder::new()
152 /// # .with_public_algorithm(PublicAlgorithm::Rsa)
153 /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
154 /// # .with_object_attributes(parent_object_attributes)
155 /// # .with_rsa_parameters(
156 /// # PublicRsaParametersBuilder::new_restricted_decryption_key(
157 /// # Cipher::aes_256_cfb().try_into().unwrap(),
158 /// # RsaKeyBits::Rsa2048,
159 /// # RsaExponent::default(),
160 /// # )
161 /// # .build()
162 /// # .unwrap(),
163 /// # )
164 /// # .with_rsa_unique_identifier(PublicKeyRsa::default())
165 /// # .build()
166 /// # .unwrap();
167 /// #
168 /// # let parent_of_object_to_duplicate_handle = context
169 /// # .create_primary(
170 /// # Hierarchy::Owner,
171 /// # parent_public.clone(),
172 /// # None,
173 /// # None,
174 /// # None,
175 /// # None,
176 /// # )
177 /// # .unwrap()
178 /// # .key_handle;
179 /// #
180 /// # // Fixed TPM and Fixed Parent should be "false" for an object
181 /// # // to be eligible for duplication
182 /// # let object_attributes = ObjectAttributesBuilder::new()
183 /// # .with_fixed_tpm(false)
184 /// # .with_fixed_parent(false)
185 /// # .with_sensitive_data_origin(true)
186 /// # .with_user_with_auth(true)
187 /// # .with_decrypt(true)
188 /// # .with_sign_encrypt(true)
189 /// # .with_restricted(false)
190 /// # .build()
191 /// # .expect("Attributes to be valid");
192 /// #
193 /// # let public_child = PublicBuilder::new()
194 /// # .with_public_algorithm(PublicAlgorithm::Rsa)
195 /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
196 /// # .with_object_attributes(object_attributes)
197 /// # .with_auth_policy(digest)
198 /// # .with_rsa_parameters(
199 /// # PublicRsaParametersBuilder::new()
200 /// # .with_scheme(RsaScheme::Null)
201 /// # .with_key_bits(RsaKeyBits::Rsa2048)
202 /// # .with_is_signing_key(true)
203 /// # .with_is_decryption_key(true)
204 /// # .with_restricted(false)
205 /// # .build()
206 /// # .expect("Params to be valid"),
207 /// # )
208 /// # .with_rsa_unique_identifier(PublicKeyRsa::default())
209 /// # .build()
210 /// # .expect("public to be valid");
211 /// #
212 /// # let result = context
213 /// # .create(
214 /// # parent_of_object_to_duplicate_handle,
215 /// # public_child,
216 /// # None,
217 /// # None,
218 /// # None,
219 /// # None,
220 /// # )
221 /// # .unwrap();
222 /// #
223 /// # let object_to_duplicate_handle: ObjectHandle = context
224 /// # .load(
225 /// # parent_of_object_to_duplicate_handle,
226 /// # result.out_private.clone(),
227 /// # result.out_public,
228 /// # )
229 /// # .unwrap()
230 /// # .into();
231 /// #
232 /// # let new_parent_handle: ObjectHandle = context
233 /// # .create_primary(
234 /// # Hierarchy::Owner,
235 /// # parent_public,
236 /// # None,
237 /// # None,
238 /// # None,
239 /// # None,
240 /// # )
241 /// # .unwrap()
242 /// # .key_handle
243 /// # .into();
244 /// #
245 /// # context.set_sessions((None, None, None));
246 /// #
247 /// # // Create a Policy session with the same exact attributes
248 /// # // as the trial session so that the session digest stays
249 /// # // the same.
250 /// # let policy_auth_session = context
251 /// # .start_auth_session(
252 /// # None,
253 /// # None,
254 /// # None,
255 /// # SessionType::Policy,
256 /// # SymmetricDefinition::AES_256_CFB,
257 /// # HashingAlgorithm::Sha256,
258 /// # )
259 /// # .expect("Start auth session failed")
260 /// # .expect("Start auth session returned a NONE handle");
261 /// #
262 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
263 /// # SessionAttributesBuilder::new()
264 /// # .with_decrypt(true)
265 /// # .with_encrypt(true)
266 /// # .build();
267 /// # context
268 /// # .tr_sess_set_attributes(
269 /// # policy_auth_session,
270 /// # policy_auth_session_attributes,
271 /// # policy_auth_session_attributes_mask,
272 /// # )
273 /// # .expect("tr_sess_set_attributes call failed");
274 /// #
275 /// # let policy_session = PolicySession::try_from(policy_auth_session)
276 /// # .expect("Failed to convert auth session into policy session");
277 /// #
278 /// # context
279 /// # .policy_auth_value(policy_session)
280 /// # .expect("Policy auth value");
281 /// #
282 /// # context
283 /// # .policy_command_code(policy_session, CommandCode::Duplicate)
284 /// # .unwrap();
285 /// #
286 /// # context.set_sessions((Some(policy_auth_session), None, None));
287 ///
288 /// let (encryption_key_out, duplicate, out_sym_seed) = context
289 /// .duplicate(
290 /// object_to_duplicate_handle,
291 /// new_parent_handle,
292 /// None,
293 /// SymmetricDefinitionObject::Null,
294 /// )
295 /// .unwrap();
296 /// # eprintln!("D: {:?}, P: {:?}, S: {:?}", encryption_key_out, duplicate, out_sym_seed);
297 /// ```
298 pub fn duplicate(
299 &mut self,
300 object_to_duplicate: ObjectHandle,
301 new_parent_handle: ObjectHandle,
302 encryption_key_in: Option<Data>,
303 symmetric_alg: SymmetricDefinitionObject,
304 ) -> Result<(Data, Private, EncryptedSecret)> {
305 let mut encryption_key_out_ptr = null_mut();
306 let mut duplicate_ptr = null_mut();
307 let mut out_sym_seed_ptr = null_mut();
308 let ret = unsafe {
309 Esys_Duplicate(
310 self.mut_context(),
311 object_to_duplicate.into(),
312 new_parent_handle.into(),
313 self.required_session_1()?,
314 self.optional_session_2(),
315 self.optional_session_3(),
316 &encryption_key_in.unwrap_or_default().into(),
317 &symmetric_alg.into(),
318 &mut encryption_key_out_ptr,
319 &mut duplicate_ptr,
320 &mut out_sym_seed_ptr,
321 )
322 };
323 let ret = Error::from_tss_rc(ret);
324
325 if ret.is_success() {
326 Ok((
327 Data::try_from(Context::ffi_data_to_owned(encryption_key_out_ptr))?,
328 Private::try_from(Context::ffi_data_to_owned(duplicate_ptr))?,
329 EncryptedSecret::try_from(Context::ffi_data_to_owned(out_sym_seed_ptr))?,
330 ))
331 } else {
332 error!("Error when performing duplication: {}", ret);
333 Err(ret)
334 }
335 }
336
337 // Missing function: Rewrap
338
339 /// Import attaches imported object to a new parent.
340 ///
341 /// # Details
342 /// This command allows an object to be encrypted using the symmetric
343 /// encryption values of a Storage Key. After encryption, the
344 /// object may be loaded and used in the new hierarchy. The
345 /// imported object (duplicate) may be singly encrypted, multiply
346 /// encrypted, or unencrypted.
347 ///
348 /// # Arguments
349 /// * `parent_handle` - An [ObjectHandle] of the new parent for the object.
350 /// * `encryption_key` - An optional symmetric encryption key used as the inner wrapper.
351 /// If `encryption_key` is `None` then a [default value][Default::default] is used.
352 /// * `public` - A [Public] of the imported object.
353 /// * `duplicate` - A symmetrically encrypted duplicated object.
354 /// * `encrypted_secret` - The seed for the symmetric key and HMAC key.
355 /// * `symmetric_alg` - Symmetric algorithm to be used for the inner wrapper.
356 ///
357 /// The `public` is needed to check the integrity value for `duplicate`.
358 ///
359 /// # Returns
360 /// The command returns the sensitive area encrypted with the symmetric key of `parent_handle`.
361 ///
362 /// # Example
363 ///
364 /// ```rust
365 /// # use std::convert::{TryFrom, TryInto};
366 /// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
367 /// # use tss_esapi::constants::{CommandCode, SessionType};
368 /// # use tss_esapi::handles::ObjectHandle;
369 /// # use tss_esapi::interface_types::{
370 /// # algorithm::{HashingAlgorithm, PublicAlgorithm},
371 /// # key_bits::RsaKeyBits,
372 /// # resource_handles::Hierarchy,
373 /// # session_handles::PolicySession,
374 /// # };
375 /// # use tss_esapi::structures::SymmetricDefinition;
376 /// # use tss_esapi::structures::{
377 /// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
378 /// # RsaExponent,
379 /// # };
380 /// use tss_esapi::structures::SymmetricDefinitionObject;
381 /// # use tss_esapi::abstraction::cipher::Cipher;
382 /// # use tss_esapi::{Context, TctiNameConf};
383 /// #
384 /// # let mut context = // ...
385 /// # Context::new(
386 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
387 /// # ).expect("Failed to create Context");
388 /// #
389 /// # let trial_session = context
390 /// # .start_auth_session(
391 /// # None,
392 /// # None,
393 /// # None,
394 /// # SessionType::Trial,
395 /// # SymmetricDefinition::AES_256_CFB,
396 /// # HashingAlgorithm::Sha256,
397 /// # )
398 /// # .expect("Start auth session failed")
399 /// # .expect("Start auth session returned a NONE handle");
400 /// #
401 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
402 /// # SessionAttributesBuilder::new()
403 /// # .with_decrypt(true)
404 /// # .with_encrypt(true)
405 /// # .build();
406 /// # context
407 /// # .tr_sess_set_attributes(
408 /// # trial_session,
409 /// # policy_auth_session_attributes,
410 /// # policy_auth_session_attributes_mask,
411 /// # )
412 /// # .expect("tr_sess_set_attributes call failed");
413 /// #
414 /// # let policy_session = PolicySession::try_from(trial_session)
415 /// # .expect("Failed to convert auth session into policy session");
416 /// #
417 /// # context
418 /// # .policy_auth_value(policy_session)
419 /// # .expect("Policy auth value");
420 /// #
421 /// # context
422 /// # .policy_command_code(policy_session, CommandCode::Duplicate)
423 /// # .expect("Policy command code");
424 /// #
425 /// # /// Digest of the policy that allows duplication
426 /// # let digest = context
427 /// # .policy_get_digest(policy_session)
428 /// # .expect("Could retrieve digest");
429 /// #
430 /// # drop(context);
431 /// # let mut context = // ...
432 /// # Context::new(
433 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
434 /// # ).expect("Failed to create Context");
435 /// #
436 /// # let session = context
437 /// # .start_auth_session(
438 /// # None,
439 /// # None,
440 /// # None,
441 /// # SessionType::Hmac,
442 /// # SymmetricDefinition::AES_256_CFB,
443 /// # HashingAlgorithm::Sha256,
444 /// # )
445 /// # .expect("Start auth session failed")
446 /// # .expect("Start auth session returned a NONE handle");
447 /// #
448 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
449 /// # .with_decrypt(true)
450 /// # .with_encrypt(true)
451 /// # .build();
452 /// #
453 /// # context.tr_sess_set_attributes(
454 /// # session,
455 /// # session_attributes,
456 /// # session_attributes_mask,
457 /// # ).unwrap();
458 /// #
459 /// # context.set_sessions((Some(session), None, None));
460 /// #
461 /// # // Attributes of parent objects. The `restricted` attribute need
462 /// # // to be `true` so that parents can act as storage keys.
463 /// # let parent_object_attributes = ObjectAttributesBuilder::new()
464 /// # .with_fixed_tpm(true)
465 /// # .with_fixed_parent(true)
466 /// # .with_sensitive_data_origin(true)
467 /// # .with_user_with_auth(true)
468 /// # .with_decrypt(true)
469 /// # .with_sign_encrypt(false)
470 /// # .with_restricted(true)
471 /// # .build()
472 /// # .unwrap();
473 /// #
474 /// # let parent_public = PublicBuilder::new()
475 /// # .with_public_algorithm(PublicAlgorithm::Rsa)
476 /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
477 /// # .with_object_attributes(parent_object_attributes)
478 /// # .with_rsa_parameters(
479 /// # PublicRsaParametersBuilder::new_restricted_decryption_key(
480 /// # Cipher::aes_256_cfb().try_into().unwrap(),
481 /// # RsaKeyBits::Rsa2048,
482 /// # RsaExponent::default(),
483 /// # )
484 /// # .build()
485 /// # .unwrap(),
486 /// # )
487 /// # .with_rsa_unique_identifier(PublicKeyRsa::default())
488 /// # .build()
489 /// # .unwrap();
490 /// #
491 /// # let parent_of_object_to_duplicate_handle = context
492 /// # .create_primary(
493 /// # Hierarchy::Owner,
494 /// # parent_public.clone(),
495 /// # None,
496 /// # None,
497 /// # None,
498 /// # None,
499 /// # )
500 /// # .unwrap()
501 /// # .key_handle;
502 /// #
503 /// # // Fixed TPM and Fixed Parent should be "false" for an object
504 /// # // to be eligible for duplication
505 /// # let object_attributes = ObjectAttributesBuilder::new()
506 /// # .with_fixed_tpm(false)
507 /// # .with_fixed_parent(false)
508 /// # .with_sensitive_data_origin(true)
509 /// # .with_user_with_auth(true)
510 /// # .with_decrypt(true)
511 /// # .with_sign_encrypt(true)
512 /// # .with_restricted(false)
513 /// # .build()
514 /// # .expect("Attributes to be valid");
515 /// #
516 /// # let public_child = PublicBuilder::new()
517 /// # .with_public_algorithm(PublicAlgorithm::Rsa)
518 /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
519 /// # .with_object_attributes(object_attributes)
520 /// # .with_auth_policy(digest)
521 /// # .with_rsa_parameters(
522 /// # PublicRsaParametersBuilder::new()
523 /// # .with_scheme(RsaScheme::Null)
524 /// # .with_key_bits(RsaKeyBits::Rsa2048)
525 /// # .with_is_signing_key(true)
526 /// # .with_is_decryption_key(true)
527 /// # .with_restricted(false)
528 /// # .build()
529 /// # .expect("Params to be valid"),
530 /// # )
531 /// # .with_rsa_unique_identifier(PublicKeyRsa::default())
532 /// # .build()
533 /// # .expect("public to be valid");
534 /// #
535 /// # let result = context
536 /// # .create(
537 /// # parent_of_object_to_duplicate_handle,
538 /// # public_child,
539 /// # None,
540 /// # None,
541 /// # None,
542 /// # None,
543 /// # )
544 /// # .unwrap();
545 /// #
546 /// # let object_to_duplicate_handle: ObjectHandle = context
547 /// # .load(
548 /// # parent_of_object_to_duplicate_handle,
549 /// # result.out_private.clone(),
550 /// # result.out_public,
551 /// # )
552 /// # .unwrap()
553 /// # .into();
554 /// #
555 /// # let new_parent_handle: ObjectHandle = context
556 /// # .create_primary(
557 /// # Hierarchy::Owner,
558 /// # parent_public,
559 /// # None,
560 /// # None,
561 /// # None,
562 /// # None,
563 /// # )
564 /// # .unwrap()
565 /// # .key_handle
566 /// # .into();
567 /// #
568 /// # context.set_sessions((None, None, None));
569 /// #
570 /// # // Create a Policy session with the same exact attributes
571 /// # // as the trial session so that the session digest stays
572 /// # // the same.
573 /// # let policy_auth_session = context
574 /// # .start_auth_session(
575 /// # None,
576 /// # None,
577 /// # None,
578 /// # SessionType::Policy,
579 /// # SymmetricDefinition::AES_256_CFB,
580 /// # HashingAlgorithm::Sha256,
581 /// # )
582 /// # .expect("Start auth session failed")
583 /// # .expect("Start auth session returned a NONE handle");
584 /// #
585 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
586 /// # SessionAttributesBuilder::new()
587 /// # .with_decrypt(true)
588 /// # .with_encrypt(true)
589 /// # .build();
590 /// # context
591 /// # .tr_sess_set_attributes(
592 /// # policy_auth_session,
593 /// # policy_auth_session_attributes,
594 /// # policy_auth_session_attributes_mask,
595 /// # )
596 /// # .expect("tr_sess_set_attributes call failed");
597 /// #
598 /// # let policy_session = PolicySession::try_from(policy_auth_session)
599 /// # .expect("Failed to convert auth session into policy session");
600 /// #
601 /// # context
602 /// # .policy_auth_value(policy_session)
603 /// # .expect("Policy auth value");
604 /// #
605 /// # context
606 /// # .policy_command_code(policy_session, CommandCode::Duplicate)
607 /// # .unwrap();
608 /// #
609 /// # context.set_sessions((Some(policy_auth_session), None, None));
610 /// #
611 /// # let (encryption_key_out, duplicate, out_sym_seed) = context
612 /// # .duplicate(
613 /// # object_to_duplicate_handle,
614 /// # new_parent_handle,
615 /// # None,
616 /// # SymmetricDefinitionObject::Null,
617 /// # )
618 /// # .unwrap();
619 /// # eprintln!("D: {:?}, P: {:?}, S: {:?}", encryption_key_out, duplicate, out_sym_seed);
620 /// # let public = context.read_public(object_to_duplicate_handle.into()).unwrap().0;
621 /// #
622 /// # let session = context
623 /// # .start_auth_session(
624 /// # None,
625 /// # None,
626 /// # None,
627 /// # SessionType::Hmac,
628 /// # SymmetricDefinition::AES_256_CFB,
629 /// # HashingAlgorithm::Sha256,
630 /// # )
631 /// # .unwrap();
632 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
633 /// # .with_decrypt(true)
634 /// # .with_encrypt(true)
635 /// # .build();
636 /// # context.tr_sess_set_attributes(
637 /// # session.unwrap(),
638 /// # session_attributes,
639 /// # session_attributes_mask,
640 /// # )
641 /// # .unwrap();
642 /// # context.set_sessions((session, None, None));
643 ///
644 /// // `encryption_key_out`, `duplicate` and `out_sym_seed` are generated
645 /// // by `duplicate` function
646 /// let private = context.import(
647 /// new_parent_handle,
648 /// Some(encryption_key_out),
649 /// public,
650 /// duplicate,
651 /// out_sym_seed,
652 /// SymmetricDefinitionObject::Null,
653 /// ).unwrap();
654 /// #
655 /// # eprintln!("P: {:?}", private);
656 /// ```
657 pub fn import(
658 &mut self,
659 parent_handle: ObjectHandle,
660 encryption_key: Option<Data>,
661 public: Public,
662 duplicate: Private,
663 encrypted_secret: EncryptedSecret,
664 symmetric_alg: SymmetricDefinitionObject,
665 ) -> Result<Private> {
666 let mut out_private_ptr = null_mut();
667 let ret = unsafe {
668 Esys_Import(
669 self.mut_context(),
670 parent_handle.into(),
671 self.required_session_1()?,
672 self.optional_session_2(),
673 self.optional_session_3(),
674 &encryption_key.unwrap_or_default().into(),
675 &public.try_into()?,
676 &duplicate.into(),
677 &encrypted_secret.into(),
678 &symmetric_alg.into(),
679 &mut out_private_ptr,
680 )
681 };
682 let ret = Error::from_tss_rc(ret);
683
684 if ret.is_success() {
685 Private::try_from(Context::ffi_data_to_owned(out_private_ptr))
686 } else {
687 error!("Error when performing import: {}", ret);
688 Err(ret)
689 }
690 }
691}