org.whispersystems.libsignal.InvalidVersionException Java Examples

The following examples show how to use org.whispersystems.libsignal.InvalidVersionException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SignalServiceEnvelope.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Construct an envelope from a serialized SignalServiceEnvelope, encrypted with a signaling key.
 *
 * @param input The serialized and (optionally) encrypted SignalServiceEnvelope.
 * @param signalingKey The signaling key.
 * @throws InvalidVersionException
 * @throws IOException
 */
public SignalServiceEnvelope(byte[] input, String signalingKey, boolean isSignalingKeyEncrypted)
    throws InvalidVersionException, IOException
{
  if (!isSignalingKeyEncrypted) {
    this.envelope = Envelope.parseFrom(input);
  } else {
    if (input.length < VERSION_LENGTH || input[VERSION_OFFSET] != SUPPORTED_VERSION) {
      throw new InvalidVersionException("Unsupported version!");
    }

    SecretKeySpec cipherKey = getCipherKey(signalingKey);
    SecretKeySpec macKey    = getMacKey(signalingKey);

    verifyMac(input, macKey);

    this.envelope = Envelope.parseFrom(getPlaintext(input, cipherKey));
  }
}
 
Example #2
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleUntrustedIdentityMessage(@NonNull SignalServiceProtos.Envelope envelope) {
    ALog.i(TAG, "handleUntrustedIdentityMessage");
    try {
        PrivateChatRepo chatRepo = repository.getChatRepo();
        Address sourceAddress = Address.from(accountContext, envelope.getSource());
        byte[] serialized = envelope.hasLegacyMessage() ? envelope.getLegacyMessage().toByteArray() : envelope.getContent().toByteArray();
        PreKeySignalMessage whisperMessage = new PreKeySignalMessage(serialized);
        String encoded = Base64.encodeBytes(serialized);

        IncomingTextMessage textMessage = new IncomingTextMessage(sourceAddress,
                envelope.getSourceDevice(),
                envelope.getTimestamp(), encoded,
                Optional.absent(), 0);

        IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded, envelope.hasLegacyMessage());

        chatRepo.insertIncomingTextMessage(bundleMessage);
    } catch (InvalidMessageException | InvalidVersionException e) {
        throw new AssertionError(e);
    }
}
 
Example #3
Source File: SignalServiceEnvelope.java    From libsignal-service-java with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Construct an envelope from a serialized SignalServiceEnvelope, encrypted with a signaling key.
 *
 * @param input The serialized and (optionally) encrypted SignalServiceEnvelope.
 * @param signalingKey The signaling key.
 * @throws InvalidVersionException
 * @throws IOException
 */
public SignalServiceEnvelope(byte[] input, String signalingKey, boolean isSignalingKeyEncrypted)
    throws InvalidVersionException, IOException
{
  if (!isSignalingKeyEncrypted) {
    this.envelope = Envelope.parseFrom(input);
  } else {
    if (input.length < VERSION_LENGTH || input[VERSION_OFFSET] != SUPPORTED_VERSION) {
      throw new InvalidVersionException("Unsupported version!");
    }

    SecretKeySpec cipherKey = getCipherKey(signalingKey);
    SecretKeySpec macKey    = getMacKey(signalingKey);

    verifyMac(input, macKey);

    this.envelope = Envelope.parseFrom(getPlaintext(input, cipherKey));
  }
}
 
Example #4
Source File: SmsCipher.java    From Silence with GNU General Public License v3.0 6 votes vote down vote up
public IncomingEncryptedMessage decrypt(Context context, IncomingPreKeyBundleMessage message)
    throws InvalidVersionException, InvalidMessageException, DuplicateMessageException,
           UntrustedIdentityException, LegacyMessageException
{
  try {
    byte[]              decoded       = transportDetails.getDecodedMessage(message.getMessageBody().getBytes());
    PreKeySignalMessage preKeyMessage = new PreKeySignalMessage(decoded);
    SessionCipher       sessionCipher = new SessionCipher(signalProtocolStore, new SignalProtocolAddress(message.getSender(), 1));
    byte[]              padded        = sessionCipher.decrypt(preKeyMessage);
    byte[]              plaintext     = transportDetails.getStrippedPaddingMessageBody(padded);

    return new IncomingEncryptedMessage(message, new String(plaintext));
  } catch (IOException | InvalidKeyException | InvalidKeyIdException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #5
Source File: SmsCipher.java    From Silence with GNU General Public License v3.0 6 votes vote down vote up
public OutgoingKeyExchangeMessage process(Context context, IncomingKeyExchangeMessage message)
    throws UntrustedIdentityException, StaleKeyExchangeException,
           InvalidVersionException, LegacyMessageException, InvalidMessageException
{
  try {
    Recipients            recipients            = RecipientFactory.getRecipientsFromString(context, message.getSender(), false);
    SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(message.getSender(), 1);
    KeyExchangeMessage    exchangeMessage       = new KeyExchangeMessage(transportDetails.getDecodedMessage(message.getMessageBody().getBytes()));
    SessionBuilder        sessionBuilder        = new SessionBuilder(signalProtocolStore, signalProtocolAddress);

    KeyExchangeMessage response        = sessionBuilder.process(exchangeMessage);

    if (response != null) {
      byte[] serializedResponse = transportDetails.getEncodedMessage(response.serialize());
      return new OutgoingKeyExchangeMessage(recipients, new String(serializedResponse), message.getSubscriptionId());
    } else {
      return null;
    }
  } catch (IOException | InvalidKeyException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #6
Source File: SignalServiceMessagePipe.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Similar to {@link #read(long, TimeUnit, MessagePipeCallback)}, except this will return
 * {@link Optional#absent()} when an empty response is hit, which indicates the websocket is
 * empty.
 *
 * Important: The empty response will only be hit once for each instance of {@link SignalServiceMessagePipe}.
 * That means subsequent calls will block until an envelope is available.
 */
public Optional<SignalServiceEnvelope> readOrEmpty(long timeout, TimeUnit unit, MessagePipeCallback callback)
    throws TimeoutException, IOException, InvalidVersionException
{
  if (!credentialsProvider.isPresent()) {
    throw new IllegalArgumentException("You can't read messages if you haven't specified credentials");
  }

  while (true) {
    WebSocketRequestMessage  request            = websocket.readRequest(unit.toMillis(timeout));
    WebSocketResponseMessage response           = createWebSocketResponse(request);
    boolean                  signalKeyEncrypted = isSignalKeyEncrypted(request);

    try {
      if (isSignalServiceEnvelope(request)) {
        SignalServiceEnvelope envelope = new SignalServiceEnvelope(request.getBody().toByteArray(),
                                                                   credentialsProvider.get().getSignalingKey(),
                                                                   signalKeyEncrypted);

        callback.onMessage(envelope);
        return Optional.of(envelope);
      } else if (isSocketEmptyRequest(request)) {
        return Optional.absent();
      }
    } finally {
      websocket.sendResponse(response);
    }
  }
}
 
Example #7
Source File: SignalServiceCipher.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private byte[] decrypt(SignalServiceProtos.Envelope envelope, byte[] ciphertext)
    throws InvalidVersionException, InvalidMessageException, InvalidKeyException,
           DuplicateMessageException, InvalidKeyIdException, UntrustedIdentityException,
           LegacyMessageException, NoSessionException
{
  SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSource(), envelope.getSourceDevice());
  SessionCipher         sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress);

  byte[] paddedMessage;

  if (envelope.getType() == Type.PREKEY_BUNDLE) {
    paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext));
      //纠正remote register id
      SessionRecord sessionRecord = signalProtocolStore.loadSession(sourceAddress);
      if (sessionRecord.getSessionState().getRemoteRegistrationId() == 0) {
          sessionRecord.getSessionState().setRemoteRegistrationId(envelope.getSourceRegistration());
          signalProtocolStore.storeSession(sourceAddress, sessionRecord);
      }

  } else if (envelope.getType() == Type.CIPHERTEXT) {
    paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext));
  } else {
    throw new InvalidMessageException("Unknown type: " + envelope.getType());
  }

  PushTransportDetails transportDetails = new PushTransportDetails(sessionCipher.getSessionVersion());
  return transportDetails.getStrippedPaddingMessageBody(paddedMessage);
}
 
Example #8
Source File: SignalServiceMessagePipe.java    From libsignal-service-java with GNU General Public License v3.0 5 votes vote down vote up
/**
 * A blocking call that reads a message off the pipe (see {@link #read(long, java.util.concurrent.TimeUnit)}
 *
 * Unlike {@link #read(long, java.util.concurrent.TimeUnit)}, this method allows you
 * to specify a callback that will be called before the received message is acknowledged.
 * This allows you to write the received message to durable storage before acknowledging
 * receipt of it to the server.
 *
 * @param timeout The timeout to wait for.
 * @param unit The timeout time unit.
 * @param callback A callback that will be called before the message receipt is
 *                 acknowledged to the server.
 * @return The message read (same as the message sent through the callback).
 * @throws TimeoutException
 * @throws IOException
 * @throws InvalidVersionException
 */
public SignalServiceEnvelope read(long timeout, TimeUnit unit, MessagePipeCallback callback)
    throws TimeoutException, IOException, InvalidVersionException
{
  if (!credentialsProvider.isPresent()) {
    throw new IllegalArgumentException("You can't read messages if you haven't specified credentials");
  }

  while (true) {
    WebSocketRequestMessage  request            = websocket.readRequest(unit.toMillis(timeout));
    WebSocketResponseMessage response           = createWebSocketResponse(request);
    boolean                  signalKeyEncrypted = isSignalKeyEncrypted(request);

    try {
      if (isSignalServiceEnvelope(request)) {
        SignalServiceEnvelope envelope = new SignalServiceEnvelope(request.getBody().toByteArray(),
                                                                   credentialsProvider.get().getSignalingKey(),
                                                                   signalKeyEncrypted);

        callback.onMessage(envelope);
        return envelope;
      }
    } finally {
      websocket.sendResponse(response);
    }
  }
}
 
Example #9
Source File: KeyExchangeMessage.java    From Silence with GNU General Public License v3.0 5 votes vote down vote up
public KeyExchangeMessage(byte[] serialized)
    throws InvalidMessageException, InvalidVersionException, LegacyMessageException
{
  try {
    byte[][] parts        = ByteUtil.split(serialized, 1, serialized.length - 1);
    this.version          = ByteUtil.highBitsToInt(parts[0][0]);
    this.supportedVersion = ByteUtil.lowBitsToInt(parts[0][0]);

    if (this.version < CiphertextMessage.CURRENT_VERSION) {
      throw new LegacyMessageException("Unsupported legacy version: " + this.version);
    }

    if (this.version > CiphertextMessage.CURRENT_VERSION) {
      throw new InvalidVersionException("Unknown version: " + this.version);
    }

    SignalProtos.KeyExchangeMessage message = SignalProtos.KeyExchangeMessage.parseFrom(parts[1]);

    if (!message.hasId()           || !message.hasBaseKey()     ||
        !message.hasRatchetKey()   || !message.hasIdentityKey() ||
        !message.hasBaseKeySignature())
    {
      throw new InvalidMessageException("Some required fields missing!");
    }

    this.sequence         = message.getId() >> 5;
    this.flags            = message.getId() & 0x1f;
    this.serialized       = serialized;
    this.baseKey          = Curve.decodePoint(message.getBaseKey().toByteArray(), 0);
    this.baseKeySignature = message.getBaseKeySignature().toByteArray();
    this.ratchetKey       = Curve.decodePoint(message.getRatchetKey().toByteArray(), 0);
    this.identityKey      = new IdentityKey(message.getIdentityKey().toByteArray(), 0);
  } catch (InvalidKeyException | IOException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #10
Source File: PreKeySignalMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public PreKeySignalMessage(byte[] serialized)
    throws InvalidMessageException, InvalidVersionException
{
  try {
    this.version = ByteUtil.highBitsToInt(serialized[0]);

    if (this.version > CiphertextMessage.CURRENT_VERSION) {
      throw new InvalidVersionException("Unknown version: " + this.version);
    }

    if (this.version < CiphertextMessage.CURRENT_VERSION) {
      throw new LegacyMessageException("Legacy version: " + this.version);
    }

    SignalProtos.PreKeySignalMessage preKeyWhisperMessage
        = SignalProtos.PreKeySignalMessage.parseFrom(ByteString.copyFrom(serialized, 1,
                                                                         serialized.length-1));

    if (!preKeyWhisperMessage.hasSignedPreKeyId()  ||
        !preKeyWhisperMessage.hasBaseKey()         ||
        !preKeyWhisperMessage.hasIdentityKey()     ||
        !preKeyWhisperMessage.hasMessage())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized     = serialized;
    this.registrationId = preKeyWhisperMessage.getRegistrationId();
    this.preKeyId       = preKeyWhisperMessage.hasPreKeyId() ? Optional.of(preKeyWhisperMessage.getPreKeyId()) : Optional.<Integer>absent();
    this.signedPreKeyId = preKeyWhisperMessage.hasSignedPreKeyId() ? preKeyWhisperMessage.getSignedPreKeyId() : -1;
    this.baseKey        = Curve.decodePoint(preKeyWhisperMessage.getBaseKey().toByteArray(), 0);
    this.identityKey    = new IdentityKey(Curve.decodePoint(preKeyWhisperMessage.getIdentityKey().toByteArray(), 0));
    this.message        = new SignalMessage(preKeyWhisperMessage.getMessage().toByteArray());
  } catch (InvalidProtocolBufferException | InvalidKeyException | LegacyMessageException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #11
Source File: SignalServiceMessagePipe.java    From mollyim-android with GNU General Public License v3.0 3 votes vote down vote up
/**
 * A blocking call that reads a message off the pipe (see {@link #read(long, java.util.concurrent.TimeUnit)}
 *
 * Unlike {@link #read(long, java.util.concurrent.TimeUnit)}, this method allows you
 * to specify a callback that will be called before the received message is acknowledged.
 * This allows you to write the received message to durable storage before acknowledging
 * receipt of it to the server.
 *
 * @param timeout The timeout to wait for.
 * @param unit The timeout time unit.
 * @param callback A callback that will be called before the message receipt is
 *                 acknowledged to the server.
 * @return The message read (same as the message sent through the callback).
 * @throws TimeoutException
 * @throws IOException
 * @throws InvalidVersionException
 */
public SignalServiceEnvelope read(long timeout, TimeUnit unit, MessagePipeCallback callback)
    throws TimeoutException, IOException, InvalidVersionException
{
  while (true) {
    Optional<SignalServiceEnvelope> envelope = readOrEmpty(timeout, unit, callback);

    if (envelope.isPresent()) {
      return envelope.get();
    }
  }
}
 
Example #12
Source File: SignalServiceEnvelope.java    From mollyim-android with GNU General Public License v3.0 2 votes vote down vote up
/**
 * Construct an envelope from a serialized, Base64 encoded SignalServiceEnvelope, encrypted
 * with a signaling key.
 *
 * @param message The serialized SignalServiceEnvelope, base64 encoded and encrypted.
 * @param signalingKey The signaling key.
 * @throws IOException
 * @throws InvalidVersionException
 */
public SignalServiceEnvelope(String message, String signalingKey, boolean isSignalingKeyEncrypted)
    throws IOException, InvalidVersionException
{
  this(Base64.decode(message), signalingKey, isSignalingKeyEncrypted);
}
 
Example #13
Source File: SignalServiceMessagePipe.java    From mollyim-android with GNU General Public License v3.0 2 votes vote down vote up
/**
 * A blocking call that reads a message off the pipe.  When this
 * call returns, the message has been acknowledged and will not
 * be retransmitted.
 *
 * @param timeout The timeout to wait for.
 * @param unit The timeout time unit.
 * @return A new message.
 *
 * @throws InvalidVersionException
 * @throws IOException
 * @throws TimeoutException
 */
public SignalServiceEnvelope read(long timeout, TimeUnit unit)
    throws InvalidVersionException, IOException, TimeoutException
{
  return read(timeout, unit, new NullMessagePipeCallback());
}
 
Example #14
Source File: SignalServiceEnvelope.java    From libsignal-service-java with GNU General Public License v3.0 2 votes vote down vote up
/**
 * Construct an envelope from a serialized, Base64 encoded SignalServiceEnvelope, encrypted
 * with a signaling key.
 *
 * @param message The serialized SignalServiceEnvelope, base64 encoded and encrypted.
 * @param signalingKey The signaling key.
 * @throws IOException
 * @throws InvalidVersionException
 */
public SignalServiceEnvelope(String message, String signalingKey, boolean isSignalingKeyEncrypted)
    throws IOException, InvalidVersionException
{
  this(Base64.decode(message), signalingKey, isSignalingKeyEncrypted);
}
 
Example #15
Source File: SignalServiceMessagePipe.java    From libsignal-service-java with GNU General Public License v3.0 2 votes vote down vote up
/**
 * A blocking call that reads a message off the pipe.  When this
 * call returns, the message has been acknowledged and will not
 * be retransmitted.
 *
 * @param timeout The timeout to wait for.
 * @param unit The timeout time unit.
 * @return A new message.
 *
 * @throws InvalidVersionException
 * @throws IOException
 * @throws TimeoutException
 */
public SignalServiceEnvelope read(long timeout, TimeUnit unit)
    throws InvalidVersionException, IOException, TimeoutException
{
  return read(timeout, unit, new NullMessagePipeCallback());
}