Esempio n. 1
0
        /**
         * Encrypt a message.
         *
         * @param paddedPlaintext The plaintext message bytes, optionally padded.
         * @return Ciphertext.
         * @throws NoSessionException
         */
        public byte[] encrypt(byte[] paddedPlaintext)
        {
            lock (LOCK)
            {
                try
                {
                    SenderKeyRecord  record         = senderKeyStore.loadSenderKey(senderKeyId);
                    SenderKeyState   senderKeyState = record.getSenderKeyState();
                    SenderMessageKey senderKey      = senderKeyState.getSenderChainKey().getSenderMessageKey();
                    byte[]           ciphertext     = getCipherText(senderKey.getIv(), senderKey.getCipherKey(), paddedPlaintext);

                    SenderKeyMessage senderKeyMessage = new SenderKeyMessage(senderKeyState.getKeyId(),
                                                                             senderKey.getIteration(),
                                                                             ciphertext,
                                                                             senderKeyState.getSigningKeyPrivate());

                    senderKeyState.setSenderChainKey(senderKeyState.getSenderChainKey().getNext());

                    senderKeyStore.storeSenderKey(senderKeyId, record);

                    return(senderKeyMessage.serialize());
                }
                catch (InvalidKeyIdException e)
                {
                    throw new NoSessionException(e);
                }
            }
        }
        /**
         * Decrypt a SenderKey group message.
         *
         * @param senderKeyMessageBytes The received ciphertext.
         * @param callback   A callback that is triggered after decryption is complete,
         *                    but before the updated session state has been committed to the session
         *                    DB.  This allows some implementations to store the committed plaintext
         *                    to a DB first, in case they are concerned with a crash happening between
         *                    the time the session state is updated but before they're able to store
         *                    the plaintext to disk.
         * @return Plaintext
         * @throws LegacyMessageException
         * @throws InvalidMessageException
         * @throws DuplicateMessageException
         */
        public byte[] Decrypt(byte[] senderKeyMessageBytes, IDecryptionCallback callback)
        {
            lock (Lock)
            {
                try
                {
                    SenderKeyRecord record = _senderKeyStore.LoadSenderKey(_senderKeyId);

                    if (record.IsEmpty())
                    {
                        throw new NoSessionException("No sender key for: " + _senderKeyId);
                    }

                    SenderKeyMessage senderKeyMessage = new SenderKeyMessage(senderKeyMessageBytes);
                    SenderKeyState   senderKeyState   = record.GetSenderKeyState(senderKeyMessage.GetKeyId());

                    senderKeyMessage.VerifySignature(senderKeyState.GetSigningKeyPublic());

                    SenderMessageKey senderKey = GetSenderKey(senderKeyState, senderKeyMessage.GetIteration());

                    byte[] plaintext = GetPlainText(senderKey.GetIv(), senderKey.GetCipherKey(), senderKeyMessage.GetCipherText());

                    callback.HandlePlaintext(plaintext);

                    _senderKeyStore.StoreSenderKey(_senderKeyId, record);

                    return(plaintext);
                }
                catch (Exception e) when(e is InvalidKeyException || e is InvalidKeyIdException)
                {
                    throw new InvalidMessageException(e);
                }
            }
        }
Esempio n. 3
0
        public void addSenderMessageKey(SenderMessageKey senderMessageKey)
        {
            SenderKeyStateStructure.Types.SenderMessageKey senderMessageKeyStructure =
                SenderKeyStateStructure.Types.SenderMessageKey.CreateBuilder()
                .SetIteration(senderMessageKey.getIteration())
                .SetSeed(ByteString.CopyFrom(senderMessageKey.getSeed()))
                .Build();

            this.senderKeyStateStructure = this.senderKeyStateStructure.ToBuilder()
                                           .AddSenderMessageKeys(senderMessageKeyStructure)
                                           .Build();
        }
        public void AddSenderMessageKey(SenderMessageKey senderMessageKey)
        {
            SenderKeyStateStructure.Types.SenderMessageKey senderMessageKeyStructure = new SenderKeyStateStructure.Types.SenderMessageKey
            {
                Iteration = senderMessageKey.GetIteration(),
                Seed      = ByteString.CopyFrom(senderMessageKey.GetSeed())
            };
            _senderKeyStateStructure.SenderMessageKeys.Add(senderMessageKeyStructure);

            if (_senderKeyStateStructure.SenderMessageKeys.Count > MaxMessageKeys)
            {
                _senderKeyStateStructure.SenderMessageKeys.RemoveAt(0);
            }
        }
        public void addSenderMessageKey(SenderMessageKey senderMessageKey)
        {
            SenderKeyStateStructure.Types.SenderMessageKey senderMessageKeyStructure = new SenderKeyStateStructure.Types.SenderMessageKey
            {
                Iteration = senderMessageKey.getIteration(),
                Seed      = ByteString.CopyFrom(senderMessageKey.getSeed())
            };
            this.senderKeyStateStructure.SenderMessageKeys.Add(senderMessageKeyStructure);

            if (senderKeyStateStructure.SenderMessageKeys.Count > MAX_MESSAGE_KEYS)
            {
                senderKeyStateStructure.SenderMessageKeys.RemoveAt(0);
            }
        }
Esempio n. 6
0
        public void AddSenderMessageKey(SenderMessageKey senderMessageKey)
        {
            SenderKeyStateStructure.Types.SenderMessageKey senderMessageKeyStructure =
                SenderKeyStateStructure.Types.SenderMessageKey.CreateBuilder()
                .SetIteration(senderMessageKey.GetIteration())
                .SetSeed(ByteString.CopyFrom(senderMessageKey.GetSeed()))
                .Build();

            SenderKeyStateStructure.Builder builder = this.senderKeyStateStructure.ToBuilder();
            builder.AddSenderMessageKeys(senderMessageKeyStructure);

            if (builder.SenderMessageKeysList.Count > MAX_MESSAGE_KEYS)
            {
                builder.SenderMessageKeysList.RemoveAt(0);
            }
            this.senderKeyStateStructure = builder.Build();
        }
Esempio n. 7
0
        public void AddSenderMessageKey(SenderMessageKey senderMessageKey)
        {
            StorageProtos.SenderKeyStateStructure.Types.SenderMessageKey senderMessageKeyStructure =
                StorageProtos.SenderKeyStateStructure.Types.SenderMessageKey.CreateBuilder()
                .SetIteration(senderMessageKey.GetIteration())
                .SetSeed(ByteString.CopyFrom(senderMessageKey.GetSeed()))
                .Build();

            StorageProtos.SenderKeyStateStructure.Builder builder = _senderKeyStateStructure.ToBuilder();
            builder.AddSenderMessageKeys(senderMessageKeyStructure);

            if (builder.SenderMessageKeysList.Count > MaxMessageKeys)
            {
                builder.SenderMessageKeysList.RemoveAt(0);
            }
            _senderKeyStateStructure = builder.Build();
        }
Esempio n. 8
0
        /**
         * Decrypt a SenderKey group message.
         *
         * @param senderKeyMessageBytes The received ciphertext.
         * @param callback   A callback that is triggered after decryption is complete,
         *                    but before the updated session state has been committed to the session
         *                    DB.  This allows some implementations to store the committed plaintext
         *                    to a DB first, in case they are concerned with a crash happening between
         *                    the time the session state is updated but before they're able to store
         *                    the plaintext to disk.
         * @return Plaintext
         * @throws LegacyMessageException
         * @throws InvalidMessageException
         * @throws DuplicateMessageException
         */
        public byte[] decrypt(byte[] senderKeyMessageBytes, DecryptionCallback callback)
        {
            lock (LOCK)
            {
                try
                {
                    SenderKeyRecord record = senderKeyStore.loadSenderKey(senderKeyId);

                    if (record.isEmpty())
                    {
                        throw new NoSessionException("No sender key for: " + senderKeyId);
                    }

                    SenderKeyMessage senderKeyMessage = new SenderKeyMessage(senderKeyMessageBytes);
                    SenderKeyState   senderKeyState   = record.getSenderKeyState(senderKeyMessage.getKeyId());

                    senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());

                    SenderMessageKey senderKey = getSenderKey(senderKeyState, senderKeyMessage.getIteration());

                    byte[] plaintext = getPlainText(senderKey.getIv(), senderKey.getCipherKey(), senderKeyMessage.getCipherText());

                    callback.handlePlaintext(plaintext);

                    senderKeyStore.storeSenderKey(senderKeyId, record);

                    return(plaintext);
                }
                catch (InvalidKeyException e)
                {
                    throw new InvalidMessageException(e);
                }
                catch (InvalidKeyIdException e)
                {
                    throw new InvalidMessageException(e);
                }
            }
        }