Rearrange decrypt API.
1) Change SessionBuilder to only establish sessions via KeyExchangeMessage and PreKeyBundles. 2) Change SessionCipher to decrypt either WhisperMessage or PreKeyWhisperMessage items, automatically building a session for the latter. 3) Change SessionCipher to tear down new sessions built with PreKeyWhisperMessages if the embedded WhsiperMessage fails to decrypt.pull/1/head
parent
42cf53e487
commit
819982af7b
@ -0,0 +1,7 @@
|
|||||||
|
package org.whispersystems.libaxolotl;
|
||||||
|
|
||||||
|
public class NoSessionException extends Exception {
|
||||||
|
public NoSessionException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
@ -1,41 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2013 Open Whisper Systems
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.whispersystems.textsecure.crypto;
|
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import org.whispersystems.libaxolotl.SessionCipher;
|
|
||||||
import org.whispersystems.libaxolotl.state.SessionStore;
|
|
||||||
import org.whispersystems.textsecure.storage.RecipientDevice;
|
|
||||||
import org.whispersystems.textsecure.storage.TextSecureSessionStore;
|
|
||||||
|
|
||||||
public class SessionCipherFactory {
|
|
||||||
|
|
||||||
public static SessionCipher getInstance(Context context,
|
|
||||||
MasterSecret masterSecret,
|
|
||||||
RecipientDevice recipient)
|
|
||||||
{
|
|
||||||
SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret);
|
|
||||||
|
|
||||||
if (sessionStore.containsSession(recipient.getRecipientId(), recipient.getDeviceId())) {
|
|
||||||
return new SessionCipher(sessionStore, recipient.getRecipientId(), recipient.getDeviceId());
|
|
||||||
} else {
|
|
||||||
throw new AssertionError("Attempt to initialize cipher for non-existing session.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,67 @@
|
|||||||
|
package org.thoughtcrime.securesms.crypto;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.whispersystems.libaxolotl.DuplicateMessageException;
|
||||||
|
import org.whispersystems.libaxolotl.InvalidKeyException;
|
||||||
|
import org.whispersystems.libaxolotl.InvalidKeyIdException;
|
||||||
|
import org.whispersystems.libaxolotl.InvalidMessageException;
|
||||||
|
import org.whispersystems.libaxolotl.LegacyMessageException;
|
||||||
|
import org.whispersystems.libaxolotl.NoSessionException;
|
||||||
|
import org.whispersystems.libaxolotl.SessionCipher;
|
||||||
|
import org.whispersystems.libaxolotl.UntrustedIdentityException;
|
||||||
|
import org.whispersystems.libaxolotl.protocol.CiphertextMessage;
|
||||||
|
import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage;
|
||||||
|
import org.whispersystems.libaxolotl.protocol.WhisperMessage;
|
||||||
|
import org.whispersystems.libaxolotl.state.IdentityKeyStore;
|
||||||
|
import org.whispersystems.libaxolotl.state.PreKeyStore;
|
||||||
|
import org.whispersystems.libaxolotl.state.SessionStore;
|
||||||
|
import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
|
||||||
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
|
import org.whispersystems.textsecure.crypto.TransportDetails;
|
||||||
|
import org.whispersystems.textsecure.storage.RecipientDevice;
|
||||||
|
import org.whispersystems.textsecure.storage.TextSecurePreKeyStore;
|
||||||
|
import org.whispersystems.textsecure.storage.TextSecureSessionStore;
|
||||||
|
|
||||||
|
public class TextSecureCipher {
|
||||||
|
|
||||||
|
private final SessionCipher sessionCipher;
|
||||||
|
private final TransportDetails transportDetails;
|
||||||
|
|
||||||
|
public TextSecureCipher(Context context, MasterSecret masterSecret,
|
||||||
|
RecipientDevice recipient, TransportDetails transportDetails)
|
||||||
|
{
|
||||||
|
SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret);
|
||||||
|
PreKeyStore preKeyStore = new TextSecurePreKeyStore(context, masterSecret);
|
||||||
|
SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context, masterSecret);
|
||||||
|
IdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(context, masterSecret);
|
||||||
|
|
||||||
|
this.transportDetails = transportDetails;
|
||||||
|
this.sessionCipher = new SessionCipher(sessionStore, preKeyStore, signedPreKeyStore, identityKeyStore,
|
||||||
|
recipient.getRecipientId(), recipient.getDeviceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CiphertextMessage encrypt(byte[] unpaddedMessage) {
|
||||||
|
return sessionCipher.encrypt(transportDetails.getPaddedMessageBody(unpaddedMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] decrypt(WhisperMessage message)
|
||||||
|
throws DuplicateMessageException, LegacyMessageException, InvalidMessageException, NoSessionException
|
||||||
|
{
|
||||||
|
byte[] paddedMessage = sessionCipher.decrypt(message);
|
||||||
|
return transportDetails.getStrippedPaddingMessageBody(paddedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] decrypt(PreKeyWhisperMessage message)
|
||||||
|
throws InvalidKeyException, LegacyMessageException, InvalidMessageException,
|
||||||
|
DuplicateMessageException, InvalidKeyIdException, UntrustedIdentityException, NoSessionException
|
||||||
|
{
|
||||||
|
byte[] paddedMessage = sessionCipher.decrypt(message);
|
||||||
|
return transportDetails.getStrippedPaddingMessageBody(paddedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRemoteRegistrationId() {
|
||||||
|
return sessionCipher.getRemoteRegistrationId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue