예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }