pub struct LARight { /* private fields */ }Expand description
Managed wrapper around Apple’s LARight.
Implementations§
Source§impl LARight
impl LARight
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Create a right with the framework’s default authentication requirement.
§Errors
Returns an error if the API is unavailable or the Swift bridge rejects the request.
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let right = LARight::new()?;
5 right.set_tag(42)?;
6
7 println!("state: {:?}", right.state()?);
8 println!("tag: {}", right.tag()?);
9 println!("check_can_authorize: {:?}", right.check_can_authorize());
10 right.deauthorize()?;
11 println!("state after deauthorize: {:?}", right.state()?);
12 println!("✅ right lifecycle OK");
13 Ok(())
14}More examples
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13 let store = LARightStore::shared()?;
14 let right = LARight::new()?;
15 let identifier = unique_identifier("store");
16
17 match store.save_right(&right, &identifier) {
18 Ok(persisted) => {
19 println!("saved state: {:?}", persisted.state()?);
20 store.remove_right(&persisted)?;
21 }
22 Err(error) => {
23 println!("save_right expectedly failed in unsigned/headless environments: {error}");
24 }
25 }
26
27 println!("✅ right-store smoke OK");
28 Ok(())
29}12fn main() -> Result<(), Box<dyn std::error::Error>> {
13 let store = LARightStore::shared()?;
14 let right = LARight::new()?;
15 let identifier = unique_identifier("persisted");
16
17 match store.save_right_with_secret(&right, &identifier, b"top-secret") {
18 Ok(persisted) => {
19 persisted.set_tag(7)?;
20 println!("persisted state: {:?}", persisted.state()?);
21 println!("persisted tag: {}", persisted.tag()?);
22 println!("persisted preflight: {:?}", persisted.check_can_authorize());
23 println!("secret bytes: {}", persisted.secret()?.load_data()?.len());
24 store.remove_right(&persisted)?;
25 }
26 Err(error) => {
27 println!("persisted-right APIs need entitlements on many systems: {error}");
28 }
29 }
30
31 println!("✅ persisted-right smoke OK");
32 Ok(())
33}12fn main() -> Result<(), Box<dyn std::error::Error>> {
13 let store = LARightStore::shared()?;
14 let first_right = LARight::new()?;
15 let second_right = LARight::new()?;
16 let first_identifier = unique_identifier("public-key-a");
17 let second_identifier = unique_identifier("public-key-b");
18
19 match store.save_right(&first_right, &first_identifier) {
20 Ok(first) => {
21 let public_key = first.public_key()?;
22 let sign = SecKeyAlgorithm::ecdsa_signature_message_x962_sha256();
23 let encrypt =
24 SecKeyAlgorithm::ecies_encryption_cofactor_variable_iv_x963_sha256_aes_gcm();
25 let exchange = SecKeyAlgorithm::ecdh_key_exchange_cofactor_x963_sha256();
26 let first_private_key = first.key()?;
27
28 println!("public key bytes: {}", public_key.export_bytes()?.len());
29 println!("can verify: {}", public_key.can_verify_using(&sign)?);
30 println!("can encrypt: {}", public_key.can_encrypt_using(&encrypt)?);
31 println!("private key can sign: {}", first_private_key.can_sign_using(&sign)?);
32 println!(
33 "private key can exchange: {}",
34 first_private_key.can_exchange_keys_using(&exchange)?
35 );
36
37 match store.save_right(&second_right, &second_identifier) {
38 Ok(second) => {
39 let second_private_key = second.key()?;
40 if first_private_key.can_exchange_keys_using(&exchange)?
41 && second_private_key.can_exchange_keys_using(&exchange)?
42 {
43 let parameters = SecKeyExchangeParameters::with_requested_size(32)
44 .with_shared_info(b"localauthentication-rs");
45 let first_public_key = first_private_key.public_key()?.export_bytes()?;
46 let second_public_key = second_private_key.public_key()?.export_bytes()?;
47
48 match (
49 first_private_key.exchange_keys_with_public_key(
50 &second_public_key,
51 &exchange,
52 ¶meters,
53 ),
54 second_private_key.exchange_keys_with_public_key(
55 &first_public_key,
56 &exchange,
57 ¶meters,
58 ),
59 ) {
60 (Ok(first_secret), Ok(second_secret)) => {
61 println!("shared secret bytes: {}", first_secret.len());
62 println!("shared secrets match: {}", first_secret == second_secret);
63 }
64 (Err(error), _) | (_, Err(error)) => {
65 println!("key exchange requires additional system support: {error}");
66 }
67 }
68 }
69 store.remove_right(&second)?;
70 }
71 Err(error) => {
72 println!("key-exchange demo needs two persisted keys: {error}");
73 }
74 }
75
76 store.remove_right(&first)?;
77 }
78 Err(error) => {
79 println!("public-key APIs need entitlements on many systems: {error}");
80 }
81 }
82
83 println!("✅ public-key smoke OK");
84 Ok(())
85}Sourcepub fn new_with_requirement(
requirement: &LAAuthenticationRequirement,
) -> Result<Self>
pub fn new_with_requirement( requirement: &LAAuthenticationRequirement, ) -> Result<Self>
Create a right with an explicit authentication requirement.
§Errors
Returns an error if the API is unavailable or the Swift bridge rejects the request.
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let default_requirement = LAAuthenticationRequirement::default_requirement()?;
5 let biometry_requirement = LAAuthenticationRequirement::biometry_requirement()?;
6 let current_set_requirement = LAAuthenticationRequirement::biometry_current_set_requirement()?;
7 let fallback = LABiometryFallbackRequirement::device_passcode_requirement()?;
8 let fallback_requirement =
9 LAAuthenticationRequirement::biometry_requirement_with_fallback(&fallback)?;
10
11 let rights = [
12 LARight::new_with_requirement(&default_requirement)?,
13 LARight::new_with_requirement(&biometry_requirement)?,
14 LARight::new_with_requirement(¤t_set_requirement)?,
15 LARight::new_with_requirement(&fallback_requirement)?,
16 ];
17
18 for (index, right) in rights.iter().enumerate() {
19 println!("right {index} state: {:?}", right.state()?);
20 println!("right {index} preflight: {:?}", right.check_can_authorize());
21 }
22
23 println!("✅ authentication requirements OK");
24 Ok(())
25}Sourcepub fn state(&self) -> Result<LARightState>
pub fn state(&self) -> Result<LARightState>
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let right = LARight::new()?;
5 right.set_tag(42)?;
6
7 println!("state: {:?}", right.state()?);
8 println!("tag: {}", right.tag()?);
9 println!("check_can_authorize: {:?}", right.check_can_authorize());
10 right.deauthorize()?;
11 println!("state after deauthorize: {:?}", right.state()?);
12 println!("✅ right lifecycle OK");
13 Ok(())
14}More examples
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let default_requirement = LAAuthenticationRequirement::default_requirement()?;
5 let biometry_requirement = LAAuthenticationRequirement::biometry_requirement()?;
6 let current_set_requirement = LAAuthenticationRequirement::biometry_current_set_requirement()?;
7 let fallback = LABiometryFallbackRequirement::device_passcode_requirement()?;
8 let fallback_requirement =
9 LAAuthenticationRequirement::biometry_requirement_with_fallback(&fallback)?;
10
11 let rights = [
12 LARight::new_with_requirement(&default_requirement)?,
13 LARight::new_with_requirement(&biometry_requirement)?,
14 LARight::new_with_requirement(¤t_set_requirement)?,
15 LARight::new_with_requirement(&fallback_requirement)?,
16 ];
17
18 for (index, right) in rights.iter().enumerate() {
19 println!("right {index} state: {:?}", right.state()?);
20 println!("right {index} preflight: {:?}", right.check_can_authorize());
21 }
22
23 println!("✅ authentication requirements OK");
24 Ok(())
25}Sourcepub fn tag(&self) -> Result<i64>
pub fn tag(&self) -> Result<i64>
Application-controlled integer tag.
§Errors
Returns an error if the Swift bridge rejects the request.
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let right = LARight::new()?;
5 right.set_tag(42)?;
6
7 println!("state: {:?}", right.state()?);
8 println!("tag: {}", right.tag()?);
9 println!("check_can_authorize: {:?}", right.check_can_authorize());
10 right.deauthorize()?;
11 println!("state after deauthorize: {:?}", right.state()?);
12 println!("✅ right lifecycle OK");
13 Ok(())
14}Sourcepub fn set_tag(&self, tag: i64) -> Result<()>
pub fn set_tag(&self, tag: i64) -> Result<()>
Update the application-controlled integer tag.
§Errors
Returns an error if the Swift bridge rejects the request.
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let right = LARight::new()?;
5 right.set_tag(42)?;
6
7 println!("state: {:?}", right.state()?);
8 println!("tag: {}", right.tag()?);
9 println!("check_can_authorize: {:?}", right.check_can_authorize());
10 right.deauthorize()?;
11 println!("state after deauthorize: {:?}", right.state()?);
12 println!("✅ right lifecycle OK");
13 Ok(())
14}Attempt to authorize the right.
§Errors
Returns a mapped framework or bridge error when authorization fails.
Preflight whether the right can eventually be authorized.
§Errors
Returns a mapped framework or bridge error when authorization is not possible.
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let right = LARight::new()?;
5 right.set_tag(42)?;
6
7 println!("state: {:?}", right.state()?);
8 println!("tag: {}", right.tag()?);
9 println!("check_can_authorize: {:?}", right.check_can_authorize());
10 right.deauthorize()?;
11 println!("state after deauthorize: {:?}", right.state()?);
12 println!("✅ right lifecycle OK");
13 Ok(())
14}More examples
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let default_requirement = LAAuthenticationRequirement::default_requirement()?;
5 let biometry_requirement = LAAuthenticationRequirement::biometry_requirement()?;
6 let current_set_requirement = LAAuthenticationRequirement::biometry_current_set_requirement()?;
7 let fallback = LABiometryFallbackRequirement::device_passcode_requirement()?;
8 let fallback_requirement =
9 LAAuthenticationRequirement::biometry_requirement_with_fallback(&fallback)?;
10
11 let rights = [
12 LARight::new_with_requirement(&default_requirement)?,
13 LARight::new_with_requirement(&biometry_requirement)?,
14 LARight::new_with_requirement(¤t_set_requirement)?,
15 LARight::new_with_requirement(&fallback_requirement)?,
16 ];
17
18 for (index, right) in rights.iter().enumerate() {
19 println!("right {index} state: {:?}", right.state()?);
20 println!("right {index} preflight: {:?}", right.check_can_authorize());
21 }
22
23 println!("✅ authentication requirements OK");
24 Ok(())
25}Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let right = LARight::new()?;
5 right.set_tag(42)?;
6
7 println!("state: {:?}", right.state()?);
8 println!("tag: {}", right.tag()?);
9 println!("check_can_authorize: {:?}", right.check_can_authorize());
10 right.deauthorize()?;
11 println!("state after deauthorize: {:?}", right.state()?);
12 println!("✅ right lifecycle OK");
13 Ok(())
14}