processPreKeyBundle method
Implementation
Future<void> processPreKeyBundle(PreKeyBundle preKey) async {
if (!await _identityKeyStore.isTrustedIdentity(
_remoteAddress, preKey.getIdentityKey(), Direction.sending)) {
throw UntrustedIdentityException(
_remoteAddress.getName(), preKey.getIdentityKey());
}
if (preKey.getSignedPreKey() != null &&
!Curve.verifySignature(
preKey.getIdentityKey().publicKey,
preKey.getSignedPreKey()!.serialize(),
preKey.getSignedPreKeySignature())) {
throw InvalidKeyException('Invalid signature on device key!');
}
if (preKey.getSignedPreKey() == null) {
throw InvalidKeyException('No signed prekey!');
}
final sessionRecord = await _sessionStore.loadSession(_remoteAddress);
final ourBaseKey = Curve.generateKeyPair();
final theirSignedPreKey = preKey.getSignedPreKey();
final theirOneTimePreKey = Optional.ofNullable(preKey.getPreKey());
final theirOneTimePreKeyId = theirOneTimePreKey.isPresent
? Optional.ofNullable(preKey.getPreKeyId())
: const Optional<int>.empty();
final parameters = AliceSignalProtocolParameters(
ourBaseKey: ourBaseKey,
ourIdentityKey: await _identityKeyStore.getIdentityKeyPair(),
theirIdentityKey: preKey.getIdentityKey(),
theirSignedPreKey: theirSignedPreKey!,
theirRatchetKey: theirSignedPreKey,
theirOneTimePreKey: theirOneTimePreKey,
);
if (!sessionRecord.isFresh()) sessionRecord.archiveCurrentState();
RatchetingSession.initializeSessionAlice(
sessionRecord.sessionState, parameters);
sessionRecord.sessionState.setUnacknowledgedPreKeyMessage(
theirOneTimePreKeyId, preKey.getSignedPreKeyId(), ourBaseKey.publicKey);
sessionRecord.sessionState.localRegistrationId =
await _identityKeyStore.getLocalRegistrationId();
sessionRecord.sessionState.remoteRegistrationId =
preKey.getRegistrationId();
sessionRecord.sessionState.aliceBaseKey = ourBaseKey.publicKey.serialize();
await _identityKeyStore.saveIdentity(
_remoteAddress, preKey.getIdentityKey());
await _sessionStore.storeSession(_remoteAddress, sessionRecord);
}