예제 #1
0
 public void StoreSenderKey(SenderKeyName senderKeyName, SenderKeyRecord record)
 {
     if (this.OnStoreSenderKey != null)
     {
         this.OnStoreSenderKey(senderKeyName, record);
     }
 }
        /**
         * Construct a group session for sending messages.
         *
         * @param senderKeyName The (groupId, senderId, deviceId) tuple.  In this case, 'senderId' should be the caller.
         * @return A SenderKeyDistributionMessage that is individually distributed to each member of the group.
         */
        public SenderKeyDistributionMessage Create(SenderKeyName senderKeyName)
        {
            lock (GroupCipher.Lock)
            {
                try
                {
                    SenderKeyRecord senderKeyRecord = _senderKeyStore.LoadSenderKey(senderKeyName);

                    if (senderKeyRecord.IsEmpty())
                    {
                        senderKeyRecord.SetSenderKeyState(KeyHelper.GenerateSenderKeyId(),
                                                          0,
                                                          KeyHelper.GenerateSenderKey(),
                                                          KeyHelper.GenerateSenderSigningKey());
                        _senderKeyStore.StoreSenderKey(senderKeyName, senderKeyRecord);
                    }

                    SenderKeyState state = senderKeyRecord.GetSenderKeyState();

                    return(new SenderKeyDistributionMessage(state.GetKeyId(),
                                                            state.GetSenderChainKey().GetIteration(),
                                                            state.GetSenderChainKey().GetSeed(),
                                                            state.GetSigningKeyPublic()));
                }
                catch (Exception e) when(e is InvalidKeyIdException || e is InvalidKeyException)
                {
                    throw new Exception(e.Message);
                }
            }
        }
        /**
         * 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);
                }
            }
        }
 /**
  * Construct a group session for receiving messages from senderKeyName.
  *
  * @param senderKeyName The (groupId, senderId, deviceId) tuple associated with the SenderKeyDistributionMessage.
  * @param senderKeyDistributionMessage A received SenderKeyDistributionMessage.
  */
 public void Process(SenderKeyName senderKeyName, SenderKeyDistributionMessage senderKeyDistributionMessage)
 {
     lock (GroupCipher.Lock)
     {
         SenderKeyRecord senderKeyRecord = _senderKeyStore.LoadSenderKey(senderKeyName);
         senderKeyRecord.AddSenderKeyState(senderKeyDistributionMessage.GetId(),
                                           senderKeyDistributionMessage.GetIteration(),
                                           senderKeyDistributionMessage.GetChainKey(),
                                           senderKeyDistributionMessage.GetSignatureKey());
         _senderKeyStore.StoreSenderKey(senderKeyName, senderKeyRecord);
     }
 }
예제 #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="senderKeyName"></param>
        /// <param name="record"></param>
        public void StoreSenderKey(SenderKeyName senderKeyName, SenderKeyRecord record)
        {
            if (SenderKeysObjectsDic.ContainsKey(senderKeyName))
            {
                SenderKeysObjectsDic.Remove(senderKeyName);
            }

            SenderKeysObjectsDic.Add(senderKeyName, new SenderKeysObject()
            {
                SenderKeyKeyName = senderKeyName,
                Record           = record.Serialize()
            });
        }
예제 #7
0
        public SenderKeyRecord LoadSenderKey(SenderKeyName senderKeyName)
        {
            String senderKeyId = senderKeyName.GetSender().GetName() + " : " + senderKeyName.GetGroupId();
            SenderKeysRepository senderKeysRepository = new SenderKeysRepository();
            List <SenderKeys>    senderKeys           = senderKeysRepository.GetSenderKeys(senderKeyId);

            if (senderKeys != null && senderKeys.Count > 0)
            {
                SenderKeys      senderKey       = senderKeys.First();
                SenderKeyRecord senderKeyRecord = new SenderKeyRecord(senderKey.Record);
                return(senderKeyRecord);
            }

            return(new SenderKeyRecord());
        }
예제 #8
0
        public void StoreSenderKey(SenderKeyName senderKeyName, SenderKeyRecord record)
        {
            if (ContainsSenderKey(senderKeyName))
            {
                RemoveSenderKey(senderKeyName);
            }

            String senderKeyId = senderKeyName.GetSender().GetName() + " : " + senderKeyName.GetGroupId();
            SenderKeysRepository senderKeysRepository = new SenderKeysRepository();

            SenderKeys senderKey = new SenderKeys()
            {
                Record      = record.Serialize(),
                SenderKeyId = senderKeyId
            };

            senderKeysRepository.Save(senderKey);
        }
 public void storeSenderKey(SenderKeyName senderKeyName, SenderKeyRecord record)
 {
     store[senderKeyName] = record;
 }