1 /*
2 * Copyright (C) 2025 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //! Unit tests for AuthMgr BE
18 use crate::server::{AuthMgrMessage, AUTHMGR_SERVICE_PORT};
19 use alloc::vec::Vec;
20 use android_hardware_security_see_authmgr::aidl::android::hardware::security::see::authmgr::{
21 DiceChainEntry::DiceChainEntry as AidlDiceChainEntry, DiceLeafArtifacts::DiceLeafArtifacts,
22 DicePolicy::DicePolicy, Error::Error, ExplicitKeyDiceCertChain::ExplicitKeyDiceCertChain,
23 IAuthMgrAuthorization::IAuthMgrAuthorization, SignedConnectionRequest::SignedConnectionRequest,
24 };
25 use authgraph_boringssl::{BoringEcDsa, BoringRng};
26 use authgraph_core::key::{CertChain, DiceChainEntry};
27 use authgraph_core::traits::Rng;
28 use authgraph_core_test::{
29 create_dice_cert_chain_for_guest_os, create_dice_leaf_cert, SAMPLE_INSTANCE_HASH,
30 };
31 use authmgr_common::{
32 signed_connection_request::{
33 ConnectionRequest, TEMP_AUTHMGR_BE_TRANSPORT_ID, TEMP_AUTHMGR_FE_TRANSPORT_ID,
34 },
35 CMD_RAW, CMD_RPC, TOKEN_LENGTH,
36 };
37 use authmgr_common_util::{
38 get_constraint_spec_for_static_trusty_ta, get_constraints_spec_for_trusty_vm,
39 policy_for_dice_node,
40 };
41 use binder::Strong;
42 use coset::CborSerializable;
43 use hello_world_trusted_aidl::aidl::android::trusty::trustedhal::IHelloWorld::IHelloWorld;
44 use rpcbinder::RpcSession;
45 use test::assert_ok;
46 use tipc::{Deserialize, Handle, Serialize, Serializer, TipcError};
47 use trusty_std::alloc::TryAllocFrom;
48
49 test::init!();
50
51 #[test]
test_authmgr_connection()52 fn test_authmgr_connection() {
53 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
54 }
55
56 #[test]
test_authmgr_rpc_command()57 fn test_authmgr_rpc_command() {
58 // Test the AuthMgr Init Service by sending just CMD_RPC over the connection, expect success.
59
60 let conn_rpc =
61 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
62 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
63 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
64 }
65
66 #[test]
test_authmgr_rpc_command_with_session_setup()67 fn test_authmgr_rpc_command_with_session_setup() {
68 // Test the AuthMgr Init Service by sending CMD_RPC over the connection and then setting
69 // up session, expect success.
70
71 let conn_rpc =
72 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
73 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
74 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
75 let cb = || {
76 let fd = conn_rpc.as_raw_fd();
77 Some(fd)
78 };
79 let rpc_session = RpcSession::new();
80 let _rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
81 rpc_session.setup_preconnected_client(cb),
82 "Failed to setup pre-connected client for the authmgr rpc service."
83 );
84 }
85
86 #[test]
test_authmgr_init_auth_ok()87 fn test_authmgr_init_auth_ok() {
88 // Test the IAuthMgrAuthorization AIDL interface - initAuthentication, expect success.
89 // Connect and send message indicating the intent to connect to the RPC service
90
91 let conn_rpc =
92 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
93 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
94 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
95 let cb = || {
96 let fd = conn_rpc.as_raw_fd();
97 Some(fd)
98 };
99 let rpc_session = RpcSession::new();
100 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
101 rpc_session.setup_preconnected_client(cb),
102 "Failed to setup pre-connected client for the authmgr rpc service."
103 );
104 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
105 let (_signing_key, _cdi_values, cert_chain) =
106 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
107 let result_init_auth = rpc_session
108 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
109 let _challenge: [u8; TOKEN_LENGTH] =
110 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
111 }
112
113 #[test]
test_authmgr_init_auth_with_invalid_dice_chain()114 fn test_authmgr_init_auth_with_invalid_dice_chain() {
115 // Test the IAuthMgrAuthorization AIDL interface - initAuthentication with an invalid
116 // DICE chain, expect error.
117 // Connect and send message indicating the intent to connect to the RPC service
118 let conn_rpc =
119 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
120 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
121 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
122 let cb = || {
123 let fd = conn_rpc.as_raw_fd();
124 Some(fd)
125 };
126 let rpc_session = RpcSession::new();
127 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
128 rpc_session.setup_preconnected_client(cb),
129 "Failed to setup pre-connected client for the authmgr rpc service."
130 );
131
132 let result_init_auth = rpc_session
133 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: Vec::<u8>::new() }, None);
134 assert!(result_init_auth.is_err());
135 assert_eq!(
136 result_init_auth.err().unwrap().service_specific_error(),
137 Error::INVALID_DICE_CERT_CHAIN.0
138 );
139 }
140
141 #[test]
test_authmgr_init_auth_no_instance_id()142 fn test_authmgr_init_auth_no_instance_id() {
143 // Test the IAuthMgrAuthorization AIDL interface - initAuthentication with no instance id,
144 // expect error.
145 // Connect and send message indicating the intent to connect to the RPC service
146 let conn_rpc =
147 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
148 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
149 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
150 let cb = || {
151 let fd = conn_rpc.as_raw_fd();
152 Some(fd)
153 };
154 let rpc_session = RpcSession::new();
155 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
156 rpc_session.setup_preconnected_client(cb),
157 "Failed to setup pre-connected client for the authmgr rpc service."
158 );
159 // Create a test DICE chain (with CDI secrets for signing) without instance hash
160 let (_signing_key, _cdi_values, cert_chain) = create_dice_cert_chain_for_guest_os(None, 1);
161 let result_init_auth = rpc_session
162 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
163 // Expect error because the instance hash is neither in the DICE chain nor provided externally
164 assert!(result_init_auth.is_err());
165 assert_eq!(
166 result_init_auth.err().unwrap().service_specific_error(),
167 Error::INVALID_INSTANCE_IDENTIFIER.0
168 );
169 }
170
171 #[test]
test_authmgr_duplicate_init_auth_with_same_vm_id()172 fn test_authmgr_duplicate_init_auth_with_same_vm_id() {
173 // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, from
174 // the same transport id (i.e. VM-ID), expect error.
175 // Connect and send message indicating the intent to connect to the RPC service
176 let conn_rpc =
177 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
178 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
179 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
180 let cb = || {
181 let fd = conn_rpc.as_raw_fd();
182 Some(fd)
183 };
184 let rpc_session = RpcSession::new();
185 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
186 rpc_session.setup_preconnected_client(cb),
187 "Failed to setup pre-connected client for the authmgr rpc service."
188 );
189 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
190 let (_signing_key, _cdi_values, cert_chain) =
191 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
192 let result_init_auth = rpc_session
193 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain.clone() }, None);
194 let _challenge: [u8; TOKEN_LENGTH] =
195 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
196
197 let result_init_auth2 = rpc_session
198 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
199 assert!(result_init_auth2.is_err());
200 assert_eq!(
201 result_init_auth2.err().unwrap().service_specific_error(),
202 Error::AUTHENTICATION_ALREADY_STARTED.0
203 );
204 }
205
206 #[test]
test_authmgr_duplicate_init_auth_with_same_vm_id_after_cache_cleanup()207 fn test_authmgr_duplicate_init_auth_with_same_vm_id_after_cache_cleanup() {
208 // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, from
209 // the same transport id (i.e. VM-ID), but after cache cleanup triggered by closing the initial
210 // connection, expect success.
211 // Connect and send message indicating the intent to connect to the RPC service
212 let conn_rpc =
213 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
214 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
215 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
216 let cb = || {
217 let fd = conn_rpc.as_raw_fd();
218 Some(fd)
219 };
220 let rpc_session = RpcSession::new();
221 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
222 rpc_session.setup_preconnected_client(cb),
223 "Failed to setup pre-connected client for the authmgr rpc service."
224 );
225 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
226 let (_signing_key, _cdi_values, cert_chain) =
227 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
228 let result_init_auth = rpc_session
229 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain.clone() }, None);
230 let _challenge: [u8; TOKEN_LENGTH] =
231 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
232 // Drop the first connection to trigger cache cleanup
233 core::mem::drop(conn_rpc);
234
235 // Setup a new connection
236 let conn_rpc_2 =
237 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
238 assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
239 let cb_authmgr_2 = || {
240 let fd = conn_rpc_2.as_raw_fd();
241 Some(fd)
242 };
243
244 // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
245 let rpc_session_2 = RpcSession::new();
246 let rpc_session_2: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
247 rpc_session_2.setup_preconnected_client(cb_authmgr_2),
248 "Failed to setup pre-connected client for the authmgr rpc service."
249 );
250
251 let result_init_auth2 = rpc_session_2
252 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
253 let _challenge: [u8; TOKEN_LENGTH] = assert_ok!(result_init_auth2);
254 }
255
256 #[test]
test_authmgr_complete_auth_ok()257 fn test_authmgr_complete_auth_ok() {
258 // Test the IAuthMgrAuthorization AIDL interface - completeAuthentication, expect success.
259 let conn_rpc =
260 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
261 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
262 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
263 let cb = || {
264 let fd = conn_rpc.as_raw_fd();
265 Some(fd)
266 };
267 let rpc_session = RpcSession::new();
268 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
269 rpc_session.setup_preconnected_client(cb),
270 "Failed to setup pre-connected client for the authmgr rpc service."
271 );
272 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
273 let (signing_key, _cdi_values, cert_chain_bytes) =
274 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
275 let result_init_auth = rpc_session.initAuthentication(
276 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
277 None,
278 );
279 let challenge: [u8; TOKEN_LENGTH] =
280 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
281
282 let cert_chain =
283 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
284 // Build the connection request to be signed
285 let conn_req = ConnectionRequest::new_for_ffa_transport(
286 challenge,
287 TEMP_AUTHMGR_FE_TRANSPORT_ID,
288 TEMP_AUTHMGR_BE_TRANSPORT_ID,
289 );
290 // Sign the connection request with the DICE CDI secrets
291 let ecdsa = BoringEcDsa;
292 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
293 let signing_algorithm = verify_key.get_cose_sign_algorithm();
294 let signature = assert_ok!(
295 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
296 "Failed to sign connection request"
297 );
298 // Create a DICE policy
299 let constraint_spec = get_constraints_spec_for_trusty_vm();
300 let policy = assert_ok!(
301 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
302 "Failed to building policy for pvm"
303 );
304
305 // ****** Invoke step 2 of phase 1 of the protocol ******
306 let result_complete_auth = rpc_session.completeAuthentication(
307 &SignedConnectionRequest { signedConnectionRequest: signature },
308 &DicePolicy {
309 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
310 },
311 );
312 assert_ok!(result_complete_auth);
313 }
314
315 #[test]
test_authmgr_duplicate_init_auth_on_authenticated_connection()316 fn test_authmgr_duplicate_init_auth_on_authenticated_connection() {
317 // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, over
318 // an already authenticated connection, expect error.
319 // Connect and send message indicating the intent to connect to the RPC service
320 let conn_rpc =
321 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
322 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
323 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
324 let cb = || {
325 let fd = conn_rpc.as_raw_fd();
326 Some(fd)
327 };
328 let rpc_session = RpcSession::new();
329 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
330 rpc_session.setup_preconnected_client(cb),
331 "Failed to setup pre-connected client for the authmgr rpc service."
332 );
333 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
334 let (signing_key, _cdi_values, cert_chain_bytes) =
335 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
336 let result_init_auth = rpc_session.initAuthentication(
337 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
338 None,
339 );
340 let challenge: [u8; TOKEN_LENGTH] =
341 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
342
343 let cert_chain =
344 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
345 // Build the connection request to be signed
346 let conn_req = ConnectionRequest::new_for_ffa_transport(
347 challenge,
348 TEMP_AUTHMGR_FE_TRANSPORT_ID,
349 TEMP_AUTHMGR_BE_TRANSPORT_ID,
350 );
351 // Sign the connection request with the DICE CDI secrets
352 let ecdsa = BoringEcDsa;
353 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
354 let signing_algorithm = verify_key.get_cose_sign_algorithm();
355 let signature = assert_ok!(
356 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
357 "Failed to sign connection request"
358 );
359 // Create a DICE policy
360 let constraint_spec = get_constraints_spec_for_trusty_vm();
361 let policy = assert_ok!(
362 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
363 "Failed to building policy for pvm"
364 );
365
366 // ****** Invoke step 2 of phase 1 of the protocol ******
367 let result_complete_auth = rpc_session.completeAuthentication(
368 &SignedConnectionRequest { signedConnectionRequest: signature },
369 &DicePolicy {
370 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
371 },
372 );
373 assert_ok!(result_complete_auth);
374
375 // ******* Invoke step 1 of phase 1 of the protocol over the same connection ********
376 let result_init_auth2 = rpc_session
377 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes }, None);
378 assert!(result_init_auth2.is_err());
379 assert_eq!(
380 result_init_auth2.err().unwrap().service_specific_error(),
381 Error::INSTANCE_ALREADY_AUTHENTICATED.0
382 );
383 }
384
385 #[test]
test_authmgr_duplicate_init_auth_with_same_instance_id_of_authenticatd_vm_on_new_connection()386 fn test_authmgr_duplicate_init_auth_with_same_instance_id_of_authenticatd_vm_on_new_connection() {
387 // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, using
388 // the same instance id of an authenticated pvm, over a new connection, expect error.
389 // Connect and send message indicating the intent to connect to the RPC service
390 let conn_rpc =
391 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
392 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
393 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
394 let cb = || {
395 let fd = conn_rpc.as_raw_fd();
396 Some(fd)
397 };
398 let rpc_session = RpcSession::new();
399 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
400 rpc_session.setup_preconnected_client(cb),
401 "Failed to setup pre-connected client for the authmgr rpc service."
402 );
403 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
404 let (signing_key, _cdi_values, cert_chain_bytes) =
405 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
406 let result_init_auth = rpc_session.initAuthentication(
407 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
408 None,
409 );
410 let challenge: [u8; TOKEN_LENGTH] =
411 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
412
413 let cert_chain =
414 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
415 // Build the connection request to be signed
416 let conn_req = ConnectionRequest::new_for_ffa_transport(
417 challenge,
418 TEMP_AUTHMGR_FE_TRANSPORT_ID,
419 TEMP_AUTHMGR_BE_TRANSPORT_ID,
420 );
421 // Sign the connection request with the DICE CDI secrets
422 let ecdsa = BoringEcDsa;
423 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
424 let signing_algorithm = verify_key.get_cose_sign_algorithm();
425 let signature = assert_ok!(
426 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
427 "Failed to sign connection request"
428 );
429 // Create a DICE policy
430 let constraint_spec = get_constraints_spec_for_trusty_vm();
431 let policy = assert_ok!(
432 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
433 "Failed to building policy for pvm"
434 );
435
436 // ****** Invoke step 2 of phase 1 of the protocol ******
437 let result_complete_auth = rpc_session.completeAuthentication(
438 &SignedConnectionRequest { signedConnectionRequest: signature },
439 &DicePolicy {
440 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
441 },
442 );
443 assert_ok!(result_complete_auth);
444
445 // ******* Invoke step 1 of phase 1 of the protocol over a different connection ********
446 let conn_rpc_2 = assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT));
447 assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
448 let cb_authmgr_2 = || {
449 let fd = conn_rpc_2.as_raw_fd();
450 Some(fd)
451 };
452
453 // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
454 let rpc_session_2 = RpcSession::new();
455 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
456 rpc_session_2.setup_preconnected_client(cb_authmgr_2),
457 "Failed to setup pre-connected client for the authmgr rpc service."
458 );
459
460 let result_init_auth2 = rpc_session
461 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes }, None);
462 assert!(result_init_auth2.is_err());
463 assert_eq!(
464 result_init_auth2.err().unwrap().service_specific_error(),
465 Error::INSTANCE_ALREADY_AUTHENTICATED.0
466 );
467 }
468
469 #[test]
test_authmgr_duplicate_init_auth_with_diff_instance_ids_same_vm_id_of_authenticatd_vm_on_new_connection( )470 fn test_authmgr_duplicate_init_auth_with_diff_instance_ids_same_vm_id_of_authenticatd_vm_on_new_connection(
471 ) {
472 // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, using
473 // different instance ids, but the same vm-id of an authenticated pvm, over a new connection,
474 // expect error.
475 // Connect and send message indicating the intent to connect to the RPC service
476 let conn_rpc =
477 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
478 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
479 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
480 let cb = || {
481 let fd = conn_rpc.as_raw_fd();
482 Some(fd)
483 };
484 let rpc_session = RpcSession::new();
485 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
486 rpc_session.setup_preconnected_client(cb),
487 "Failed to setup pre-connected client for the authmgr rpc service."
488 );
489 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
490 let (signing_key, _cdi_values, cert_chain_bytes) =
491 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
492 let result_init_auth = rpc_session.initAuthentication(
493 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
494 None,
495 );
496 let challenge: [u8; TOKEN_LENGTH] =
497 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
498
499 let cert_chain =
500 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
501 // Build the connection request to be signed
502 let conn_req = ConnectionRequest::new_for_ffa_transport(
503 challenge,
504 TEMP_AUTHMGR_FE_TRANSPORT_ID,
505 TEMP_AUTHMGR_BE_TRANSPORT_ID,
506 );
507 // Sign the connection request with the DICE CDI secrets
508 let ecdsa = BoringEcDsa;
509 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
510 let signing_algorithm = verify_key.get_cose_sign_algorithm();
511 let signature = assert_ok!(
512 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
513 "Failed to sign connection request"
514 );
515 // Create a DICE policy
516 let constraint_spec = get_constraints_spec_for_trusty_vm();
517 let policy = assert_ok!(
518 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
519 "Failed to building policy for pvm"
520 );
521
522 // ****** Invoke step 2 of phase 1 of the protocol ******
523 let result_complete_auth = rpc_session.completeAuthentication(
524 &SignedConnectionRequest { signedConnectionRequest: signature },
525 &DicePolicy {
526 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
527 },
528 );
529 assert_ok!(result_complete_auth);
530
531 // Create a DICE chain with a different instance hash
532 pub const DIFF_INSTANCE_HASH: [u8; 64] = [
533 0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x21, 0x09, 0x9c, 0xf3, 0xcd, 0xc7, 0xa4,
534 0x2a, 0x7d, 0x7e, 0xf5, 0x8e, 0xd6, 0x4d, 0x82, 0x25, 0x1a, 0x51, 0x27, 0x9d, 0x55, 0x8a,
535 0xe9, 0x90, 0xf5, 0x8e, 0xd6, 0x4d, 0x84, 0x25, 0x1a, 0x51, 0x27, 0x9d, 0x5b, 0x3f, 0xc9,
536 0x6a, 0xe3, 0x95, 0x59, 0x40, 0x21, 0x09, 0x3d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0x7d, 0x7e,
537 0xf5, 0x8e, 0xf5, 0x8e,
538 ];
539 let (_signing_key_2, _cdi_values_2, cert_chain_bytes_2) =
540 create_dice_cert_chain_for_guest_os(Some(DIFF_INSTANCE_HASH), 1);
541
542 // ******* Invoke step 1 of phase 1 of the protocol over a different connection ********
543 let conn_rpc_2 = assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT));
544 assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
545 let cb_authmgr_2 = || {
546 let fd = conn_rpc_2.as_raw_fd();
547 Some(fd)
548 };
549
550 // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
551 let rpc_session_2 = RpcSession::new();
552 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
553 rpc_session_2.setup_preconnected_client(cb_authmgr_2),
554 "Failed to setup pre-connected client for the authmgr rpc service."
555 );
556
557 let result_init_auth2 = rpc_session
558 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes_2 }, None);
559 assert!(result_init_auth2.is_err());
560 assert_eq!(
561 result_init_auth2.err().unwrap().service_specific_error(),
562 Error::INSTANCE_ALREADY_AUTHENTICATED.0
563 );
564 }
565
566 #[test]
test_authmgr_raw_command_without_authentication()567 fn test_authmgr_raw_command_without_authentication() {
568 // Test the AuthMgr Init Service by sending CMD_RAW over the connection, which should result in
569 // an error and connection close at the service side because the previous steps of the protocol
570 // have not been performed yet. The only way we can assert that this results in an error in the
571 // service is by waiting for `recv` on the connection and trying to send another command and
572 // asserting that it fails.
573 let conn_raw =
574 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
575
576 let mut token = [0u8; TOKEN_LENGTH];
577 let boring_rng = BoringRng;
578 boring_rng.fill_bytes(&mut token);
579 let mut msg = Vec::<u8>::new();
580 msg.push(CMD_RAW);
581 msg.extend_from_slice(&token);
582 let cmd_raw = AuthMgrMessage(msg);
583 assert_ok!(conn_raw.send(&cmd_raw));
584
585 pub struct AuthMgrMessage(pub Vec<u8>);
586
587 impl Deserialize for AuthMgrMessage {
588 type Error = TipcError;
589 const MAX_SERIALIZED_SIZE: usize = 4000;
590
591 fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, TipcError> {
592 Ok(AuthMgrMessage(Vec::try_alloc_from(bytes)?))
593 }
594 }
595
596 impl<'s> Serialize<'s> for AuthMgrMessage {
597 fn serialize<'a: 's, S: Serializer<'s>>(
598 &'a self,
599 serializer: &mut S,
600 ) -> Result<S::Ok, S::Error> {
601 serializer.serialize_bytes(self.0.as_slice())
602 }
603 }
604
605 let mut buf = [0u8; 1];
606 let _resul: Result<AuthMgrMessage, TipcError> = conn_raw.recv(&mut buf);
607
608 let result2 = conn_raw.send(&cmd_raw);
609 assert!(result2.is_err());
610 }
611
612 #[test]
test_authmgr_complete_auth_without_init_auth()613 fn test_authmgr_complete_auth_without_init_auth() {
614 // Test IAuthMgrAuthorization AIDL interface - by invoking completeAuthentication without
615 // invoking initAuthentication before - expect error
616 let conn_rpc =
617 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
618 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
619 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
620 let cb = || {
621 let fd = conn_rpc.as_raw_fd();
622 Some(fd)
623 };
624 let rpc_session = RpcSession::new();
625 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
626 rpc_session.setup_preconnected_client(cb),
627 "Failed to setup pre-connected client for the authmgr rpc service."
628 );
629 let result_complete_auth = rpc_session.completeAuthentication(
630 &SignedConnectionRequest { signedConnectionRequest: Vec::new() },
631 &DicePolicy { dicePolicy: Vec::new() },
632 );
633 assert!(result_complete_auth.is_err());
634 assert_eq!(
635 result_complete_auth.err().unwrap().service_specific_error(),
636 Error::AUTHENTICATION_NOT_STARTED.0
637 );
638 }
639
640 #[test]
test_authmgr_duplicate_complete_auth_on_the_same_connection()641 fn test_authmgr_duplicate_complete_auth_on_the_same_connection() {
642 // Test IAuthMgrAuthorization AIDL interface - by invoking completeAuthentication on an alerady
643 // authenticated connection.
644 let conn_rpc =
645 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
646 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
647 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
648 let cb = || {
649 let fd = conn_rpc.as_raw_fd();
650 Some(fd)
651 };
652 let rpc_session = RpcSession::new();
653 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
654 rpc_session.setup_preconnected_client(cb),
655 "Failed to setup pre-connected client for the authmgr rpc service."
656 );
657 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
658 let (signing_key, _cdi_values, cert_chain_bytes) =
659 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
660 let result_init_auth = rpc_session.initAuthentication(
661 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
662 None,
663 );
664 let challenge: [u8; TOKEN_LENGTH] =
665 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
666
667 let cert_chain =
668 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
669 // Build the connection request to be signed
670 let conn_req = ConnectionRequest::new_for_ffa_transport(
671 challenge,
672 TEMP_AUTHMGR_FE_TRANSPORT_ID,
673 TEMP_AUTHMGR_BE_TRANSPORT_ID,
674 );
675 // Sign the connection request with the DICE CDI secrets
676 let ecdsa = BoringEcDsa;
677 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
678 let signing_algorithm = verify_key.get_cose_sign_algorithm();
679 let signature = assert_ok!(
680 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
681 "Failed to sign connection request"
682 );
683 // Create a DICE policy
684 let constraint_spec = get_constraints_spec_for_trusty_vm();
685 let policy = assert_ok!(
686 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
687 "Failed to building policy for pvm"
688 );
689
690 // ****** Invoke step 2 of phase 1 of the protocol ******
691 let result_complete_auth = rpc_session.completeAuthentication(
692 &SignedConnectionRequest { signedConnectionRequest: signature.clone() },
693 &DicePolicy {
694 dicePolicy: assert_ok!(policy.clone().to_vec(), "Failed to encode DICE policy for pvm"),
695 },
696 );
697 assert_ok!(result_complete_auth);
698
699 let result_complete_auth2 = rpc_session.completeAuthentication(
700 &SignedConnectionRequest { signedConnectionRequest: signature },
701 &DicePolicy {
702 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
703 },
704 );
705 assert!(result_complete_auth2.is_err());
706 assert_eq!(
707 result_complete_auth2.err().unwrap().service_specific_error(),
708 Error::INSTANCE_ALREADY_AUTHENTICATED.0
709 );
710 }
711
712 #[test]
test_authmgr_duplicate_complete_auth_on_new_connection()713 fn test_authmgr_duplicate_complete_auth_on_new_connection() {
714 // Test the IAuthMgrAuthorization AIDL interface - by invoking completeAuthentication from
715 // an authenticated pvm, over a new connection, expect error.
716 // Connect and send message indicating the intent to connect to the RPC service
717 let conn_rpc =
718 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
719 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
720 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
721 let cb = || {
722 let fd = conn_rpc.as_raw_fd();
723 Some(fd)
724 };
725 let rpc_session = RpcSession::new();
726 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
727 rpc_session.setup_preconnected_client(cb),
728 "Failed to setup pre-connected client for the authmgr rpc service."
729 );
730 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
731 let (signing_key, _cdi_values, cert_chain_bytes) =
732 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
733 let result_init_auth = rpc_session.initAuthentication(
734 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
735 None,
736 );
737 let challenge: [u8; TOKEN_LENGTH] =
738 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
739
740 let cert_chain =
741 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
742 // Build the connection request to be signed
743 let conn_req = ConnectionRequest::new_for_ffa_transport(
744 challenge,
745 TEMP_AUTHMGR_FE_TRANSPORT_ID,
746 TEMP_AUTHMGR_BE_TRANSPORT_ID,
747 );
748 // Sign the connection request with the DICE CDI secrets
749 let ecdsa = BoringEcDsa;
750 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
751 let signing_algorithm = verify_key.get_cose_sign_algorithm();
752 let signature = assert_ok!(
753 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
754 "Failed to sign connection request"
755 );
756 // Create a DICE policy
757 let constraint_spec = get_constraints_spec_for_trusty_vm();
758 let policy = assert_ok!(
759 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
760 "Failed to building policy for pvm"
761 );
762
763 // ****** Invoke step 2 of phase 1 of the protocol ******
764 let result_complete_auth = rpc_session.completeAuthentication(
765 &SignedConnectionRequest { signedConnectionRequest: signature.clone() },
766 &DicePolicy {
767 dicePolicy: assert_ok!(policy.clone().to_vec(), "Failed to encode DICE policy for pvm"),
768 },
769 );
770 assert_ok!(result_complete_auth);
771
772 // ******* Invoke step 2 of phase 1 of the protocol over a different connection ********
773 let conn_rpc_2 = assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT));
774 assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
775 let cb_authmgr_2 = || {
776 let fd = conn_rpc_2.as_raw_fd();
777 Some(fd)
778 };
779
780 // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
781 let rpc_session_2 = RpcSession::new();
782 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
783 rpc_session_2.setup_preconnected_client(cb_authmgr_2),
784 "Failed to setup pre-connected client for the authmgr rpc service."
785 );
786
787 let result_complete_auth_2 = rpc_session.completeAuthentication(
788 &SignedConnectionRequest { signedConnectionRequest: signature },
789 &DicePolicy {
790 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
791 },
792 );
793 assert!(result_complete_auth_2.is_err());
794 assert_eq!(
795 result_complete_auth_2.err().unwrap().service_specific_error(),
796 Error::INSTANCE_ALREADY_AUTHENTICATED.0
797 );
798 }
799
800 #[test]
test_authmgr_duplicate_complete_auth_after_cache_cleanup()801 fn test_authmgr_duplicate_complete_auth_after_cache_cleanup() {
802 // Test the IAuthMgrAuthorization AIDL interface - with two attempts for phase 1, from
803 // the same transport id (i.e. VM-ID), but after cache cleanup triggered by closing the initial
804 // connection, expect success.
805 // Connect and send message indicating the intent to connect to the RPC service
806 let conn_rpc =
807 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
808 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
809 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
810 let cb = || {
811 let fd = conn_rpc.as_raw_fd();
812 Some(fd)
813 };
814 let rpc_session = RpcSession::new();
815 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
816 rpc_session.setup_preconnected_client(cb),
817 "Failed to setup pre-connected client for the authmgr rpc service."
818 );
819 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
820 let (signing_key, _cdi_values, cert_chain_bytes) =
821 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
822 let result_init_auth = rpc_session.initAuthentication(
823 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
824 None,
825 );
826 let challenge: [u8; TOKEN_LENGTH] =
827 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
828
829 let cert_chain =
830 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
831 // Build the connection request to be signed
832 let conn_req = ConnectionRequest::new_for_ffa_transport(
833 challenge,
834 TEMP_AUTHMGR_FE_TRANSPORT_ID,
835 TEMP_AUTHMGR_BE_TRANSPORT_ID,
836 );
837 // Sign the connection request with the DICE CDI secrets
838 let ecdsa = BoringEcDsa;
839 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
840 let signing_algorithm = verify_key.get_cose_sign_algorithm();
841 let signature = assert_ok!(
842 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
843 "Failed to sign connection request"
844 );
845 // Create a DICE policy
846 let constraint_spec = get_constraints_spec_for_trusty_vm();
847 let policy = assert_ok!(
848 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
849 "Failed to building policy for pvm"
850 );
851
852 // ****** Invoke step 2 of phase 1 of the protocol ******
853 let result_complete_auth = rpc_session.completeAuthentication(
854 &SignedConnectionRequest { signedConnectionRequest: signature },
855 &DicePolicy {
856 dicePolicy: assert_ok!(policy.clone().to_vec(), "Failed to encode DICE policy for pvm"),
857 },
858 );
859 assert_ok!(result_complete_auth);
860
861 // Drop the first connection to trigger cache cleanup
862 core::mem::drop(conn_rpc);
863
864 // Setup a new connection
865 let conn_rpc_2 =
866 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
867 assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
868 let cb_authmgr_2 = || {
869 let fd = conn_rpc_2.as_raw_fd();
870 Some(fd)
871 };
872
873 // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
874 let rpc_session_2 = RpcSession::new();
875 let rpc_session_2: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
876 rpc_session_2.setup_preconnected_client(cb_authmgr_2),
877 "Failed to setup pre-connected client for the authmgr rpc service."
878 );
879
880 let result_init_auth_2 = rpc_session_2
881 .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes }, None);
882 let challenge_2: [u8; TOKEN_LENGTH] = assert_ok!(result_init_auth_2);
883
884 // Build the connection request to be signed
885 let conn_req_2 = ConnectionRequest::new_for_ffa_transport(
886 challenge_2,
887 TEMP_AUTHMGR_FE_TRANSPORT_ID,
888 TEMP_AUTHMGR_BE_TRANSPORT_ID,
889 );
890 let signature_2 = assert_ok!(
891 conn_req_2.sign(&signing_key, &ecdsa, signing_algorithm),
892 "Failed to sign connection request"
893 );
894
895 let result_complete_auth_2 = rpc_session_2.completeAuthentication(
896 &SignedConnectionRequest { signedConnectionRequest: signature_2 },
897 &DicePolicy {
898 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
899 },
900 );
901 assert_ok!(result_complete_auth_2);
902 }
903
904 #[test]
authmgr_full_protocol_happy_path()905 fn authmgr_full_protocol_happy_path() {
906 // Connect to the TA and send message indicating the intent to connect to the binder RPC service
907 let conn_rpc =
908 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
909 let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
910 assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
911 let cb = || {
912 let fd = conn_rpc.as_raw_fd();
913 Some(fd)
914 };
915 let rpc_session = RpcSession::new();
916 let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
917 rpc_session.setup_preconnected_client(cb),
918 "Failed to setup pre-connected client for the authmgr rpc service."
919 );
920 // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
921 let (signing_key, cdi_values, cert_chain_bytes) =
922 create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
923 let result_init_auth = rpc_session.initAuthentication(
924 &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
925 None,
926 );
927 let challenge: [u8; TOKEN_LENGTH] =
928 assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
929
930 let cert_chain =
931 assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
932 // Build the connection request to be signed
933 let conn_req = ConnectionRequest::new_for_ffa_transport(
934 challenge,
935 TEMP_AUTHMGR_FE_TRANSPORT_ID,
936 TEMP_AUTHMGR_BE_TRANSPORT_ID,
937 );
938 // Sign the connection request with the DICE CDI secrets
939 let ecdsa = BoringEcDsa;
940 let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
941 let signing_algorithm = verify_key.get_cose_sign_algorithm();
942 let signature = assert_ok!(
943 conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
944 "Failed to sign connection request"
945 );
946 // Create a DICE policy
947 let constraint_spec = get_constraints_spec_for_trusty_vm();
948 let policy = assert_ok!(
949 dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
950 "Failed to building policy for pvm"
951 );
952
953 // ****** Invoke step 2 of phase 1 of the protocol ******
954 let result_complete_auth = rpc_session.completeAuthentication(
955 &SignedConnectionRequest { signedConnectionRequest: signature },
956 &DicePolicy {
957 dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
958 },
959 );
960 assert_ok!(result_complete_auth);
961
962 // Connect to the TA and send a message indicating the intent establish a raw connection and
963 // send a token
964 let conn_raw =
965 assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to setup a raw connection");
966 let mut token = [0u8; TOKEN_LENGTH];
967 let boring_rng = BoringRng;
968 boring_rng.fill_bytes(&mut token);
969 let mut msg = Vec::<u8>::new();
970 msg.push(CMD_RAW);
971 msg.extend_from_slice(&token);
972 let cmd_raw = AuthMgrMessage(msg);
973 assert_ok!(conn_raw.send(&cmd_raw));
974
975 // ****** Execute phase 2 of the AuthMgr protocol ******
976 // Create DICE certificate and a DICE policy for the client
977 let leaf_cert_bytes = create_dice_leaf_cert(cdi_values, "keymint", 1);
978 let client_constraint_spec_km = get_constraint_spec_for_static_trusty_ta();
979 let leaf_cert =
980 assert_ok!(DiceChainEntry::from_slice(&leaf_cert_bytes), "Failed to decode leaf cert");
981 let client_policy = assert_ok!(
982 policy_for_dice_node(&leaf_cert, client_constraint_spec_km),
983 "Failed to create policy for leaf cert"
984 );
985 let result_client_authz = rpc_session.authorizeAndConnectClientToTrustedService(
986 &[],
987 "HelloService",
988 &token,
989 &DiceLeafArtifacts {
990 diceLeaf: AidlDiceChainEntry { diceChainEntry: leaf_cert_bytes },
991 diceLeafPolicy: DicePolicy {
992 dicePolicy: assert_ok!(
993 client_policy.to_vec(),
994 "Failed to encode client dice policy."
995 ),
996 },
997 },
998 );
999 assert_ok!(result_client_authz);
1000
1001 // Simulate the client connecting to the IHelloWorld example trusted service over the raw
1002 // connection authorized via AuthMgr protocol execution above
1003 let cb_trusted_hal = || {
1004 let fd = conn_raw.as_raw_fd();
1005 Some(fd)
1006 };
1007
1008 let trusted_service_rpc_session = RpcSession::new();
1009 let trusted_service_rpc_session: Strong<dyn IHelloWorld> = assert_ok!(
1010 trusted_service_rpc_session.setup_preconnected_client(cb_trusted_hal),
1011 "Failed to setup pre-connected client for the trusted service."
1012 );
1013 let result = assert_ok!(trusted_service_rpc_session.sayHello("Test."));
1014 assert_eq!("Hello Test.", result);
1015 }
1016