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 Result, ReturnCode,
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 /// # reserved_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 ReturnCode::ensure_success(
309 unsafe {
310 Esys_Duplicate(
311 self.mut_context(),
312 object_to_duplicate.into(),
313 new_parent_handle.into(),
314 self.required_session_1()?,
315 self.optional_session_2(),
316 self.optional_session_3(),
317 &encryption_key_in.unwrap_or_default().into(),
318 &symmetric_alg.into(),
319 &mut encryption_key_out_ptr,
320 &mut duplicate_ptr,
321 &mut out_sym_seed_ptr,
322 )
323 },
324 |ret| {
325 error!("Error when performing duplication: {:#010X}", ret);
326 },
327 )?;
328
329 Ok((
330 Data::try_from(Context::ffi_data_to_owned(encryption_key_out_ptr)?)?,
331 Private::try_from(Context::ffi_data_to_owned(duplicate_ptr)?)?,
332 EncryptedSecret::try_from(Context::ffi_data_to_owned(out_sym_seed_ptr)?)?,
333 ))
334 }
335
336 // Missing function: Rewrap
337
338 /// Import attaches imported object to a new parent.
339 ///
340 /// # Details
341 /// This command allows an object to be encrypted using the symmetric
342 /// encryption values of a Storage Key. After encryption, the
343 /// object may be loaded and used in the new hierarchy. The
344 /// imported object (duplicate) may be singly encrypted, multiply
345 /// encrypted, or unencrypted.
346 ///
347 /// # Arguments
348 /// * `parent_handle` - An [ObjectHandle] of the new parent for the object.
349 /// * `encryption_key` - An optional symmetric encryption key used as the inner wrapper.
350 /// If `encryption_key` is `None` then a [default value][Default::default] is used.
351 /// * `public` - A [Public] of the imported object.
352 /// * `duplicate` - A symmetrically encrypted duplicated object.
353 /// * `encrypted_secret` - The seed for the symmetric key and HMAC key.
354 /// * `symmetric_alg` - Symmetric algorithm to be used for the inner wrapper.
355 ///
356 /// The `public` is needed to check the integrity value for `duplicate`.
357 ///
358 /// # Returns
359 /// The command returns the sensitive area encrypted with the symmetric key of `parent_handle`.
360 ///
361 /// # Example
362 ///
363 /// ```rust
364 /// # use std::convert::{TryFrom, TryInto};
365 /// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
366 /// # use tss_esapi::constants::{CommandCode, SessionType};
367 /// # use tss_esapi::handles::ObjectHandle;
368 /// # use tss_esapi::interface_types::{
369 /// # algorithm::{HashingAlgorithm, PublicAlgorithm},
370 /// # key_bits::RsaKeyBits,
371 /// # reserved_handles::Hierarchy,
372 /// # session_handles::PolicySession,
373 /// # };
374 /// # use tss_esapi::structures::SymmetricDefinition;
375 /// # use tss_esapi::structures::{
376 /// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
377 /// # RsaExponent,
378 /// # };
379 /// use tss_esapi::structures::SymmetricDefinitionObject;
380 /// # use tss_esapi::abstraction::cipher::Cipher;
381 /// # use tss_esapi::{Context, TctiNameConf};
382 /// #
383 /// # let mut context = // ...
384 /// # Context::new(
385 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
386 /// # ).expect("Failed to create Context");
387 /// #
388 /// # let trial_session = context
389 /// # .start_auth_session(
390 /// # None,
391 /// # None,
392 /// # None,
393 /// # SessionType::Trial,
394 /// # SymmetricDefinition::AES_256_CFB,
395 /// # HashingAlgorithm::Sha256,
396 /// # )
397 /// # .expect("Start auth session failed")
398 /// # .expect("Start auth session returned a NONE handle");
399 /// #
400 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
401 /// # SessionAttributesBuilder::new()
402 /// # .with_decrypt(true)
403 /// # .with_encrypt(true)
404 /// # .build();
405 /// # context
406 /// # .tr_sess_set_attributes(
407 /// # trial_session,
408 /// # policy_auth_session_attributes,
409 /// # policy_auth_session_attributes_mask,
410 /// # )
411 /// # .expect("tr_sess_set_attributes call failed");
412 /// #
413 /// # let policy_session = PolicySession::try_from(trial_session)
414 /// # .expect("Failed to convert auth session into policy session");
415 /// #
416 /// # context
417 /// # .policy_auth_value(policy_session)
418 /// # .expect("Policy auth value");
419 /// #
420 /// # context
421 /// # .policy_command_code(policy_session, CommandCode::Duplicate)
422 /// # .expect("Policy command code");
423 /// #
424 /// # /// Digest of the policy that allows duplication
425 /// # let digest = context
426 /// # .policy_get_digest(policy_session)
427 /// # .expect("Could retrieve digest");
428 /// #
429 /// # drop(context);
430 /// # let mut context = // ...
431 /// # Context::new(
432 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
433 /// # ).expect("Failed to create Context");
434 /// #
435 /// # let session = context
436 /// # .start_auth_session(
437 /// # None,
438 /// # None,
439 /// # None,
440 /// # SessionType::Hmac,
441 /// # SymmetricDefinition::AES_256_CFB,
442 /// # HashingAlgorithm::Sha256,
443 /// # )
444 /// # .expect("Start auth session failed")
445 /// # .expect("Start auth session returned a NONE handle");
446 /// #
447 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
448 /// # .with_decrypt(true)
449 /// # .with_encrypt(true)
450 /// # .build();
451 /// #
452 /// # context.tr_sess_set_attributes(
453 /// # session,
454 /// # session_attributes,
455 /// # session_attributes_mask,
456 /// # ).unwrap();
457 /// #
458 /// # context.set_sessions((Some(session), None, None));
459 /// #
460 /// # // Attributes of parent objects. The `restricted` attribute need
461 /// # // to be `true` so that parents can act as storage keys.
462 /// # let parent_object_attributes = ObjectAttributesBuilder::new()
463 /// # .with_fixed_tpm(true)
464 /// # .with_fixed_parent(true)
465 /// # .with_sensitive_data_origin(true)
466 /// # .with_user_with_auth(true)
467 /// # .with_decrypt(true)
468 /// # .with_sign_encrypt(false)
469 /// # .with_restricted(true)
470 /// # .build()
471 /// # .unwrap();
472 /// #
473 /// # let parent_public = PublicBuilder::new()
474 /// # .with_public_algorithm(PublicAlgorithm::Rsa)
475 /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
476 /// # .with_object_attributes(parent_object_attributes)
477 /// # .with_rsa_parameters(
478 /// # PublicRsaParametersBuilder::new_restricted_decryption_key(
479 /// # Cipher::aes_256_cfb().try_into().unwrap(),
480 /// # RsaKeyBits::Rsa2048,
481 /// # RsaExponent::default(),
482 /// # )
483 /// # .build()
484 /// # .unwrap(),
485 /// # )
486 /// # .with_rsa_unique_identifier(PublicKeyRsa::default())
487 /// # .build()
488 /// # .unwrap();
489 /// #
490 /// # let parent_of_object_to_duplicate_handle = context
491 /// # .create_primary(
492 /// # Hierarchy::Owner,
493 /// # parent_public.clone(),
494 /// # None,
495 /// # None,
496 /// # None,
497 /// # None,
498 /// # )
499 /// # .unwrap()
500 /// # .key_handle;
501 /// #
502 /// # // Fixed TPM and Fixed Parent should be "false" for an object
503 /// # // to be eligible for duplication
504 /// # let object_attributes = ObjectAttributesBuilder::new()
505 /// # .with_fixed_tpm(false)
506 /// # .with_fixed_parent(false)
507 /// # .with_sensitive_data_origin(true)
508 /// # .with_user_with_auth(true)
509 /// # .with_decrypt(true)
510 /// # .with_sign_encrypt(true)
511 /// # .with_restricted(false)
512 /// # .build()
513 /// # .expect("Attributes to be valid");
514 /// #
515 /// # let public_child = PublicBuilder::new()
516 /// # .with_public_algorithm(PublicAlgorithm::Rsa)
517 /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
518 /// # .with_object_attributes(object_attributes)
519 /// # .with_auth_policy(digest)
520 /// # .with_rsa_parameters(
521 /// # PublicRsaParametersBuilder::new()
522 /// # .with_scheme(RsaScheme::Null)
523 /// # .with_key_bits(RsaKeyBits::Rsa2048)
524 /// # .with_is_signing_key(true)
525 /// # .with_is_decryption_key(true)
526 /// # .with_restricted(false)
527 /// # .build()
528 /// # .expect("Params to be valid"),
529 /// # )
530 /// # .with_rsa_unique_identifier(PublicKeyRsa::default())
531 /// # .build()
532 /// # .expect("public to be valid");
533 /// #
534 /// # let result = context
535 /// # .create(
536 /// # parent_of_object_to_duplicate_handle,
537 /// # public_child,
538 /// # None,
539 /// # None,
540 /// # None,
541 /// # None,
542 /// # )
543 /// # .unwrap();
544 /// #
545 /// # let object_to_duplicate_handle: ObjectHandle = context
546 /// # .load(
547 /// # parent_of_object_to_duplicate_handle,
548 /// # result.out_private.clone(),
549 /// # result.out_public,
550 /// # )
551 /// # .unwrap()
552 /// # .into();
553 /// #
554 /// # let new_parent_handle: ObjectHandle = context
555 /// # .create_primary(
556 /// # Hierarchy::Owner,
557 /// # parent_public,
558 /// # None,
559 /// # None,
560 /// # None,
561 /// # None,
562 /// # )
563 /// # .unwrap()
564 /// # .key_handle
565 /// # .into();
566 /// #
567 /// # context.set_sessions((None, None, None));
568 /// #
569 /// # // Create a Policy session with the same exact attributes
570 /// # // as the trial session so that the session digest stays
571 /// # // the same.
572 /// # let policy_auth_session = context
573 /// # .start_auth_session(
574 /// # None,
575 /// # None,
576 /// # None,
577 /// # SessionType::Policy,
578 /// # SymmetricDefinition::AES_256_CFB,
579 /// # HashingAlgorithm::Sha256,
580 /// # )
581 /// # .expect("Start auth session failed")
582 /// # .expect("Start auth session returned a NONE handle");
583 /// #
584 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
585 /// # SessionAttributesBuilder::new()
586 /// # .with_decrypt(true)
587 /// # .with_encrypt(true)
588 /// # .build();
589 /// # context
590 /// # .tr_sess_set_attributes(
591 /// # policy_auth_session,
592 /// # policy_auth_session_attributes,
593 /// # policy_auth_session_attributes_mask,
594 /// # )
595 /// # .expect("tr_sess_set_attributes call failed");
596 /// #
597 /// # let policy_session = PolicySession::try_from(policy_auth_session)
598 /// # .expect("Failed to convert auth session into policy session");
599 /// #
600 /// # context
601 /// # .policy_auth_value(policy_session)
602 /// # .expect("Policy auth value");
603 /// #
604 /// # context
605 /// # .policy_command_code(policy_session, CommandCode::Duplicate)
606 /// # .unwrap();
607 /// #
608 /// # context.set_sessions((Some(policy_auth_session), None, None));
609 /// #
610 /// # let (encryption_key_out, duplicate, out_sym_seed) = context
611 /// # .duplicate(
612 /// # object_to_duplicate_handle,
613 /// # new_parent_handle,
614 /// # None,
615 /// # SymmetricDefinitionObject::Null,
616 /// # )
617 /// # .unwrap();
618 /// # eprintln!("D: {:?}, P: {:?}, S: {:?}", encryption_key_out, duplicate, out_sym_seed);
619 /// # let public = context.read_public(object_to_duplicate_handle.into()).unwrap().0;
620 /// #
621 /// # let session = context
622 /// # .start_auth_session(
623 /// # None,
624 /// # None,
625 /// # None,
626 /// # SessionType::Hmac,
627 /// # SymmetricDefinition::AES_256_CFB,
628 /// # HashingAlgorithm::Sha256,
629 /// # )
630 /// # .unwrap();
631 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
632 /// # .with_decrypt(true)
633 /// # .with_encrypt(true)
634 /// # .build();
635 /// # context.tr_sess_set_attributes(
636 /// # session.unwrap(),
637 /// # session_attributes,
638 /// # session_attributes_mask,
639 /// # )
640 /// # .unwrap();
641 /// # context.set_sessions((session, None, None));
642 ///
643 /// // `encryption_key_out`, `duplicate` and `out_sym_seed` are generated
644 /// // by `duplicate` function
645 /// let private = context.import(
646 /// new_parent_handle,
647 /// Some(encryption_key_out),
648 /// public,
649 /// duplicate,
650 /// out_sym_seed,
651 /// SymmetricDefinitionObject::Null,
652 /// ).unwrap();
653 /// #
654 /// # eprintln!("P: {:?}", private);
655 /// ```
656 pub fn import(
657 &mut self,
658 parent_handle: ObjectHandle,
659 encryption_key: Option<Data>,
660 public: Public,
661 duplicate: Private,
662 encrypted_secret: EncryptedSecret,
663 symmetric_alg: SymmetricDefinitionObject,
664 ) -> Result<Private> {
665 let mut out_private_ptr = null_mut();
666 ReturnCode::ensure_success(
667 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 |ret| {
683 error!("Error when performing import: {:#010X}", ret);
684 },
685 )?;
686 Private::try_from(Context::ffi_data_to_owned(out_private_ptr)?)
687 }
688}