Java Code Examples for org.whispersystems.libsignal.util.ByteUtil#split()

The following examples show how to use org.whispersystems.libsignal.util.ByteUtil#split() . 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: AESCipher.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
static AESEncryptedResult encrypt(byte[] key, byte[] aad, byte[] requestData) {
  try {
    byte[] iv     = Util.getSecretBytes(12);
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(TAG_LENGTH_BITS, iv));
    cipher.updateAAD(aad);

    byte[]   cipherText = cipher.doFinal(requestData);
    byte[][] parts      = ByteUtil.split(cipherText, cipherText.length - TAG_LENGTH_BYTES, TAG_LENGTH_BYTES);

    byte[] mac  = parts[1];
    byte[] data = parts[0];

    return new AESEncryptedResult(iv, data, mac, aad);
  } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
    throw new AssertionError(e);
  }
}
 
Example 2
Source File: ContactDiscoveryCipher.java    From libsignal-service-java with GNU General Public License v3.0 6 votes vote down vote up
public DiscoveryRequest createDiscoveryRequest(List<String> addressBook, RemoteAttestation remoteAttestation) {
  try {
    ByteArrayOutputStream requestDataStream = new ByteArrayOutputStream();

    for (String address : addressBook) {
      requestDataStream.write(ByteUtil.longToByteArray(Long.parseLong(address)));
    }

    byte[]         requestData = requestDataStream.toByteArray();
    byte[]         nonce       = Util.getSecretBytes(12);
    Cipher         cipher      = Cipher.getInstance("AES/GCM/NoPadding");

    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(remoteAttestation.getKeys().getClientKey(), "AES"), new GCMParameterSpec(TAG_LENGTH_BITS, nonce));
    cipher.updateAAD(remoteAttestation.getRequestId());

    byte[]   cipherText = cipher.doFinal(requestData);
    byte[][] parts      = ByteUtil.split(cipherText, cipherText.length - TAG_LENGTH_BYTES, TAG_LENGTH_BYTES);

    return new DiscoveryRequest(addressBook.size(), remoteAttestation.getRequestId(), nonce, parts[0], parts[1]);
  } catch (IOException | NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
    throw new AssertionError(e);
  }
}
 
Example 3
Source File: FullBackupExporter.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private BackupFrameOutputStream(@NonNull File output, @NonNull String passphrase) throws IOException {
  try {
    byte[]   salt    = Util.getSecretBytes(32);
    byte[]   key     = getBackupKey(passphrase, salt);
    byte[]   derived = new HKDFv3().deriveSecrets(key, "Backup Export".getBytes(), 64);
    byte[][] split   = ByteUtil.split(derived, 32, 32);

    this.cipherKey = split[0];
    this.macKey    = split[1];

    this.cipher       = Cipher.getInstance("AES/CTR/NoPadding");
    this.mac          = Mac.getInstance("HmacSHA256");
    this.outputStream = new FileOutputStream(output);
    this.iv           = Util.getSecretBytes(16);
    this.counter      = Conversions.byteArrayToInt(iv);

    mac.init(new SecretKeySpec(macKey, "HmacSHA256"));

    byte[] header = BackupProtos.BackupFrame.newBuilder().setHeader(BackupProtos.Header.newBuilder()
                                                                                       .setIv(ByteString.copyFrom(iv))
                                                                                       .setSalt(ByteString.copyFrom(salt)))
                                            .build().toByteArray();

    outputStream.write(Conversions.intToByteArray(header.length));
    outputStream.write(header);
  } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example 4
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 5
Source File: SenderMessageKey.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public SenderMessageKey(int iteration, byte[] seed) {
  byte[] derivative = new HKDFv3().deriveSecrets(seed, "WhisperGroup".getBytes(), 48);
  byte[][] parts    = ByteUtil.split(derivative, 16, 32);

  this.iteration = iteration;
  this.seed      = seed;
  this.iv        = parts[0];
  this.cipherKey = parts[1];
}
 
Example 6
Source File: SenderKeyDistributionMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public SenderKeyDistributionMessage(byte[] serialized) throws LegacyMessageException, InvalidMessageException {
  try {
    byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1);
    byte     version      = messageParts[0][0];
    byte[]   message      = messageParts[1];

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

    if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
      throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
    }

    SignalProtos.SenderKeyDistributionMessage distributionMessage = SignalProtos.SenderKeyDistributionMessage.parseFrom(message);

    if (!distributionMessage.hasId()        ||
        !distributionMessage.hasIteration() ||
        !distributionMessage.hasChainKey()  ||
        !distributionMessage.hasSigningKey())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized   = serialized;
    this.id           = distributionMessage.getId();
    this.iteration    = distributionMessage.getIteration();
    this.chainKey     = distributionMessage.getChainKey().toByteArray();
    this.signatureKey = Curve.decodePoint(distributionMessage.getSigningKey().toByteArray(), 0);
  } catch (InvalidProtocolBufferException | InvalidKeyException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example 7
Source File: SenderKeyMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public SenderKeyMessage(byte[] serialized) throws InvalidMessageException, LegacyMessageException {
  try {
    byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1 - SIGNATURE_LENGTH, SIGNATURE_LENGTH);
    byte     version      = messageParts[0][0];
    byte[]   message      = messageParts[1];
    byte[]   signature    = messageParts[2];

    if (ByteUtil.highBitsToInt(version) < 3) {
      throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
    }

    if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
      throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
    }

    SignalProtos.SenderKeyMessage senderKeyMessage = SignalProtos.SenderKeyMessage.parseFrom(message);

    if (!senderKeyMessage.hasId() ||
        !senderKeyMessage.hasIteration() ||
        !senderKeyMessage.hasCiphertext())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized     = serialized;
    this.messageVersion = ByteUtil.highBitsToInt(version);
    this.keyId          = senderKeyMessage.getId();
    this.iteration      = senderKeyMessage.getIteration();
    this.ciphertext     = senderKeyMessage.getCiphertext().toByteArray();
  } catch (InvalidProtocolBufferException | ParseException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example 8
Source File: SenderKeyMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public void verifySignature(ECPublicKey signatureKey)
    throws InvalidMessageException
{
  try {
    byte[][] parts    = ByteUtil.split(serialized, serialized.length - SIGNATURE_LENGTH, SIGNATURE_LENGTH);

    if (!Curve.verifySignature(signatureKey, parts[0], parts[1])) {
      throw new InvalidMessageException("Invalid signature!");
    }

  } catch (InvalidKeyException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example 9
Source File: SignalMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public SignalMessage(byte[] serialized) throws InvalidMessageException, LegacyMessageException {
  try {
    byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1 - MAC_LENGTH, MAC_LENGTH);
    byte     version      = messageParts[0][0];
    byte[]   message      = messageParts[1];
    byte[]   mac          = messageParts[2];

    if (ByteUtil.highBitsToInt(version) < CURRENT_VERSION) {
      throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
    }

    if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
      throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
    }

    SignalProtos.SignalMessage whisperMessage = SignalProtos.SignalMessage.parseFrom(message);

    if (!whisperMessage.hasCiphertext() ||
        !whisperMessage.hasCounter() ||
        !whisperMessage.hasRatchetKey())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized       = serialized;
    this.senderRatchetKey = Curve.decodePoint(whisperMessage.getRatchetKey().toByteArray(), 0);
    this.messageVersion   = ByteUtil.highBitsToInt(version);
    this.counter          = whisperMessage.getCounter();
    this.previousCounter  = whisperMessage.getPreviousCounter();
    this.ciphertext       = whisperMessage.getCiphertext().toByteArray();
  } catch (InvalidProtocolBufferException | InvalidKeyException | ParseException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example 10
Source File: SignalMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public void verifyMac(IdentityKey senderIdentityKey, IdentityKey receiverIdentityKey, SecretKeySpec macKey)
    throws InvalidMessageException
{
  byte[][] parts    = ByteUtil.split(serialized, serialized.length - MAC_LENGTH, MAC_LENGTH);
  byte[]   ourMac   = getMac(senderIdentityKey, receiverIdentityKey, macKey, parts[0]);
  byte[]   theirMac = parts[1];

  if (!MessageDigest.isEqual(ourMac, theirMac)) {
    throw new InvalidMessageException("Bad Mac!");
  }
}
 
Example 11
Source File: DerivedMessageSecrets.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public DerivedMessageSecrets(byte[] okm) {
  try {
    byte[][] keys = ByteUtil.split(okm, CIPHER_KEY_LENGTH, MAC_KEY_LENGTH, IV_LENGTH);

    this.cipherKey = new SecretKeySpec(keys[0], "AES");
    this.macKey    = new SecretKeySpec(keys[1], "HmacSHA256");
    this.iv        = new IvParameterSpec(keys[2]);
  } catch (ParseException e) {
    throw new AssertionError(e);
  }
}
 
Example 12
Source File: RatchetingSession.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
private static DerivedKeys calculateDerivedKeys(byte[] masterSecret) {
  HKDF     kdf                = new HKDFv3();
  byte[]   derivedSecretBytes = kdf.deriveSecrets(masterSecret, "WhisperText".getBytes(), 64);
  byte[][] derivedSecrets     = ByteUtil.split(derivedSecretBytes, 32, 32);

  return new DerivedKeys(new RootKey(kdf, derivedSecrets[0]),
                         new ChainKey(kdf, derivedSecrets[1], 0));
}
 
Example 13
Source File: FullBackupImporter.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
private BackupRecordInputStream(@NonNull File file, @NonNull String passphrase) throws IOException {
  try {
    this.in     = new FileInputStream(file);

    byte[] headerLengthBytes = new byte[4];
    Util.readFully(in, headerLengthBytes);

    int headerLength = Conversions.byteArrayToInt(headerLengthBytes);
    byte[] headerFrame = new byte[headerLength];
    Util.readFully(in, headerFrame);

    BackupFrame frame = BackupFrame.parseFrom(headerFrame);

    if (!frame.hasHeader()) {
      throw new IOException("Backup stream does not start with header!");
    }

    BackupProtos.Header header = frame.getHeader();

    this.iv = header.getIv().toByteArray();

    if (iv.length != 16) {
      throw new IOException("Invalid IV length!");
    }

    byte[]   key     = getBackupKey(passphrase, header.hasSalt() ? header.getSalt().toByteArray() : null);
    byte[]   derived = new HKDFv3().deriveSecrets(key, "Backup Export".getBytes(), 64);
    byte[][] split   = ByteUtil.split(derived, 32, 32);

    this.cipherKey = split[0];
    this.macKey    = split[1];

    this.cipher = Cipher.getInstance("AES/CTR/NoPadding");
    this.mac    = Mac.getInstance("HmacSHA256");
    this.mac.init(new SecretKeySpec(macKey, "HmacSHA256"));

    this.counter = Conversions.byteArrayToInt(iv);
  } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example 14
Source File: DerivedRootSecrets.java    From libsignal-protocol-java with GNU General Public License v3.0 4 votes vote down vote up
public DerivedRootSecrets(byte[] okm) {
  byte[][] keys = ByteUtil.split(okm, 32, 32);
  this.rootKey  = keys[0];
  this.chainKey = keys[1];
}