private void initializeSessionsV2(SessionState aliceSessionState, SessionState bobSessionState) { ECKeyPair aliceIdentityKeyPair = Curve.generateKeyPair(); IdentityKeyPair aliceIdentityKey = new IdentityKeyPair(new IdentityKey(aliceIdentityKeyPair.getPublicKey()), aliceIdentityKeyPair.getPrivateKey()); ECKeyPair aliceBaseKey = Curve.generateKeyPair(); ECKeyPair aliceEphemeralKey = Curve.generateKeyPair(); ECKeyPair bobIdentityKeyPair = Curve.generateKeyPair(); IdentityKeyPair bobIdentityKey = new IdentityKeyPair(new IdentityKey(bobIdentityKeyPair.getPublicKey()), bobIdentityKeyPair.getPrivateKey()); ECKeyPair bobBaseKey = Curve.generateKeyPair(); ECKeyPair bobEphemeralKey = bobBaseKey; AliceAxolotlParameters aliceParameters = AliceAxolotlParameters.newBuilder() .setOurIdentityKey(aliceIdentityKey) .setOurBaseKey(aliceBaseKey) .setTheirIdentityKey(bobIdentityKey.getPublicKey()) .setTheirSignedPreKey(bobEphemeralKey.getPublicKey()) .setTheirRatchetKey(bobEphemeralKey.getPublicKey()) .setTheirOneTimePreKey(May <ECPublicKey> .NoValue) .create(); BobAxolotlParameters bobParameters = BobAxolotlParameters.newBuilder() .setOurIdentityKey(bobIdentityKey) .setOurOneTimePreKey(May <ECKeyPair> .NoValue) .setOurRatchetKey(bobEphemeralKey) .setOurSignedPreKey(bobBaseKey) .setTheirBaseKey(aliceBaseKey.getPublicKey()) .setTheirIdentityKey(aliceIdentityKey.getPublicKey()) .create(); RatchetingSession.initializeSession(aliceSessionState, 2, aliceParameters); RatchetingSession.initializeSession(bobSessionState, 2, bobParameters); }
public void TestSignature() { ECKeyPair serverKey = Curve.generateKeyPair(); ECKeyPair key = Curve.generateKeyPair(); byte[] certificateBytes = new libsignalmetadata.protobuf.SenderCertificate.Types.Certificate() { Sender = "+14152222222", SenderDevice = 1, Expires = 31337, IdentityKey = ByteString.CopyFrom(key.getPublicKey().serialize()), Signer = GetServerCertificate(serverKey) }.ToByteArray(); byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes); SenderCertificate senderCertificate = new SenderCertificate(new libsignalmetadata.protobuf.SenderCertificate() { Certificate = ByteString.CopyFrom(certificateBytes), Signature = ByteString.CopyFrom(certificateSignature) }.ToByteArray()); new CertificateValidator(TrustRoot.getPublicKey()).Validate(senderCertificate, 31336); }
public void testBadMessageBundle() { SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore(); SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore(); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(); byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(), bobSignedPreKeyPair.getPublicKey().serialize()); PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1, 31337, bobPreKeyPair.getPublicKey(), 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature, bobStore.GetIdentityKeyPair().getPublicKey()); bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature)); aliceSessionBuilder.process(bobPreKey); String originalMessage = "L'homme est condamné à être libre"; SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage)); Assert.AreEqual(CiphertextMessage.PREKEY_TYPE, outgoingMessageOne.getType()); byte[] goodMessage = outgoingMessageOne.serialize(); byte[] badMessage = new byte[goodMessage.Length]; Array.Copy(goodMessage, 0, badMessage, 0, badMessage.Length); badMessage[badMessage.Length - 10] ^= 0x01; PreKeySignalMessage incomingMessage = new PreKeySignalMessage(badMessage); SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = new byte[0]; try { plaintext = bobSessionCipher.decrypt(incomingMessage); throw new Exception("Decrypt should have failed!"); } catch (InvalidMessageException) { // good. } Assert.IsTrue(bobStore.ContainsPreKey(31337)); plaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(goodMessage)); Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext)); Assert.IsFalse(bobStore.ContainsPreKey(31337)); }
public void testRepeatBundleMessageV3() { SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore(); SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore(); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(); byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(), bobSignedPreKeyPair.getPublicKey().serialize()); PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1, 31337, bobPreKeyPair.getPublicKey(), 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature, bobStore.GetIdentityKeyPair().getPublicKey()); bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature)); aliceSessionBuilder.process(bobPreKey); String originalMessage = "L'homme est condamné à être libre"; SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage)); CiphertextMessage outgoingMessageTwo = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage)); Assert.AreEqual(CiphertextMessage.PREKEY_TYPE, outgoingMessageOne.getType()); Assert.AreEqual(CiphertextMessage.PREKEY_TYPE, outgoingMessageTwo.getType()); PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessageOne.serialize()); SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = bobSessionCipher.decrypt(incomingMessage); Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext)); CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage)); byte[] alicePlaintext = aliceSessionCipher.decrypt(new SignalMessage(bobOutgoingMessage.serialize())); Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(alicePlaintext)); // The test PreKeySignalMessage incomingMessageTwo = new PreKeySignalMessage(outgoingMessageTwo.serialize()); plaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(incomingMessageTwo.serialize())); Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext)); bobOutgoingMessage = bobSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage)); alicePlaintext = aliceSessionCipher.decrypt(new SignalMessage(bobOutgoingMessage.serialize())); Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(alicePlaintext)); }
public void testMatchingFingerprints() { ECKeyPair aliceKeyPair = Curve.generateKeyPair(); ECKeyPair bobKeyPair = Curve.generateKeyPair(); IdentityKey aliceIdentityKey = new IdentityKey(aliceKeyPair.getPublicKey()); IdentityKey bobIdentityKey = new IdentityKey(bobKeyPair.getPublicKey()); NumericFingerprintGenerator generator = new NumericFingerprintGenerator(1024); Fingerprint aliceFingerprint = generator.createFor("+14152222222", aliceIdentityKey, "+14153333333", bobIdentityKey); Fingerprint bobFingerprint = generator.createFor("+14153333333", bobIdentityKey, "+14152222222", aliceIdentityKey); Assert.AreEqual <string>(aliceFingerprint.getDisplayableFingerprint().getDisplayText(), bobFingerprint.getDisplayableFingerprint().getDisplayText()); Assert.IsTrue( aliceFingerprint.getScannableFingerprint().compareTo( bobFingerprint.getScannableFingerprint().getSerialized())); Assert.IsTrue( bobFingerprint.getScannableFingerprint().compareTo( aliceFingerprint.getScannableFingerprint().getSerialized())); Assert.AreEqual <int>(aliceFingerprint.getDisplayableFingerprint().getDisplayText().Length, 60); }
/** * Initiate a new session by sending an initial KeyExchangeMessage to the recipient. * * @return the KeyExchangeMessage to deliver. */ public KeyExchangeMessage process() { lock (SessionCipher.SESSION_LOCK) { try { uint sequence = KeyHelper.getRandomSequence(65534) + 1; uint flags = KeyExchangeMessage.INITIATE_FLAG; ECKeyPair baseKey = Curve.generateKeyPair(); ECKeyPair ratchetKey = Curve.generateKeyPair(); IdentityKeyPair identityKey = identityKeyStore.GetIdentityKeyPair(); byte[] baseKeySignature = Curve.calculateSignature(identityKey.getPrivateKey(), baseKey.getPublicKey().serialize()); SessionRecord sessionRecord = sessionStore.LoadSession(remoteAddress); sessionRecord.getSessionState().setPendingKeyExchange(sequence, baseKey, ratchetKey, identityKey); sessionStore.StoreSession(remoteAddress, sessionRecord); return(new KeyExchangeMessage(CiphertextMessage.CURRENT_VERSION, sequence, flags, baseKey.getPublicKey(), baseKeySignature, ratchetKey.getPublicKey(), identityKey.getPublicKey())); } catch (InvalidKeyException e) { throw new Exception(e.Message); } } }
private static IdentityKeyPair generateIdentityKeyPair() { ECKeyPair identityKeyPairKeys = Curve.generateKeyPair(); return(new IdentityKeyPair(new IdentityKey(identityKeyPairKeys.getPublicKey()), identityKeyPairKeys.getPrivateKey())); }
private void GenerateKey(IDataStore dataStore, object context) { keyPair = Curve.generateKeyPair(); dataStore.SetString(context, "privateKey", Convert.ToBase64String(keyPair.getPrivateKey().serialize())); dataStore.SetString(context, "publicKey", Convert.ToBase64String(keyPair.getPublicKey().serialize())); }
public void testMismatchingFingerprints() { ECKeyPair aliceKeyPair = Curve.generateKeyPair(); ECKeyPair bobKeyPair = Curve.generateKeyPair(); ECKeyPair mitmKeyPair = Curve.generateKeyPair(); IdentityKey aliceIdentityKey = new IdentityKey(aliceKeyPair.getPublicKey()); IdentityKey bobIdentityKey = new IdentityKey(bobKeyPair.getPublicKey()); IdentityKey mitmIdentityKey = new IdentityKey(mitmKeyPair.getPublicKey()); NumericFingerprintGenerator generator = new NumericFingerprintGenerator(1024); Fingerprint aliceFingerprint = generator.createFor(VERSION_1, Encoding.UTF8.GetBytes("+14152222222"), aliceIdentityKey, Encoding.UTF8.GetBytes("+14153333333"), mitmIdentityKey); Fingerprint bobFingerprint = generator.createFor(VERSION_1, Encoding.UTF8.GetBytes("+14153333333"), bobIdentityKey, Encoding.UTF8.GetBytes("+14152222222"), aliceIdentityKey); Assert.AreNotEqual(aliceFingerprint.getDisplayableFingerprint().getDisplayText(), bobFingerprint.getDisplayableFingerprint().getDisplayText()); Assert.IsFalse(aliceFingerprint.getScannableFingerprint().compareTo(bobFingerprint.getScannableFingerprint().getSerialized())); Assert.IsFalse(bobFingerprint.getScannableFingerprint().compareTo(aliceFingerprint.getScannableFingerprint().getSerialized())); }
public void TestEncryptFromWrongIdentity() { TestInMemorySignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore(); TestInMemorySignalProtocolStore bobStore = new TestInMemorySignalProtocolStore(); InitializeSessions(aliceStore, bobStore); ECKeyPair trustRoot = Curve.generateKeyPair(); ECKeyPair randomKeyPair = Curve.generateKeyPair(); SenderCertificate senderCertificate = CreateCertificateFor(trustRoot, "+14151111111", 1, randomKeyPair.getPublicKey(), 31337); SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, new SignalProtocolAddress("+14151111111", 1)); byte[] ciphertext = aliceCipher.Encrypt(new SignalProtocolAddress("+14152222222", 1), senderCertificate, Encoding.ASCII.GetBytes("smert za smert")); SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, new SignalProtocolAddress("+14152222222", 1)); try { bobCipher.Decrypt(new CertificateValidator(trustRoot.getPublicKey()), ciphertext, 31335); } catch (InvalidMetadataMessageException) { // good } }
/// <summary> /// Generate an identity key pair. Clients should only do this once, at install time. /// </summary> /// <returns>the generated IdentityKeyPair.</returns> public static IdentityKeyPair generateIdentityKeyPair() { ECKeyPair keyPair = Curve.generateKeyPair(); IdentityKey publicKey = new IdentityKey(keyPair.getPublicKey()); return(new IdentityKeyPair(publicKey, keyPair.getPrivateKey())); }
private SenderCertificate CreateCertificateFor(ECKeyPair trustRoot, String sender, int deviceId, ECPublicKey identityKey, long expires) { ECKeyPair serverKey = Curve.generateKeyPair(); byte[] serverCertificateBytes = new libsignalmetadata.protobuf.ServerCertificate.Types.Certificate() { Id = 1, Key = ByteString.CopyFrom(serverKey.getPublicKey().serialize()) }.ToByteArray(); byte[] serverCertificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), serverCertificateBytes); ServerCertificate serverCertificate = new ServerCertificate(new libsignalmetadata.protobuf.ServerCertificate() { Certificate = ByteString.CopyFrom(serverCertificateBytes), Signature = ByteString.CopyFrom(serverCertificateSignature) }.ToByteArray()); byte[] senderCertificateBytes = new libsignalmetadata.protobuf.SenderCertificate.Types.Certificate { Sender = sender, SenderDevice = (uint)deviceId, IdentityKey = ByteString.CopyFrom(identityKey.serialize()), Expires = (ulong)expires, Signer = libsignalmetadata.protobuf.ServerCertificate.Parser.ParseFrom(serverCertificate.Serialized) }.ToByteArray(); byte[] senderCertificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), senderCertificateBytes); return(new SenderCertificate(new libsignalmetadata.protobuf.SenderCertificate() { Certificate = ByteString.CopyFrom(senderCertificateBytes), Signature = ByteString.CopyFrom(senderCertificateSignature) }.ToByteArray())); }
public void testOptionalOneTimePreKey() { SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore(); SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore(); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(); byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(), bobSignedPreKeyPair.getPublicKey().serialize()); PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1, 0, null, 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature, bobStore.GetIdentityKeyPair().getPublicKey()); aliceSessionBuilder.process(bobPreKey); Assert.IsTrue(aliceStore.ContainsSession(BOB_ADDRESS)); Assert.AreEqual((uint)3, aliceStore.LoadSession(BOB_ADDRESS).getSessionState().getSessionVersion()); String originalMessage = "L'homme est condamné à être libre"; SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessage = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage)); Assert.AreEqual(outgoingMessage.getType(), CiphertextMessage.PREKEY_TYPE); PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessage.serialize()); Assert.IsFalse(incomingMessage.getPreKeyId().HasValue); bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature)); SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = bobSessionCipher.decrypt(incomingMessage); Assert.IsTrue(bobStore.ContainsSession(ALICE_ADDRESS)); Assert.AreEqual((uint)3, bobStore.LoadSession(ALICE_ADDRESS).getSessionState().getSessionVersion()); Assert.IsNotNull(bobStore.LoadSession(ALICE_ADDRESS).getSessionState().getAliceBaseKey()); Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext)); }
/** * Build a new session from a {@link org.whispersystems.libaxolotl.state.PreKeyBundle} retrieved from * a server. * * @param preKey A PreKey for the destination recipient, retrieved from a server. * @throws InvalidKeyException when the {@link org.whispersystems.libaxolotl.state.PreKeyBundle} is * badly formatted. * @throws org.whispersystems.libaxolotl.UntrustedIdentityException when the sender's * {@link IdentityKey} is not * trusted. */ public void process(PreKeyBundle preKey) { lock (SessionCipher.SESSION_LOCK) { if (!identityKeyStore.IsTrustedIdentity(remoteAddress.getName(), preKey.getIdentityKey())) { throw new UntrustedIdentityException(remoteAddress.getName(), preKey.getIdentityKey()); } if (preKey.getSignedPreKey() != null && !Curve.verifySignature(preKey.getIdentityKey().getPublicKey(), preKey.getSignedPreKey().serialize(), preKey.getSignedPreKeySignature())) { throw new InvalidKeyException("Invalid signature on device key!"); } if (preKey.getSignedPreKey() == null && preKey.getPreKey() == null) { throw new InvalidKeyException("Both signed and unsigned prekeys are absent!"); } bool supportsV3 = preKey.getSignedPreKey() != null; SessionRecord sessionRecord = sessionStore.LoadSession(remoteAddress); ECKeyPair ourBaseKey = Curve.generateKeyPair(); ECPublicKey theirSignedPreKey = supportsV3 ? preKey.getSignedPreKey() : preKey.getPreKey(); ECPublicKey test = preKey.getPreKey(); // TODO: cleanup May <ECPublicKey> theirOneTimePreKey = (test == null) ? May <ECPublicKey> .NoValue : new May <ECPublicKey>(test); May <uint> theirOneTimePreKeyId = theirOneTimePreKey.HasValue ? new May <uint>(preKey.getPreKeyId()) : May <uint> .NoValue; AliceAxolotlParameters.Builder parameters = AliceAxolotlParameters.newBuilder(); parameters.setOurBaseKey(ourBaseKey) .setOurIdentityKey(identityKeyStore.GetIdentityKeyPair()) .setTheirIdentityKey(preKey.getIdentityKey()) .setTheirSignedPreKey(theirSignedPreKey) .setTheirRatchetKey(theirSignedPreKey) .setTheirOneTimePreKey(supportsV3 ? theirOneTimePreKey : May <ECPublicKey> .NoValue); if (!sessionRecord.isFresh()) { sessionRecord.archiveCurrentState(); } RatchetingSession.initializeSession(sessionRecord.getSessionState(), supportsV3 ? (uint)3 : 2, parameters.create()); sessionRecord.getSessionState().setUnacknowledgedPreKeyMessage(theirOneTimePreKeyId, preKey.getSignedPreKeyId(), ourBaseKey.getPublicKey()); sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.GetLocalRegistrationId()); sessionRecord.getSessionState().setRemoteRegistrationId(preKey.getRegistrationId()); sessionRecord.getSessionState().setAliceBaseKey(ourBaseKey.getPublicKey().serialize()); sessionStore.StoreSession(remoteAddress, sessionRecord); identityKeyStore.SaveIdentity(remoteAddress.getName(), preKey.getIdentityKey()); } }
private PreKeyBundle createBobPreKeyBundle(SignalProtocolStore bobStore) { ECKeyPair bobUnsignedPreKey = Curve.generateKeyPair(); int bobUnsignedPreKeyId = new Random().Next((int)Medium.MAX_VALUE); byte[] bobSignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(), bobSignedPreKey.getPublicKey().serialize()); PreKeyBundle bobPreKeyBundle = new PreKeyBundle(1, 1, (uint)bobUnsignedPreKeyId, bobUnsignedPreKey.getPublicKey(), bobSignedPreKeyId, bobSignedPreKey.getPublicKey(), bobSignature, bobStore.GetIdentityKeyPair().getPublicKey()); bobStore.StoreSignedPreKey(bobSignedPreKeyId, new SignedPreKeyRecord(bobSignedPreKeyId, (ulong)DateTime.UtcNow.Ticks, bobSignedPreKey, bobSignature)); bobStore.StorePreKey((uint)bobUnsignedPreKeyId, new PreKeyRecord((uint)bobUnsignedPreKeyId, bobUnsignedPreKey)); return(bobPreKeyBundle); }
public PreKeyRecord(uint id, ECKeyPair keyPair) { this.structure = new PreKeyRecordStructure { Id = id, PublicKey = ByteString.CopyFrom(keyPair.getPublicKey().serialize()), PrivateKey = ByteString.CopyFrom(keyPair.getPrivateKey().serialize()) }; }
private PreKeyBundle createBobPreKeyBundle(AxolotlStore bobStore) { ECKeyPair bobUnsignedPreKey = Curve.generateKeyPair(); uint bobUnsignedPreKeyId = (uint)new Random().Next((int)Medium.MAX_VALUE); byte[] bobSignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(), bobSignedPreKey.getPublicKey().serialize()); PreKeyBundle bobPreKeyBundle = new PreKeyBundle(1, 1, bobUnsignedPreKeyId, bobUnsignedPreKey.getPublicKey(), bobSignedPreKeyId, bobSignedPreKey.getPublicKey(), bobSignature, bobStore.GetIdentityKeyPair().getPublicKey()); bobStore.StoreSignedPreKey(bobSignedPreKeyId, new SignedPreKeyRecord(bobSignedPreKeyId, DateUtil.currentTimeMillis(), bobSignedPreKey, bobSignature)); bobStore.StorePreKey(bobUnsignedPreKeyId, new PreKeyRecord(bobUnsignedPreKeyId, bobUnsignedPreKey)); return(bobPreKeyBundle); }
private PreKeyBundle createAlicePreKeyBundle(SignalProtocolStore aliceStore) { ECKeyPair aliceUnsignedPreKey = Curve.generateKeyPair(); int aliceUnsignedPreKeyId = new Random().Next((int)Medium.MAX_VALUE); byte[] aliceSignature = Curve.calculateSignature(aliceStore.GetIdentityKeyPair().getPrivateKey(), aliceSignedPreKey.getPublicKey().serialize()); PreKeyBundle alicePreKeyBundle = new PreKeyBundle(1, 1, (uint)aliceUnsignedPreKeyId, aliceUnsignedPreKey.getPublicKey(), aliceSignedPreKeyId, aliceSignedPreKey.getPublicKey(), aliceSignature, aliceStore.GetIdentityKeyPair().getPublicKey()); aliceStore.StoreSignedPreKey(aliceSignedPreKeyId, new SignedPreKeyRecord(aliceSignedPreKeyId, (ulong)DateTime.UtcNow.Ticks, aliceSignedPreKey, aliceSignature)); aliceStore.StorePreKey((uint)aliceUnsignedPreKeyId, new PreKeyRecord((uint)aliceUnsignedPreKeyId, aliceUnsignedPreKey)); return(alicePreKeyBundle); }
public void testBadSignedPreKeySignature() { SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore(); SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); IdentityKeyStore bobIdentityKeyStore = new TestInMemoryIdentityKeyStore(); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(); byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.GetIdentityKeyPair().getPrivateKey(), bobSignedPreKeyPair.getPublicKey().serialize()); for (int i = 0; i < bobSignedPreKeySignature.Length * 8; i++) { byte[] modifiedSignature = new byte[bobSignedPreKeySignature.Length]; Array.Copy(bobSignedPreKeySignature, 0, modifiedSignature, 0, modifiedSignature.Length); modifiedSignature[i / 8] ^= (byte)(0x01 << (i % 8)); PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.GetLocalRegistrationId(), 1, 31337, bobPreKeyPair.getPublicKey(), 22, bobSignedPreKeyPair.getPublicKey(), modifiedSignature, bobIdentityKeyStore.GetIdentityKeyPair().getPublicKey()); try { aliceSessionBuilder.process(bobPreKey); throw new Exception("Accepted modified device key signature!"); } catch (InvalidKeyException) { // good } } PreKeyBundle bobPreKey2 = new PreKeyBundle(bobIdentityKeyStore.GetLocalRegistrationId(), 1, 31337, bobPreKeyPair.getPublicKey(), 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature, bobIdentityKeyStore.GetIdentityKeyPair().getPublicKey()); aliceSessionBuilder.process(bobPreKey2); }
public PreKeyRecord(uint id, ECKeyPair keyPair) { this.structure = PreKeyRecordStructure.CreateBuilder() .SetId(id) .SetPublicKey(ByteString.CopyFrom(keyPair.getPublicKey() .serialize())) .SetPrivateKey(ByteString.CopyFrom(keyPair.getPrivateKey() .serialize())) .Build(); }
public SignedPreKeyRecord(uint id, ulong timestamp, ECKeyPair keyPair, byte[] signature) { this.structure = new SignedPreKeyRecordStructure { Id = id, PublicKey = ByteString.CopyFrom(keyPair.getPublicKey().serialize()), PrivateKey = ByteString.CopyFrom(keyPair.getPrivateKey().serialize()), Signature = ByteString.CopyFrom(signature), Timestamp = timestamp }; }
public static void generateCurve25519IdentityKeys() { //MasterCipher masterCipher = new MasterCipher(masterSecret); ECKeyPair djbKeyPair = Curve.generateKeyPair(); IdentityKey djbIdentityKey = new IdentityKey(djbKeyPair.getPublicKey()); byte[] djbPrivateKey = /*masterCipher.encryptKey(*/ djbKeyPair.getPrivateKey().serialize() /*)*/; save(IDENTITY_PUBLIC_KEY_DJB_PREF, System.Convert.ToBase64String(djbIdentityKey.serialize())); save(IDENTITY_PRIVATE_KEY_DJB_PREF, System.Convert.ToBase64String(djbPrivateKey)); }
public SignedPreKeyRecord(uint id, ulong timestamp, ECKeyPair keyPair, byte[] signature) { structure = SignedPreKeyRecordStructure.CreateBuilder() .SetId(id) .SetPublicKey(ByteString.CopyFrom(keyPair.getPublicKey() .serialize())) .SetPrivateKey(ByteString.CopyFrom(keyPair.getPrivateKey() .serialize())) .SetSignature(ByteString.CopyFrom(signature)) .SetTimestamp(timestamp) .Build(); }
public void TestDecodeSize() { ECKeyPair keyPair = Curve.generateKeyPair(); byte[] serializedPublic = keyPair.getPublicKey().serialize(); ECPublicKey justRight = Curve.decodePoint(serializedPublic, 0); try { ECPublicKey tooSmall = Curve.decodePoint(serializedPublic, 1); Assert.Fail("Shouldn't decode"); } catch (InvalidKeyException e) { // good } try { ECPublicKey empty = Curve.decodePoint(new byte[0], 0); Assert.Fail("Shouldn't parse"); } catch (InvalidKeyException e) { // good } try { byte[] badKeyType = new byte[33]; Array.Copy(serializedPublic, 0, badKeyType, 0, serializedPublic.Length); badKeyType[0] = 0x01; Curve.decodePoint(badKeyType, 0); Assert.Fail("Should be bad key type"); } catch (InvalidKeyException e) { // good } byte[] extraSpace = new byte[serializedPublic.Length + 1]; Array.Copy(serializedPublic, 0, extraSpace, 0, serializedPublic.Length); ECPublicKey extra = Curve.decodePoint(extraSpace, 0); byte[] offsetSpace = new byte[serializedPublic.Length + 1]; Array.Copy(serializedPublic, 0, offsetSpace, 1, serializedPublic.Length); ECPublicKey offset = Curve.decodePoint(offsetSpace, 1); CollectionAssert.AreEqual(serializedPublic, justRight.serialize()); CollectionAssert.AreEqual(extra.serialize(), serializedPublic); CollectionAssert.AreEqual(offset.serialize(), serializedPublic); }
public void testRandomAgreements() { for (int i = 0; i < 50; i++) { ECKeyPair alice = Curve.generateKeyPair(); ECKeyPair bob = Curve.generateKeyPair(); byte[] sharedAlice = Curve.calculateAgreement(bob.getPublicKey(), alice.getPrivateKey()); byte[] sharedBob = Curve.calculateAgreement(alice.getPublicKey(), bob.getPrivateKey()); CollectionAssert.AreEqual(sharedAlice, sharedBob); } }
private void InitializeSessions(TestInMemorySignalProtocolStore aliceStore, TestInMemorySignalProtocolStore bobStore) { ECKeyPair bobPreKey = Curve.generateKeyPair(); IdentityKeyPair bobIdentityKey = bobStore.GetIdentityKeyPair(); SignedPreKeyRecord bobSignedPreKey = KeyHelper.generateSignedPreKey(bobIdentityKey, 2); PreKeyBundle bobBundle = new PreKeyBundle(1, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey()); SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, new SignalProtocolAddress("+14152222222", 1)); aliceSessionBuilder.process(bobBundle); bobStore.StoreSignedPreKey(2, bobSignedPreKey); bobStore.StorePreKey(1, new PreKeyRecord(1, bobPreKey)); }
public void setSenderChain(ECKeyPair senderRatchetKeyPair, ChainKey chainKey) { Chain.Types.ChainKey chainKeyStructure = Chain.Types.ChainKey.CreateBuilder() .SetKey(ByteString.CopyFrom(chainKey.getKey())) .SetIndex(chainKey.getIndex()) .Build(); Chain senderChain = Chain.CreateBuilder() .SetSenderRatchetKey(ByteString.CopyFrom(senderRatchetKeyPair.getPublicKey().serialize())) .SetSenderRatchetKeyPrivate(ByteString.CopyFrom(senderRatchetKeyPair.getPrivateKey().serialize())) .SetChainKey(chainKeyStructure) .Build(); this.sessionStructure = this.sessionStructure.ToBuilder().SetSenderChain(senderChain).Build(); }
private libsignalmetadata.protobuf.ServerCertificate GetServerCertificate(ECKeyPair serverKey) { byte[] certificateBytes = new libsignalmetadata.protobuf.ServerCertificate.Types.Certificate() { Id = 1, Key = ByteString.CopyFrom(serverKey.getPublicKey().serialize()) }.ToByteArray(); byte[] certificateSignature = Curve.calculateSignature(TrustRoot.getPrivateKey(), certificateBytes); return(new libsignalmetadata.protobuf.ServerCertificate() { Certificate = ByteString.CopyFrom(certificateBytes), Signature = ByteString.CopyFrom(certificateSignature) }); }
public void setSenderChain(ECKeyPair senderRatchetKeyPair, ChainKey chainKey) { Chain.Types.ChainKey chainKeyStructure = new Chain.Types.ChainKey { Key = ByteString.CopyFrom(chainKey.getKey()), Index = chainKey.getIndex() }; Chain senderChain = new Chain { SenderRatchetKey = ByteString.CopyFrom(senderRatchetKeyPair.getPublicKey().serialize()), SenderRatchetKeyPrivate = ByteString.CopyFrom(senderRatchetKeyPair.getPrivateKey().serialize()), ChainKey = chainKeyStructure }; this.sessionStructure.SenderChain = senderChain; }
public void setPendingKeyExchange(uint sequence, ECKeyPair ourBaseKey, ECKeyPair ourRatchetKey, IdentityKeyPair ourIdentityKey) { PendingKeyExchange structure = new PendingKeyExchange { LocalBaseKey = ByteString.CopyFrom(ourBaseKey.getPublicKey().serialize()), LocalBaseKeyPrivate = ByteString.CopyFrom(ourBaseKey.getPrivateKey().serialize()), LocalRatchetKey = ByteString.CopyFrom(ourRatchetKey.getPublicKey().serialize()), LocalRatchetKeyPrivate = ByteString.CopyFrom(ourRatchetKey.getPrivateKey().serialize()), LocalIdentityKey = ByteString.CopyFrom(ourIdentityKey.getPublicKey().serialize()), LocalIdentityKeyPrivate = ByteString.CopyFrom(ourIdentityKey.getPrivateKey().serialize()) }; this.sessionStructure.PendingKeyExchange = structure; }