org.whispersystems.libsignal.InvalidKeyException Java Examples

The following examples show how to use org.whispersystems.libsignal.InvalidKeyException. 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: 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 #2
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 #3
Source File: SignalServiceMessageSender.java    From libsignal-service-java with GNU General Public License v3.0 6 votes vote down vote up
private OutgoingPushMessageList getEncryptedMessages(PushServiceSocket            socket,
                                                     SignalServiceAddress         recipient,
                                                     Optional<UnidentifiedAccess> unidentifiedAccess,
                                                     long                         timestamp,
                                                     byte[]                       plaintext,
                                                     boolean                      online)
    throws IOException, InvalidKeyException, UntrustedIdentityException
{
  List<OutgoingPushMessage> messages = new LinkedList<>();

  if (!recipient.matches(localAddress) || unidentifiedAccess.isPresent()) {
    messages.add(getEncryptedMessage(socket, recipient, unidentifiedAccess, SignalServiceAddress.DEFAULT_DEVICE_ID, plaintext));
  }

  for (int deviceId : store.getSubDeviceSessions(recipient.getIdentifier())) {
    if (store.containsSession(new SignalProtocolAddress(recipient.getIdentifier(), deviceId))) {
      messages.add(getEncryptedMessage(socket, recipient, unidentifiedAccess, deviceId, plaintext));
    }
  }

  return new OutgoingPushMessageList(recipient.getIdentifier(), timestamp, messages, online);
}
 
Example #4
Source File: DatabaseBackend.java    From Pix-Art-Messenger with GNU General Public License v3.0 6 votes vote down vote up
public Set<IdentityKey> loadIdentityKeys(Account account, String name, FingerprintStatus status) {
    Set<IdentityKey> identityKeys = new HashSet<>();
    Cursor cursor = getIdentityKeyCursor(account, name, false);

    while (cursor.moveToNext()) {
        if (status != null && !FingerprintStatus.fromCursor(cursor).equals(status)) {
            continue;
        }
        try {
            String key = cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY));
            if (key != null) {
                identityKeys.add(new IdentityKey(Base64.decode(key, Base64.DEFAULT), 0));
            } else {
                Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Missing key (possibly preverified) in database for account" + account.getJid().asBareJid() + ", address: " + name);
            }
        } catch (InvalidKeyException e) {
            Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Encountered invalid IdentityKey in database for account" + account.getJid().asBareJid() + ", address: " + name);
        }
    }
    cursor.close();

    return identityKeys;
}
 
Example #5
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 #6
Source File: SignalStorageModels.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public static SignalStorageRecord remoteToLocalStorageRecord(StorageItem item, int type, StorageKey storageKey) throws IOException, InvalidKeyException {
  byte[]        key       = item.getKey().toByteArray();
  byte[]        rawRecord = SignalStorageCipher.decrypt(storageKey.deriveItemKey(key), item.getValue().toByteArray());
  StorageRecord record    = StorageRecord.parseFrom(rawRecord);
  StorageId     id        = StorageId.forType(key, type);

  if (record.hasContact() && type == ManifestRecord.Identifier.Type.CONTACT_VALUE) {
    return SignalStorageRecord.forContact(id, new SignalContactRecord(id, record.getContact()));
  } else if (record.hasGroupV1() && type == ManifestRecord.Identifier.Type.GROUPV1_VALUE) {
    return SignalStorageRecord.forGroupV1(id, new SignalGroupV1Record(id, record.getGroupV1()));
  } else if (record.hasGroupV2() && type == ManifestRecord.Identifier.Type.GROUPV2_VALUE && record.getGroupV2().getMasterKey().size() == GroupMasterKey.SIZE) {
    return SignalStorageRecord.forGroupV2(id, new SignalGroupV2Record(id, record.getGroupV2()));
  } else if (record.hasAccount() && type == ManifestRecord.Identifier.Type.ACCOUNT_VALUE) {
    return SignalStorageRecord.forAccount(id, new SignalAccountRecord(id, record.getAccount()));
  } else {
    return SignalStorageRecord.forUnknown(StorageId.forType(key, type));
  }
}
 
Example #7
Source File: SignalServiceMessageSender.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private OutgoingPushMessageList getEncryptedMessages(PushServiceSocket            socket,
                                                     SignalServiceAddress         recipient,
                                                     Optional<UnidentifiedAccess> unidentifiedAccess,
                                                     long                         timestamp,
                                                     byte[]                       plaintext,
                                                     boolean                      online)
    throws IOException, InvalidKeyException, UntrustedIdentityException
{
  List<OutgoingPushMessage> messages = new LinkedList<>();

  if (!recipient.matches(localAddress) || unidentifiedAccess.isPresent()) {
    messages.add(getEncryptedMessage(socket, recipient, unidentifiedAccess, SignalServiceAddress.DEFAULT_DEVICE_ID, plaintext));
  }

  for (int deviceId : store.getSubDeviceSessions(recipient.getIdentifier())) {
    if (store.containsSession(new SignalProtocolAddress(recipient.getIdentifier(), deviceId))) {
      messages.add(getEncryptedMessage(socket, recipient, unidentifiedAccess, deviceId, plaintext));
    }
  }

  return new OutgoingPushMessageList(recipient.getIdentifier(), timestamp, messages, online);
}
 
Example #8
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 #9
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 #10
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 #11
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 #12
Source File: AsymmetricMasterCipher.java    From bcm-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.encryptBytes(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 #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: 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 #15
Source File: MasterSecretUtil.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public static AsymmetricMasterSecret getAsymmetricMasterSecret(@NonNull  Context context,
                                                               @Nullable MasterSecret masterSecret)
{
  try {
    byte[] djbPublicBytes   = retrieve(context, ASYMMETRIC_LOCAL_PUBLIC_DJB);
    byte[] djbPrivateBytes  = retrieve(context, ASYMMETRIC_LOCAL_PRIVATE_DJB);

    MasterCipher masterCipher  = new MasterCipher(masterSecret);
    ECPublicKey  djbPublicKey  = masterCipher.decryptPublicKey(djbPublicBytes);
    ECPrivateKey djbPrivateKey = masterCipher.decryptPrivateKey(djbPrivateBytes);

    return new AsymmetricMasterSecret(djbPublicKey, djbPrivateKey);
  } catch (InvalidKeyException ike) {
    throw new SecurityException(ike);
  }
}
 
Example #16
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 #17
Source File: IdentityKeyUtil.java    From Silence with GNU General Public License v3.0 6 votes vote down vote up
public static IdentityKeyPair getIdentityKeyPair(Context context,
                                                 MasterSecret masterSecret,
                                                 int subscriptionId)
{
  if (!hasIdentityKey(context, subscriptionId))
    return null;

  try {
    MasterCipher masterCipher = new MasterCipher(masterSecret);
    IdentityKey  publicKey    = getIdentityKey(context, subscriptionId);
    ECPrivateKey privateKey   = masterCipher.decryptKey(Base64.decode(retrieve(context, getIdentityPrivateKeyDjbPref(subscriptionId))));

    return new IdentityKeyPair(publicKey, privateKey);
  } catch (IOException | InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example #18
Source File: IdentityDatabase.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public Optional<IdentityRecord> getIdentity(String uid) {
    SQLiteDatabase database = databaseHelper.getReadableDatabase();
    Cursor cursor = null;

    try {
        cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?",
                new String[]{uid}, null, null, null);

        if (cursor != null && cursor.moveToFirst()) {
            return Optional.of(getIdentityRecord(cursor));
        }
    } catch (InvalidKeyException | IOException e) {
        throw new AssertionError(e);
    } finally {
        if (cursor != null)
            cursor.close();
    }

    return Optional.absent();
}
 
Example #19
Source File: MultiDeviceVerifiedUpdateJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void onRun() throws IOException, UntrustedIdentityException {
  try {
    if (!TextSecurePreferences.isMultiDevice(context)) {
      Log.i(TAG, "Not multi device...");
      return;
    }

    if (destination == null) {
      Log.w(TAG, "No destination...");
      return;
    }

    SignalServiceMessageSender    messageSender        = ApplicationDependencies.getSignalServiceMessageSender();
    Recipient                     recipient            = Recipient.resolved(destination);
    VerifiedMessage.VerifiedState verifiedState        = getVerifiedState(verifiedStatus);
    SignalServiceAddress          verifiedAddress      = RecipientUtil.toSignalServiceAddress(context, recipient);
    VerifiedMessage               verifiedMessage      = new VerifiedMessage(verifiedAddress, new IdentityKey(identityKey, 0), verifiedState, timestamp);

    messageSender.sendMessage(SignalServiceSyncMessage.forVerified(verifiedMessage),
                              UnidentifiedAccessUtil.getAccessFor(context, recipient));
  } catch (InvalidKeyException e) {
    throw new IOException(e);
  }
}
 
Example #20
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 #21
Source File: RetrieveProfileJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void setIdentityKey(Recipient recipient, String identityKeyValue) {
  try {
    if (TextUtils.isEmpty(identityKeyValue)) {
      Log.w(TAG, "Identity key is missing on profile!");
      return;
    }

    IdentityKey identityKey = new IdentityKey(Base64.decode(identityKeyValue), 0);

    if (!DatabaseFactory.getIdentityDatabase(context)
                        .getIdentity(recipient.getId())
                        .isPresent())
    {
      Log.w(TAG, "Still first use...");
      return;
    }

    IdentityUtil.saveIdentity(context, recipient.requireServiceId(), identityKey);
  } catch (InvalidKeyException | IOException e) {
    Log.w(TAG, e);
  }
}
 
Example #22
Source File: IdentityDatabase.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public @NonNull IdentityRecordList getIdentities(@NonNull List<Recipient> recipients) {
  IdentityRecordList identityRecordList = new IdentityRecordList();
  SQLiteDatabase     database           = databaseHelper.getReadableDatabase();
  String[]           selectionArgs      = new String[1];

  database.beginTransaction();
  try {
    for (Recipient recipient : recipients) {
      selectionArgs[0] = recipient.getId().serialize();

      try (Cursor cursor = database.query(TABLE_NAME, null, RECIPIENT_ID + " = ?", selectionArgs, null, null, null)) {
        if (cursor.moveToFirst()) {
          identityRecordList.add(getIdentityRecord(cursor));
        }
      } catch (InvalidKeyException | IOException e) {
        throw new AssertionError(e);
      }
    }
  } finally {
    database.endTransaction();
  }

  return identityRecordList;
}
 
Example #23
Source File: Manager.java    From signal-cli with GNU General Public License v3.0 5 votes vote down vote up
private SignedPreKeyRecord generateSignedPreKey(IdentityKeyPair identityKeyPair) {
    try {
        ECKeyPair keyPair = Curve.generateKeyPair();
        byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
        SignedPreKeyRecord record = new SignedPreKeyRecord(account.getNextSignedPreKeyId(), System.currentTimeMillis(), keyPair, signature);

        account.addSignedPreKey(record);
        account.save();

        return record;
    } catch (InvalidKeyException e) {
        throw new AssertionError(e);
    }
}
 
Example #24
Source File: ProvisioningCipher.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private byte[] getMac(byte[] key, byte[] message) {
  try {
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(key, "HmacSHA256"));

    return mac.doFinal(message);
  } catch (NoSuchAlgorithmException | java.security.InvalidKeyException e) {
    throw new AssertionError(e);
  }
}
 
Example #25
Source File: Utils.java    From signal-cli with GNU General Public License v3.0 5 votes vote down vote up
static DeviceLinkInfo parseDeviceLinkUri(URI linkUri) throws IOException, InvalidKeyException {
    Map<String, String> query = getQueryMap(linkUri.getRawQuery());
    String deviceIdentifier = query.get("uuid");
    String publicKeyEncoded = query.get("pub_key");

    if (isEmpty(deviceIdentifier) || isEmpty(publicKeyEncoded)) {
        throw new RuntimeException("Invalid device link uri");
    }

    ECPublicKey deviceKey = Curve.decodePoint(Base64.decode(publicKeyEncoded), 0);

    return new DeviceLinkInfo(deviceIdentifier, deviceKey);
}
 
Example #26
Source File: SignalServiceAccountManager.java    From libsignal-service-java with GNU General Public License v3.0 5 votes vote down vote up
public void addDevice(String deviceIdentifier,
                      ECPublicKey deviceKey,
                      IdentityKeyPair identityKeyPair,
                      Optional<byte[]> profileKey,
                      String code)
    throws InvalidKeyException, IOException
{
  ProvisioningCipher       cipher  = new ProvisioningCipher(deviceKey);
  ProvisionMessage.Builder message = ProvisionMessage.newBuilder()
                                                     .setIdentityKeyPublic(ByteString.copyFrom(identityKeyPair.getPublicKey().serialize()))
                                                     .setIdentityKeyPrivate(ByteString.copyFrom(identityKeyPair.getPrivateKey().serialize()))
                                                     .setProvisioningCode(code)
                                                     .setProvisioningVersion(ProvisioningVersion.CURRENT_VALUE);
  if (userE164 != null) {
    message.setNumber(userE164);
  }

  if (userUuid != null) {
    message.setUuid(userUuid.toString());
  }

  if (profileKey.isPresent()) {
    message.setProfileKey(ByteString.copyFrom(profileKey.get()));
  }

  byte[] ciphertext = cipher.encrypt(message.build());
  this.pushServiceSocket.sendProvisioningMessage(deviceIdentifier, ciphertext);
}
 
Example #27
Source File: IdentityKeyUtil.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
public static @NonNull
IdentityKey getIdentityKey(@NonNull AccountContext accountContext) {
    if (!hasIdentityKey(accountContext)) {
        throw new IllegalStateException("There isn't one!");
    }

    try {
        byte[] publicKeyBytes = Base64.decode(retrieve(accountContext, IDENTITY_PUBLIC_KEY_PREF));
        return new IdentityKey(publicKeyBytes, 0);
    } catch (IOException | InvalidKeyException e) {
        throw new AssertionError(e);
    }
}
 
Example #28
Source File: IdentityKeyUtil.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private static IdentityKeyPair getLegacyIdentityKeyPair(@NonNull AccountContext accountContext,
                                                        @NonNull MasterSecret masterSecret) {
    try {
        MasterCipher masterCipher = new MasterCipher(masterSecret);
        byte[] publicKeyBytes = Base64.decode(retrieve(accountContext, IDENTITY_PUBLIC_KEY_CIPHERTEXT_LEGACY_PREF));
        IdentityKey identityKey = new IdentityKey(publicKeyBytes, 0);
        ECPrivateKey privateKey = masterCipher.decryptKey(Base64.decode(retrieve(accountContext, IDENTITY_PRIVATE_KEY_CIPHERTEXT_LEGACY_PREF)));

        return new IdentityKeyPair(identityKey, privateKey);
    } catch (IOException | InvalidKeyException e) {
        throw new AssertionError(e);
    }
}
 
Example #29
Source File: Manager.java    From signal-cli with GNU General Public License v3.0 5 votes vote down vote up
private void addDevice(String deviceIdentifier, ECPublicKey deviceKey) throws IOException, InvalidKeyException {
    IdentityKeyPair identityKeyPair = getIdentityKeyPair();
    String verificationCode = accountManager.getNewDeviceVerificationCode();

    accountManager.addDevice(deviceIdentifier, deviceKey, identityKeyPair, Optional.of(account.getProfileKey().serialize()), verificationCode);
    account.setMultiDevice(true);
    account.save();
}
 
Example #30
Source File: IdentityDatabase.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
public @Nullable
IdentityRecord getNext() {
    if (cursor.moveToNext()) {
        try {
            return getIdentityRecord(cursor);
        } catch (IOException | InvalidKeyException e) {
            throw new AssertionError(e);
        }
    }

    return null;
}