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