org.whispersystems.libsignal.ecc.Curve Java Examples

The following examples show how to use org.whispersystems.libsignal.ecc.Curve. 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: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
private PreKeyBundle createBobPreKeyBundle(SignalProtocolStore bobStore) throws InvalidKeyException {
  ECKeyPair bobUnsignedPreKey   = Curve.generateKeyPair();
  int       bobUnsignedPreKeyId = new Random().nextInt(Medium.MAX_VALUE);
  byte[]    bobSignature        = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
                                                           bobSignedPreKey.getPublicKey().serialize());

  PreKeyBundle bobPreKeyBundle = new PreKeyBundle(1, 1,
                                                  bobUnsignedPreKeyId, bobUnsignedPreKey.getPublicKey(),
                                                  bobSignedPreKeyId, bobSignedPreKey.getPublicKey(),
                                                  bobSignature, bobStore.getIdentityKeyPair().getPublicKey());

  bobStore.storeSignedPreKey(bobSignedPreKeyId, new SignedPreKeyRecord(bobSignedPreKeyId, System.currentTimeMillis(), bobSignedPreKey, bobSignature));
  bobStore.storePreKey(bobUnsignedPreKeyId, new PreKeyRecord(bobUnsignedPreKeyId, bobUnsignedPreKey));

  return bobPreKeyBundle;
}
 
Example #2
Source File: SignedPreKeyDatabase.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public @Nullable SignedPreKeyRecord getSignedPreKey(int keyId) {
  SQLiteDatabase database = databaseHelper.getReadableDatabase();

  try (Cursor cursor = database.query(TABLE_NAME, null, KEY_ID + " = ?",
                                      new String[] {String.valueOf(keyId)},
                                      null, null, null))
  {
    if (cursor != null && cursor.moveToFirst()) {
      try {
        ECPublicKey  publicKey  = Curve.decodePoint(Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(PUBLIC_KEY))), 0);
        ECPrivateKey privateKey = Curve.decodePrivatePoint(Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(PRIVATE_KEY))));
        byte[]       signature  = Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(SIGNATURE)));
        long         timestamp  = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP));

        return new SignedPreKeyRecord(keyId, timestamp, new ECKeyPair(publicKey, privateKey), signature);
      } catch (InvalidKeyException | IOException e) {
        Log.w(TAG, e);
      }
    }
  }

  return null;
}
 
Example #3
Source File: OneTimePreKeyDatabase.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public @Nullable PreKeyRecord getPreKey(int keyId) {
  SQLiteDatabase database = databaseHelper.getReadableDatabase();

  try (Cursor cursor = database.query(TABLE_NAME, null, KEY_ID + " = ?",
                                      new String[] {String.valueOf(keyId)},
                                      null, null, null))
  {
    if (cursor != null && cursor.moveToFirst()) {
      try {
        ECPublicKey  publicKey  = Curve.decodePoint(Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(PUBLIC_KEY))), 0);
        ECPrivateKey privateKey = Curve.decodePrivatePoint(Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(PRIVATE_KEY))));

        return new PreKeyRecord(keyId, new ECKeyPair(publicKey, privateKey));
      } catch (InvalidKeyException | IOException e) {
        Log.w(TAG, e);
      }
    }
  }

  return null;
}
 
Example #4
Source File: NumericFingerprintGeneratorTest.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
public void testMismatchingIdentifiers() throws FingerprintVersionMismatchException, FingerprintParsingException {
  ECKeyPair aliceKeyPair = Curve.generateKeyPair();
  ECKeyPair bobKeyPair   = Curve.generateKeyPair();

  IdentityKey aliceIdentityKey = new IdentityKey(aliceKeyPair.getPublicKey());
  IdentityKey bobIdentityKey   = new IdentityKey(bobKeyPair.getPublicKey());

  NumericFingerprintGenerator generator        = new NumericFingerprintGenerator(1024);
  Fingerprint                 aliceFingerprint = generator.createFor(VERSION_1,
                                                                     "+141512222222".getBytes(), aliceIdentityKey,
                                                                     "+14153333333".getBytes(), bobIdentityKey);

  Fingerprint bobFingerprint = generator.createFor(VERSION_1,
                                                   "+14153333333".getBytes(), bobIdentityKey,
                                                   "+14152222222".getBytes(), aliceIdentityKey);

  assertFalse(aliceFingerprint.getDisplayableFingerprint().getDisplayText().equals(
              bobFingerprint.getDisplayableFingerprint().getDisplayText()));

  assertFalse(aliceFingerprint.getScannableFingerprint().compareTo(bobFingerprint.getScannableFingerprint().getSerialized()));
  assertFalse(bobFingerprint.getScannableFingerprint().compareTo(aliceFingerprint.getScannableFingerprint().getSerialized()));
}
 
Example #5
Source File: SignedPreKeyDatabase.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public @NonNull List<SignedPreKeyRecord> getAllSignedPreKeys() {
  SQLiteDatabase           database = databaseHelper.getReadableDatabase();
  List<SignedPreKeyRecord> results  = new LinkedList<>();

  try (Cursor cursor = database.query(TABLE_NAME, null, null, null, null, null, null)) {
    while (cursor != null && cursor.moveToNext()) {
      try {
        int          keyId      = cursor.getInt(cursor.getColumnIndexOrThrow(KEY_ID));
        ECPublicKey  publicKey  = Curve.decodePoint(Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(PUBLIC_KEY))), 0);
        ECPrivateKey privateKey = Curve.decodePrivatePoint(Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(PRIVATE_KEY))));
        byte[]       signature  = Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(SIGNATURE)));
        long         timestamp  = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP));

        results.add(new SignedPreKeyRecord(keyId, timestamp, new ECKeyPair(publicKey, privateKey), signature));
      } catch (InvalidKeyException | IOException e) {
        Log.w(TAG, e);
      }
    }
  }

  return results;
}
 
Example #6
Source File: AsymmetricMasterCipher.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public byte[] encryptBytes(byte[] body) {
  try {
    ECPublicKey  theirPublic        = asymmetricMasterSecret.getDjbPublicKey();
    ECKeyPair    ourKeyPair         = Curve.generateKeyPair();
    byte[]       secret             = Curve.calculateAgreement(theirPublic, ourKeyPair.getPrivateKey());
    MasterCipher masterCipher       = getMasterCipherForSecret(secret);
    byte[]       encryptedBodyBytes = masterCipher.encrypt(body);

    PublicKey    ourPublicKey       = new PublicKey(31337, ourKeyPair.getPublicKey());
    byte[]       publicKeyBytes     = ourPublicKey.serialize();

    return Util.combine(publicKeyBytes, encryptedBodyBytes);
  } catch (InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example #7
Source File: PreKeyUtil.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public synchronized static SignedPreKeyRecord generateSignedPreKey(Context context, IdentityKeyPair identityKeyPair, boolean active) {
  try {
    SignedPreKeyStore  signedPreKeyStore = new TextSecurePreKeyStore(context);
    int                signedPreKeyId    = TextSecurePreferences.getNextSignedPreKeyId(context);
    ECKeyPair          keyPair           = Curve.generateKeyPair();
    byte[]             signature         = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
    SignedPreKeyRecord record            = new SignedPreKeyRecord(signedPreKeyId, System.currentTimeMillis(), keyPair, signature);

    signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record);
    TextSecurePreferences.setNextSignedPreKeyId(context, (signedPreKeyId + 1) % Medium.MAX_VALUE);

    if (active) {
      TextSecurePreferences.setActiveSignedPreKeyId(context, signedPreKeyId);
    }

    return record;
  } catch (InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example #8
Source File: PreKeyUtil.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public synchronized static List<PreKeyRecord> generatePreKeys(Context context) {
  PreKeyStore        preKeyStore    = new TextSecurePreKeyStore(context);
  List<PreKeyRecord> records        = new LinkedList<>();
  int                preKeyIdOffset = TextSecurePreferences.getNextPreKeyId(context);

  for (int i=0;i<BATCH_SIZE;i++) {
    int          preKeyId = (preKeyIdOffset + i) % Medium.MAX_VALUE;
    ECKeyPair    keyPair  = Curve.generateKeyPair();
    PreKeyRecord record   = new PreKeyRecord(preKeyId, keyPair);

    preKeyStore.storePreKey(preKeyId, record);
    records.add(record);
  }

  TextSecurePreferences.setNextPreKeyId(context, (preKeyIdOffset + BATCH_SIZE + 1) % Medium.MAX_VALUE);

  return records;
}
 
Example #9
Source File: ProvisioningCipher.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public byte[] encrypt(ProvisionMessage message) throws InvalidKeyException {
  ECKeyPair ourKeyPair    = Curve.generateKeyPair();
  byte[]    sharedSecret  = Curve.calculateAgreement(theirPublicKey, ourKeyPair.getPrivateKey());
  byte[]    derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, "TextSecure Provisioning Message".getBytes(), 64);
  byte[][]  parts         = Util.split(derivedSecret, 32, 32);

  byte[] version    = {0x01};
  byte[] ciphertext = getCiphertext(parts[0], message.toByteArray());
  byte[] mac        = getMac(parts[1], Util.join(version, ciphertext));
  byte[] body       = Util.join(version, ciphertext, mac);

  return ProvisionEnvelope.newBuilder()
                          .setPublicKey(ByteString.copyFrom(ourKeyPair.getPublicKey().serialize()))
                          .setBody(ByteString.copyFrom(body))
                          .build()
                          .toByteArray();
}
 
Example #10
Source File: NumericFingerprintGeneratorTest.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
public void testMatchingFingerprints() throws FingerprintVersionMismatchException, FingerprintIdentifierMismatchException, FingerprintParsingException {
  ECKeyPair aliceKeyPair = Curve.generateKeyPair();
  ECKeyPair bobKeyPair   = Curve.generateKeyPair();

  IdentityKey aliceIdentityKey = new IdentityKey(aliceKeyPair.getPublicKey());
  IdentityKey bobIdentityKey   = new IdentityKey(bobKeyPair.getPublicKey());

  NumericFingerprintGenerator generator        = new NumericFingerprintGenerator(1024);
  Fingerprint                 aliceFingerprint = generator.createFor(VERSION_1,
                                                                     "+14152222222".getBytes(), aliceIdentityKey,
                                                                     "+14153333333".getBytes(), bobIdentityKey);

  Fingerprint bobFingerprint = generator.createFor(VERSION_1,
                                                   "+14153333333".getBytes(), bobIdentityKey,
                                                   "+14152222222".getBytes(), aliceIdentityKey);

  assertEquals(aliceFingerprint.getDisplayableFingerprint().getDisplayText(),
               bobFingerprint.getDisplayableFingerprint().getDisplayText());

  assertTrue(aliceFingerprint.getScannableFingerprint().compareTo(bobFingerprint.getScannableFingerprint().getSerialized()));
  assertTrue(bobFingerprint.getScannableFingerprint().compareTo(aliceFingerprint.getScannableFingerprint().getSerialized()));

  assertEquals(aliceFingerprint.getDisplayableFingerprint().getDisplayText().length(), 60);
}
 
Example #11
Source File: MasterSecretUtil.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public static AsymmetricMasterSecret getAsymmetricMasterSecret(@NonNull AccountContext accountContext,
                                                               @Nullable MasterSecret masterSecret) {
    try {
        byte[] djbPublicBytes = retrieve(accountContext, ASYMMETRIC_LOCAL_PUBLIC_DJB);
        byte[] djbPrivateBytes = retrieve(accountContext, ASYMMETRIC_LOCAL_PRIVATE_DJB);

        ECPublicKey djbPublicKey = null;
        ECPrivateKey djbPrivateKey = null;

        if (djbPublicBytes != null) {
            djbPublicKey = Curve.decodePoint(djbPublicBytes, 0);
        }

        if (masterSecret != null) {
            MasterCipher masterCipher = new MasterCipher(masterSecret);

            if (djbPrivateBytes != null) {
                djbPrivateKey = masterCipher.decryptKey(djbPrivateBytes);
            }
        }

        return new AsymmetricMasterSecret(djbPublicKey, djbPrivateKey);
    } catch (InvalidKeyException | IOException ike) {
        throw new AssertionError(ike);
    }
}
 
Example #12
Source File: PreKeyUtil.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public static List<PreKeyRecord> generatePreKeys(Context context, AccountContext accountContext) {
    PreKeyStore preKeyStore = new TextSecurePreKeyStore(context, accountContext);
    List<PreKeyRecord> records = new LinkedList<>();
    int preKeyIdOffset = getNextPreKeyId(context, accountContext);

    for (int i = 0; i < BATCH_SIZE; i++) {
        int preKeyId = (preKeyIdOffset + i) % Medium.MAX_VALUE;
        ECKeyPair keyPair = Curve.generateKeyPair();
        PreKeyRecord record = new PreKeyRecord(preKeyId, keyPair);

        preKeyStore.storePreKey(preKeyId, record);
        records.add(record);
    }

    setNextPreKeyId(context, accountContext,(preKeyIdOffset + BATCH_SIZE + 1) % Medium.MAX_VALUE);
    return records;
}
 
Example #13
Source File: PreKeyUtil.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public static SignedPreKeyRecord generateSignedPreKey(Context context, AccountContext accountContext, IdentityKeyPair identityKeyPair, boolean active) {
    try {
        SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context, accountContext);
        int signedPreKeyId = getNextSignedPreKeyId(context, accountContext);
        ECKeyPair keyPair = Curve.generateKeyPair();
        byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
        SignedPreKeyRecord record = new SignedPreKeyRecord(signedPreKeyId, System.currentTimeMillis(), keyPair, signature);

        signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record);
        setNextSignedPreKeyId(context, accountContext,(signedPreKeyId + 1) % Medium.MAX_VALUE);

        if (active) {
            setActiveSignedPreKeyId(context, accountContext, signedPreKeyId);
        }

        return record;
    } catch (InvalidKeyException e) {
        throw new AssertionError(e);
    }
}
 
Example #14
Source File: ProvisioningCipher.java    From libsignal-service-java with GNU General Public License v3.0 6 votes vote down vote up
public byte[] encrypt(ProvisionMessage message) throws InvalidKeyException {
  ECKeyPair ourKeyPair    = Curve.generateKeyPair();
  byte[]    sharedSecret  = Curve.calculateAgreement(theirPublicKey, ourKeyPair.getPrivateKey());
  byte[]    derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, "TextSecure Provisioning Message".getBytes(), 64);
  byte[][]  parts         = Util.split(derivedSecret, 32, 32);

  byte[] version    = {0x01};
  byte[] ciphertext = getCiphertext(parts[0], message.toByteArray());
  byte[] mac        = getMac(parts[1], Util.join(version, ciphertext));
  byte[] body       = Util.join(version, ciphertext, mac);

  return ProvisionEnvelope.newBuilder()
                          .setPublicKey(ByteString.copyFrom(ourKeyPair.getPublicKey().serialize()))
                          .setBody(ByteString.copyFrom(body))
                          .build()
                          .toByteArray();
}
 
Example #15
Source File: ProvisioningCipher.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public byte[] encrypt(ProvisionMessage message) throws InvalidKeyException {
  ECKeyPair ourKeyPair    = Curve.generateKeyPair();
  byte[]    sharedSecret  = Curve.calculateAgreement(theirPublicKey, ourKeyPair.getPrivateKey());
  byte[]    derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, "TextSecure Provisioning Message".getBytes(), 64);
  byte[][]  parts         = Util.split(derivedSecret, 32, 32);

  byte[] version    = {0x01};
  byte[] ciphertext = getCiphertext(parts[0], message.toByteArray());
  byte[] mac        = getMac(parts[1], Util.join(version, ciphertext));
  byte[] body       = Util.join(version, ciphertext, mac);

  return ProvisionEnvelope.newBuilder()
                          .setPublicKey(ByteString.copyFrom(ourKeyPair.getPublicKey().serialize()))
                          .setBody(ByteString.copyFrom(body))
                          .build()
                          .toByteArray();
}
 
Example #16
Source File: SessionCipher.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
private ChainKey getOrCreateChainKey(SessionState sessionState, ECPublicKey theirEphemeral)
    throws InvalidMessageException
{
  try {
    if (sessionState.hasReceiverChain(theirEphemeral)) {
      return sessionState.getReceiverChainKey(theirEphemeral);
    } else {
      RootKey                 rootKey         = sessionState.getRootKey();
      ECKeyPair               ourEphemeral    = sessionState.getSenderRatchetKeyPair();
      Pair<RootKey, ChainKey> receiverChain   = rootKey.createChain(theirEphemeral, ourEphemeral);
      ECKeyPair               ourNewEphemeral = Curve.generateKeyPair();
      Pair<RootKey, ChainKey> senderChain     = receiverChain.first().createChain(theirEphemeral, ourNewEphemeral);

      sessionState.setRootKey(senderChain.first());
      sessionState.addReceiverChain(theirEphemeral, receiverChain.second());
      sessionState.setPreviousCounter(Math.max(sessionState.getSenderChainKey().getIndex()-1, 0));
      sessionState.setSenderChain(ourNewEphemeral, senderChain.second());

      return receiverChain.second();
    }
  } catch (InvalidKeyException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #17
Source File: SessionState.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
public UnacknowledgedPreKeyMessageItems getUnacknowledgedPreKeyMessageItems() {
  try {
    Optional<Integer> preKeyId;

    if (sessionStructure.getPendingPreKey().hasPreKeyId()) {
      preKeyId = Optional.of(sessionStructure.getPendingPreKey().getPreKeyId());
    } else {
      preKeyId = Optional.absent();
    }

    return
        new UnacknowledgedPreKeyMessageItems(preKeyId,
                                             sessionStructure.getPendingPreKey().getSignedPreKeyId(),
                                             Curve.decodePoint(sessionStructure.getPendingPreKey()
                                                                               .getBaseKey()
                                                                               .toByteArray(), 0));
  } catch (InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example #18
Source File: SessionState.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
private Pair<Chain,Integer> getReceiverChain(ECPublicKey senderEphemeral) {
  List<Chain> receiverChains = sessionStructure.getReceiverChainsList();
  int         index          = 0;

  for (Chain receiverChain : receiverChains) {
    try {
      ECPublicKey chainSenderRatchetKey = Curve.decodePoint(receiverChain.getSenderRatchetKey().toByteArray(), 0);

      if (chainSenderRatchetKey.equals(senderEphemeral)) {
        return new Pair<>(receiverChain,index);
      }
    } catch (InvalidKeyException e) {
      Log.w("SessionRecordV2", e);
    }

    index++;
  }

  return null;
}
 
Example #19
Source File: SessionBuilderTest.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
public void testBasicPreKeyV2()
    throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException, NoSessionException {
  SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

  SignalProtocolStore bobStore      = new TestInMemorySignalProtocolStore();
  ECKeyPair    bobPreKeyPair = Curve.generateKeyPair();
  PreKeyBundle bobPreKey     = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
                                                31337, bobPreKeyPair.getPublicKey(),
                                                0, null, null,
                                                bobStore.getIdentityKeyPair().getPublicKey());

  try {
    aliceSessionBuilder.process(bobPreKey);
    throw new AssertionError("Should fail with missing unsigned prekey!");
  } catch (InvalidKeyException e) {
    // Good!
    return;
  }
}
 
Example #20
Source File: DeviceConsistencyMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
public DeviceConsistencyMessage(DeviceConsistencyCommitment commitment, IdentityKeyPair identityKeyPair) {
  try {
    byte[] signatureBytes = Curve.calculateVrfSignature(identityKeyPair.getPrivateKey(), commitment.toByteArray());
    byte[] vrfOutputBytes = Curve.verifyVrfSignature(identityKeyPair.getPublicKey().getPublicKey(), commitment.toByteArray(), signatureBytes);

    this.generation = commitment.getGeneration();
    this.signature  = new DeviceConsistencySignature(signatureBytes, vrfOutputBytes);
    this.serialized = SignalProtos.DeviceConsistencyCodeMessage.newBuilder()
                                                                .setGeneration(commitment.getGeneration())
                                                                .setSignature(ByteString.copyFrom(signature.getSignature()))
                                                                .build()
                                                                .toByteArray();
  } catch (InvalidKeyException | VrfSignatureVerificationFailedException e) {
    throw new AssertionError(e);
  }
}
 
Example #21
Source File: AsymmetricMasterCipher.java    From Silence with GNU General Public License v3.0 6 votes vote down vote up
public String encryptBody(String body) {
  try {
    ECPublicKey  theirPublic        = asymmetricMasterSecret.getDjbPublicKey();
    ECKeyPair    ourKeyPair         = Curve.generateKeyPair();
    byte[]       secret             = Curve.calculateAgreement(theirPublic, ourKeyPair.getPrivateKey());
    MasterCipher masterCipher       = getMasterCipherForSecret(secret);
    byte[]       encryptedBodyBytes = masterCipher.encryptBytes(body.getBytes());

    PublicKey    ourPublicKey       = new PublicKey(31337, ourKeyPair.getPublicKey());
    byte[]       publicKeyBytes     = ourPublicKey.serialize();
    byte[]       combined           = Util.combine(publicKeyBytes, encryptedBodyBytes);

    return Base64.encodeBytes(combined);
  } catch (InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example #22
Source File: AsymmetricMasterCipher.java    From Silence with GNU General Public License v3.0 6 votes vote down vote up
public String decryptBody(String body) throws IOException, InvalidMessageException {
  try {
    byte[]    combined       = Base64.decode(body);
    byte[][]  parts          = Util.split(combined, PublicKey.KEY_SIZE, combined.length - PublicKey.KEY_SIZE);
    PublicKey theirPublicKey = new PublicKey(parts[0], 0);

    ECPrivateKey ourPrivateKey = asymmetricMasterSecret.getPrivateKey();
    byte[]       secret        = Curve.calculateAgreement(theirPublicKey.getKey(), ourPrivateKey);
    MasterCipher masterCipher  = getMasterCipherForSecret(secret);
    byte[]       decryptedBody = masterCipher.decryptBytes(parts[1]);

    return new String(decryptedBody);
  } catch (InvalidKeyException | InvalidMessageException ike) {
    throw new InvalidMessageException(ike);
  }
}
 
Example #23
Source File: SessionBuilder.java    From Silence with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Initiate a new session by sending an initial KeyExchangeMessage to the recipient.
 *
 * @return the KeyExchangeMessage to deliver.
 */
public KeyExchangeMessage process() {
  synchronized (SessionCipher.SESSION_LOCK) {
    try {
      int             sequence         = KeyHelper.getRandomSequence(65534) + 1;
      int             flags            = KeyExchangeMessage.INITIATE_FLAG;
      ECKeyPair       baseKey          = Curve.generateKeyPair();
      ECKeyPair       ratchetKey       = Curve.generateKeyPair();
      IdentityKeyPair identityKey      = identityKeyStore.getIdentityKeyPair();
      byte[]          baseKeySignature = Curve.calculateSignature(identityKey.getPrivateKey(), baseKey.getPublicKey().serialize());
      SessionRecord   sessionRecord    = sessionStore.loadSession(remoteAddress);

      sessionRecord.getSessionState().setPendingKeyExchange(sequence, baseKey, ratchetKey, identityKey);
      sessionStore.storeSession(remoteAddress, sessionRecord);

      return new KeyExchangeMessage(CiphertextMessage.CURRENT_VERSION,
                                    sequence, flags, baseKey.getPublicKey(), baseKeySignature,
                                    ratchetKey.getPublicKey(), identityKey.getPublicKey());
    } catch (InvalidKeyException e) {
      throw new AssertionError(e);
    }
  }
}
 
Example #24
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
private PreKeyBundle createAlicePreKeyBundle(SignalProtocolStore aliceStore) throws InvalidKeyException {
  ECKeyPair aliceUnsignedPreKey   = Curve.generateKeyPair();
  int       aliceUnsignedPreKeyId = new Random().nextInt(Medium.MAX_VALUE);
  byte[]    aliceSignature        = Curve.calculateSignature(aliceStore.getIdentityKeyPair().getPrivateKey(),
                                                             aliceSignedPreKey.getPublicKey().serialize());

  PreKeyBundle alicePreKeyBundle = new PreKeyBundle(1, 1,
                                                    aliceUnsignedPreKeyId, aliceUnsignedPreKey.getPublicKey(),
                                                    aliceSignedPreKeyId, aliceSignedPreKey.getPublicKey(),
                                                    aliceSignature, aliceStore.getIdentityKeyPair().getPublicKey());

  aliceStore.storeSignedPreKey(aliceSignedPreKeyId, new SignedPreKeyRecord(aliceSignedPreKeyId, System.currentTimeMillis(), aliceSignedPreKey, aliceSignature));
  aliceStore.storePreKey(aliceUnsignedPreKeyId, new PreKeyRecord(aliceUnsignedPreKeyId, aliceUnsignedPreKey));

  return alicePreKeyBundle;
}
 
Example #25
Source File: NumericFingerprintGeneratorTest.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
public void testMismatchingFingerprints() throws FingerprintVersionMismatchException, FingerprintIdentifierMismatchException, FingerprintParsingException {
  ECKeyPair aliceKeyPair = Curve.generateKeyPair();
  ECKeyPair bobKeyPair   = Curve.generateKeyPair();
  ECKeyPair mitmKeyPair  = Curve.generateKeyPair();

  IdentityKey aliceIdentityKey = new IdentityKey(aliceKeyPair.getPublicKey());
  IdentityKey bobIdentityKey   = new IdentityKey(bobKeyPair.getPublicKey());
  IdentityKey mitmIdentityKey  = new IdentityKey(mitmKeyPair.getPublicKey());

  NumericFingerprintGenerator generator        = new NumericFingerprintGenerator(1024);
  Fingerprint                 aliceFingerprint = generator.createFor(VERSION_1,
                                                                     "+14152222222".getBytes(), aliceIdentityKey,
                                                                     "+14153333333".getBytes(), mitmIdentityKey);

  Fingerprint bobFingerprint = generator.createFor(VERSION_1,
                                                   "+14153333333".getBytes(), bobIdentityKey,
                                                   "+14152222222".getBytes(), aliceIdentityKey);

  assertFalse(aliceFingerprint.getDisplayableFingerprint().getDisplayText().equals(
              bobFingerprint.getDisplayableFingerprint().getDisplayText()));

  assertFalse(aliceFingerprint.getScannableFingerprint().compareTo(bobFingerprint.getScannableFingerprint().getSerialized()));
  assertFalse(bobFingerprint.getScannableFingerprint().compareTo(aliceFingerprint.getScannableFingerprint().getSerialized()));
}
 
Example #26
Source File: Manager.java    From signald with GNU General Public License v3.0 6 votes vote down vote up
private List<PreKeyRecord> generatePreKeys() throws IOException {
    List<PreKeyRecord> records = new LinkedList<>();

    for (int i = 0; i < PREKEY_BATCH_SIZE; i++) {
        int preKeyId = (accountData.preKeyIdOffset + i) % Medium.MAX_VALUE;
        ECKeyPair keyPair = Curve.generateKeyPair();
        PreKeyRecord record = new PreKeyRecord(preKeyId, keyPair);

        accountData.axolotlStore.preKeys.storePreKey(preKeyId, record);
        records.add(record);
    }

    accountData.preKeyIdOffset = (accountData.preKeyIdOffset + PREKEY_BATCH_SIZE + 1) % Medium.MAX_VALUE;
    accountData.save();

    return records;
}
 
Example #27
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 #28
Source File: DeviceConsistencyMessage.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public DeviceConsistencyMessage(DeviceConsistencyCommitment commitment, byte[] serialized, IdentityKey identityKey) throws InvalidMessageException {
  try {
    SignalProtos.DeviceConsistencyCodeMessage message = SignalProtos.DeviceConsistencyCodeMessage.parseFrom(serialized);
    byte[] vrfOutputBytes = Curve.verifyVrfSignature(identityKey.getPublicKey(), commitment.toByteArray(), message.getSignature().toByteArray());

    this.generation = message.getGeneration();
    this.signature  = new DeviceConsistencySignature(message.getSignature().toByteArray(), vrfOutputBytes);
    this.serialized = serialized;
  } catch (InvalidProtocolBufferException | InvalidKeyException | VrfSignatureVerificationFailedException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #29
Source File: MasterSecretUtil.java    From Silence with GNU General Public License v3.0 5 votes vote down vote up
public static AsymmetricMasterSecret getAsymmetricMasterSecret(Context context,
                                                               MasterSecret masterSecret)
{
  try {
    byte[] djbPublicBytes   = retrieve(context, ASYMMETRIC_LOCAL_PUBLIC_DJB);
    byte[] djbPrivateBytes  = retrieve(context, ASYMMETRIC_LOCAL_PRIVATE_DJB);

    ECPublicKey  djbPublicKey  = null;
    ECPrivateKey djbPrivateKey = null;

    if (djbPublicBytes != null) {
      djbPublicKey = Curve.decodePoint(djbPublicBytes, 0);
    }

    if (masterSecret != null) {
      MasterCipher masterCipher = new MasterCipher(masterSecret);

      if (djbPrivateBytes != null) {
        djbPrivateKey = masterCipher.decryptKey(djbPrivateBytes);
      }
    }

    return new AsymmetricMasterSecret(djbPublicKey, djbPrivateKey);
  } catch (InvalidKeyException | IOException ike) {
    throw new AssertionError(ike);
  }
}
 
Example #30
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);
  }
}