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); }
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 byte[] Encrypt(SignalProtocolAddress destinationAddress, SenderCertificate senderCertificate, byte[] paddedPlaintext) { CiphertextMessage message = new SessionCipher(SignalProtocolStore, destinationAddress).encrypt(paddedPlaintext); IdentityKeyPair ourIdentity = SignalProtocolStore.GetIdentityKeyPair(); ECPublicKey theirIdentity = SignalProtocolStore.GetIdentity(destinationAddress).getPublicKey(); ECKeyPair ephemeral = Curve.generateKeyPair(); byte[] ephemeralSalt = ByteUtil.combine(Encoding.ASCII.GetBytes("UnidentifiedDelivery"), theirIdentity.serialize(), ephemeral.getPublicKey().serialize()); EphemeralKeys ephemeralKeys = CalculateEphemeralKeys(theirIdentity, ephemeral.getPrivateKey(), ephemeralSalt); byte[] staticKeyCiphertext = Encrypt(ephemeralKeys.CipherKey, ephemeralKeys.MacKey, ourIdentity.getPublicKey().getPublicKey().serialize()); byte[] staticSalt = ByteUtil.combine(ephemeralKeys.ChainKey, staticKeyCiphertext); StaticKeys staticKeys = CalculateStaticKeys(theirIdentity, ourIdentity.getPrivateKey(), staticSalt); UnidentifiedSenderMessageContent content = new UnidentifiedSenderMessageContent((int)message.getType(), senderCertificate, message.serialize()); byte[] messageBytes = Encrypt(staticKeys.CipherKey, staticKeys.MacKey, content.Serialized); return(new UnidentifiedSenderMessage(ephemeral.getPublicKey(), staticKeyCiphertext, messageBytes).Serialized); }
public (SignalProtocolAddress, byte[]) Decrypt(CertificateValidator validator, byte[] ciphertext, long timestamp) { UnidentifiedSenderMessageContent content; try { IdentityKeyPair ourIdentity = SignalProtocolStore.GetIdentityKeyPair(); UnidentifiedSenderMessage wrapper = new UnidentifiedSenderMessage(ciphertext); byte[] ephemeralSalt = ByteUtil.combine(Encoding.ASCII.GetBytes("UnidentifiedDelivery"), ourIdentity.getPublicKey().getPublicKey().serialize(), wrapper.Ephemeral.serialize()); EphemeralKeys ephemeralKeys = CalculateEphemeralKeys(wrapper.Ephemeral, ourIdentity.getPrivateKey(), ephemeralSalt); byte[] staticKeyBytes = Decrypt(ephemeralKeys.CipherKey, ephemeralKeys.MacKey, wrapper.EncryptedStatic); ECPublicKey staticKey = Curve.decodePoint(staticKeyBytes, 0); byte[] staticSalt = ByteUtil.combine(ephemeralKeys.ChainKey, wrapper.EncryptedStatic); StaticKeys staticKeys = CalculateStaticKeys(staticKey, ourIdentity.getPrivateKey(), staticSalt); byte[] messageBytes = Decrypt(staticKeys.CipherKey, staticKeys.MacKey, wrapper.EncryptedMessage); content = new UnidentifiedSenderMessageContent(messageBytes); validator.Validate(content.SenderCertificate, timestamp); if (!Enumerable.SequenceEqual(content.SenderCertificate.Key.serialize(), staticKeyBytes)) { throw new libsignal.InvalidKeyException("Sender's certificate key does not match key used in message"); } if (content.SenderCertificate.Sender == LocalAddress.Name && content.SenderCertificate.SenderDeviceId == LocalAddress.DeviceId) { throw new SelfSendException(); } } catch (libsignal.InvalidKeyException e) { throw new InvalidMetadataMessageException(e); } catch (InvalidCertificateException e) { throw new InvalidMetadataMessageException(e); } catch (InvalidMacException e) { throw new InvalidMetadataMessageException(e); } try { return(new SignalProtocolAddress(content.SenderCertificate.Sender, (uint)content.SenderCertificate.SenderDeviceId), Decrypt(content)); } catch (InvalidMessageException e) { throw new ProtocolInvalidMessageException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } catch (libsignal.InvalidKeyException e) { throw new ProtocolInvalidKeyException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } catch (NoSessionException e) { throw new ProtocolNoSessionException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } catch (LegacyMessageException e) { throw new ProtocolLegacyMessageException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } catch (InvalidVersionException e) { throw new ProtocolInvalidVersionException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } catch (DuplicateMessageException e) { throw new ProtocolDuplicateMessageException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } catch (InvalidKeyIdException e) { throw new ProtocolInvalidKeyIdException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } catch (UntrustedIdentityException e) { throw new ProtocolUntrustedIdentityException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId); } }