authgraph: add parallel session VTS tests

Test: VtsAidlAuthGraphSessionTest
Change-Id: Idcf79afe838fdbfb88bd7f43fe758ac03d9ba0d1
This commit is contained in:
David Drysdale
2023-10-03 15:58:13 +01:00
committed by Hasini Gunasinghe
parent c8625a8963
commit d42cb6fa69

View File

@@ -166,6 +166,171 @@ TEST_P(AuthGraphSessionTest, Mainline) {
// encoded as `sink_info.sharedKeys` and `source_info.sharedKeys`.
}
TEST_P(AuthGraphSessionTest, ParallelSink) {
std::shared_ptr<IAuthGraphKeyExchange> source = authNode_;
std::shared_ptr<IAuthGraphKeyExchange> sink1 = authNode_;
std::shared_ptr<IAuthGraphKeyExchange> sink2 = authNode_;
// Step 1: create ephemeral ECDH keys at the source.
SessionInitiationInfo source_init1_info;
ASSERT_EQ(OK, GetReturnError(source->create(&source_init1_info)));
ASSERT_TRUE(source_init1_info.key.pubKey.has_value());
ASSERT_TRUE(source_init1_info.key.arcFromPBK.has_value());
SessionInitiationInfo source_init2_info;
ASSERT_EQ(OK, GetReturnError(source->create(&source_init2_info)));
ASSERT_TRUE(source_init2_info.key.pubKey.has_value());
ASSERT_TRUE(source_init2_info.key.arcFromPBK.has_value());
// Step 2: pass the source's ECDH public keys and other session info to the sinks.
KeInitResult init1_result;
ASSERT_EQ(OK, GetReturnError(sink1->init(source_init1_info.key.pubKey.value(),
source_init1_info.identity, source_init1_info.nonce,
source_init1_info.version, &init1_result)));
SessionInitiationInfo sink1_init_info = init1_result.sessionInitiationInfo;
ASSERT_TRUE(sink1_init_info.key.pubKey.has_value());
SessionInfo sink1_info = init1_result.sessionInfo;
ASSERT_EQ((int)sink1_info.sharedKeys.size(), 2) << "Expect two symmetric keys from init()";
ASSERT_GT((int)sink1_info.sessionId.size(), 0) << "Expect non-empty session ID from sink";
std::vector<uint8_t> sink1_signing_key = SigningKeyFromIdentity(sink1_init_info.identity);
CheckSignature(sink1_signing_key, sink1_info.sessionId, sink1_info.signature);
KeInitResult init2_result;
ASSERT_EQ(OK, GetReturnError(sink2->init(source_init2_info.key.pubKey.value(),
source_init2_info.identity, source_init2_info.nonce,
source_init2_info.version, &init2_result)));
SessionInitiationInfo sink2_init_info = init2_result.sessionInitiationInfo;
ASSERT_TRUE(sink2_init_info.key.pubKey.has_value());
SessionInfo sink2_info = init2_result.sessionInfo;
ASSERT_EQ((int)sink2_info.sharedKeys.size(), 2) << "Expect two symmetric keys from init()";
ASSERT_GT((int)sink2_info.sessionId.size(), 0) << "Expect non-empty session ID from sink";
std::vector<uint8_t> sink2_signing_key = SigningKeyFromIdentity(sink2_init_info.identity);
CheckSignature(sink2_signing_key, sink2_info.sessionId, sink2_info.signature);
// Step 3: pass each sink's ECDH public key and other session info to the source, so it can
// calculate the same pair of symmetric keys.
SessionInfo source_info1;
ASSERT_EQ(OK, GetReturnError(source->finish(sink1_init_info.key.pubKey.value(),
sink1_init_info.identity, sink1_info.signature,
sink1_init_info.nonce, sink1_init_info.version,
source_init1_info.key, &source_info1)));
ASSERT_EQ((int)source_info1.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()";
ASSERT_GT((int)source_info1.sessionId.size(), 0) << "Expect non-empty session ID from source";
std::vector<uint8_t> source_signing_key1 = SigningKeyFromIdentity(source_init1_info.identity);
CheckSignature(source_signing_key1, source_info1.sessionId, source_info1.signature);
SessionInfo source_info2;
ASSERT_EQ(OK, GetReturnError(source->finish(sink2_init_info.key.pubKey.value(),
sink2_init_info.identity, sink2_info.signature,
sink2_init_info.nonce, sink2_init_info.version,
source_init2_info.key, &source_info2)));
ASSERT_EQ((int)source_info2.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()";
ASSERT_GT((int)source_info2.sessionId.size(), 0) << "Expect non-empty session ID from source";
std::vector<uint8_t> source_signing_key2 = SigningKeyFromIdentity(source_init2_info.identity);
CheckSignature(source_signing_key2, source_info2.sessionId, source_info2.signature);
// Both ends should agree on the session ID.
ASSERT_EQ(source_info1.sessionId, sink1_info.sessionId);
ASSERT_EQ(source_info2.sessionId, sink2_info.sessionId);
// Step 4: pass the source's session ID info back to the sink, so it can check it and
// update the symmetric keys so they're marked as authentication complete.
std::array<Arc, 2> auth_complete_result1;
ASSERT_EQ(OK, GetReturnError(sink1->authenticationComplete(
source_info1.signature, sink1_info.sharedKeys, &auth_complete_result1)));
ASSERT_EQ((int)auth_complete_result1.size(), 2)
<< "Expect two symmetric keys from authComplete()";
sink1_info.sharedKeys = auth_complete_result1;
std::array<Arc, 2> auth_complete_result2;
ASSERT_EQ(OK, GetReturnError(sink2->authenticationComplete(
source_info2.signature, sink2_info.sharedKeys, &auth_complete_result2)));
ASSERT_EQ((int)auth_complete_result2.size(), 2)
<< "Expect two symmetric keys from authComplete()";
sink2_info.sharedKeys = auth_complete_result2;
}
TEST_P(AuthGraphSessionTest, ParallelSource) {
std::shared_ptr<IAuthGraphKeyExchange> source1 = authNode_;
std::shared_ptr<IAuthGraphKeyExchange> source2 = authNode_;
std::shared_ptr<IAuthGraphKeyExchange> sink = authNode_;
// Step 1: create an ephemeral ECDH key at each of the sources.
SessionInitiationInfo source1_init_info;
ASSERT_EQ(OK, GetReturnError(source1->create(&source1_init_info)));
ASSERT_TRUE(source1_init_info.key.pubKey.has_value());
ASSERT_TRUE(source1_init_info.key.arcFromPBK.has_value());
SessionInitiationInfo source2_init_info;
ASSERT_EQ(OK, GetReturnError(source1->create(&source2_init_info)));
ASSERT_TRUE(source2_init_info.key.pubKey.has_value());
ASSERT_TRUE(source2_init_info.key.arcFromPBK.has_value());
// Step 2: pass each source's ECDH public key and other session info to the sink.
KeInitResult init1_result;
ASSERT_EQ(OK, GetReturnError(sink->init(source1_init_info.key.pubKey.value(),
source1_init_info.identity, source1_init_info.nonce,
source1_init_info.version, &init1_result)));
SessionInitiationInfo sink_init1_info = init1_result.sessionInitiationInfo;
ASSERT_TRUE(sink_init1_info.key.pubKey.has_value());
SessionInfo sink_info1 = init1_result.sessionInfo;
ASSERT_EQ((int)sink_info1.sharedKeys.size(), 2) << "Expect two symmetric keys from init()";
ASSERT_GT((int)sink_info1.sessionId.size(), 0) << "Expect non-empty session ID from sink";
std::vector<uint8_t> sink_signing_key1 = SigningKeyFromIdentity(sink_init1_info.identity);
CheckSignature(sink_signing_key1, sink_info1.sessionId, sink_info1.signature);
KeInitResult init2_result;
ASSERT_EQ(OK, GetReturnError(sink->init(source2_init_info.key.pubKey.value(),
source2_init_info.identity, source2_init_info.nonce,
source2_init_info.version, &init2_result)));
SessionInitiationInfo sink_init2_info = init2_result.sessionInitiationInfo;
ASSERT_TRUE(sink_init2_info.key.pubKey.has_value());
SessionInfo sink_info2 = init2_result.sessionInfo;
ASSERT_EQ((int)sink_info2.sharedKeys.size(), 2) << "Expect two symmetric keys from init()";
ASSERT_GT((int)sink_info2.sessionId.size(), 0) << "Expect non-empty session ID from sink";
std::vector<uint8_t> sink_signing_key2 = SigningKeyFromIdentity(sink_init2_info.identity);
CheckSignature(sink_signing_key2, sink_info2.sessionId, sink_info2.signature);
// Step 3: pass the sink's ECDH public keys and other session info to the each of the sources.
SessionInfo source1_info;
ASSERT_EQ(OK, GetReturnError(source1->finish(sink_init1_info.key.pubKey.value(),
sink_init1_info.identity, sink_info1.signature,
sink_init1_info.nonce, sink_init1_info.version,
source1_init_info.key, &source1_info)));
ASSERT_EQ((int)source1_info.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()";
ASSERT_GT((int)source1_info.sessionId.size(), 0) << "Expect non-empty session ID from source";
std::vector<uint8_t> source1_signing_key = SigningKeyFromIdentity(source1_init_info.identity);
CheckSignature(source1_signing_key, source1_info.sessionId, source1_info.signature);
SessionInfo source2_info;
ASSERT_EQ(OK, GetReturnError(source2->finish(sink_init2_info.key.pubKey.value(),
sink_init2_info.identity, sink_info2.signature,
sink_init2_info.nonce, sink_init2_info.version,
source2_init_info.key, &source2_info)));
ASSERT_EQ((int)source2_info.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()";
ASSERT_GT((int)source2_info.sessionId.size(), 0) << "Expect non-empty session ID from source";
std::vector<uint8_t> source2_signing_key = SigningKeyFromIdentity(source2_init_info.identity);
CheckSignature(source2_signing_key, source2_info.sessionId, source2_info.signature);
// Both ends should agree on the session ID.
ASSERT_EQ(source1_info.sessionId, sink_info1.sessionId);
ASSERT_EQ(source2_info.sessionId, sink_info2.sessionId);
// Step 4: pass the each source's session ID info back to the sink, so it can check it and
// update the symmetric keys so they're marked as authentication complete.
std::array<Arc, 2> auth_complete_result1;
ASSERT_EQ(OK, GetReturnError(sink->authenticationComplete(
source1_info.signature, sink_info1.sharedKeys, &auth_complete_result1)));
ASSERT_EQ((int)auth_complete_result1.size(), 2)
<< "Expect two symmetric keys from authComplete()";
sink_info1.sharedKeys = auth_complete_result1;
std::array<Arc, 2> auth_complete_result2;
ASSERT_EQ(OK, GetReturnError(sink->authenticationComplete(
source2_info.signature, sink_info2.sharedKeys, &auth_complete_result2)));
ASSERT_EQ((int)auth_complete_result2.size(), 2)
<< "Expect two symmetric keys from authComplete()";
sink_info2.sharedKeys = auth_complete_result2;
}
TEST_P(AuthGraphSessionTest, FreshNonces) {
std::shared_ptr<IAuthGraphKeyExchange> source = authNode_;
std::shared_ptr<IAuthGraphKeyExchange> sink = authNode_;