Search in sources :

Example 1 with DiscoveryRequest

use of org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest in project Signal-Android by WhisperSystems.

the class ContactDiscoveryCipher method createDiscoveryRequest.

public static DiscoveryRequest createDiscoveryRequest(List<String> addressBook, Map<String, RemoteAttestation> remoteAttestations) {
    byte[] queryDataKey = Util.getSecretBytes(32);
    byte[] queryData = buildQueryData(addressBook);
    AESEncryptedResult encryptedQueryData = AESCipher.encrypt(queryDataKey, null, queryData);
    byte[] commitment = CryptoUtil.sha256(queryData);
    Map<String, QueryEnvelope> envelopes = new HashMap<>(remoteAttestations.size());
    for (Map.Entry<String, RemoteAttestation> entry : remoteAttestations.entrySet()) {
        envelopes.put(entry.getKey(), buildQueryEnvelope(entry.getValue().getRequestId(), entry.getValue().getKeys().getClientKey(), queryDataKey));
    }
    return new DiscoveryRequest(addressBook.size(), commitment, encryptedQueryData.iv, encryptedQueryData.data, encryptedQueryData.mac, envelopes);
}
Also used : QueryEnvelope(org.whispersystems.signalservice.internal.contacts.entities.QueryEnvelope) HashMap(java.util.HashMap) AESEncryptedResult(org.whispersystems.signalservice.internal.contacts.crypto.AESCipher.AESEncryptedResult) DiscoveryRequest(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with DiscoveryRequest

use of org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest in project libsignal-service-java by signalapp.

the class SignalServiceAccountManager method getRegisteredUsers.

public List<String> getRegisteredUsers(KeyStore iasKeyStore, Set<String> e164numbers, String mrenclave) throws IOException, Quote.InvalidQuoteFormatException, UnauthenticatedQuoteException, SignatureException, UnauthenticatedResponseException {
    try {
        String authorization = this.pushServiceSocket.getContactDiscoveryAuthorization();
        Curve25519 curve = Curve25519.getInstance(Curve25519.BEST);
        Curve25519KeyPair keyPair = curve.generateKeyPair();
        ContactDiscoveryCipher cipher = new ContactDiscoveryCipher();
        RemoteAttestationRequest attestationRequest = new RemoteAttestationRequest(keyPair.getPublicKey());
        Pair<RemoteAttestationResponse, List<String>> attestationResponse = this.pushServiceSocket.getContactDiscoveryRemoteAttestation(authorization, attestationRequest, mrenclave);
        RemoteAttestationKeys keys = new RemoteAttestationKeys(keyPair, attestationResponse.first().getServerEphemeralPublic(), attestationResponse.first().getServerStaticPublic());
        Quote quote = new Quote(attestationResponse.first().getQuote());
        byte[] requestId = cipher.getRequestId(keys, attestationResponse.first());
        cipher.verifyServerQuote(quote, attestationResponse.first().getServerStaticPublic(), mrenclave);
        cipher.verifyIasSignature(iasKeyStore, attestationResponse.first().getCertificates(), attestationResponse.first().getSignatureBody(), attestationResponse.first().getSignature(), quote);
        RemoteAttestation remoteAttestation = new RemoteAttestation(requestId, keys);
        List<String> addressBook = new LinkedList<>();
        for (String e164number : e164numbers) {
            addressBook.add(e164number.substring(1));
        }
        DiscoveryRequest request = cipher.createDiscoveryRequest(addressBook, remoteAttestation);
        DiscoveryResponse response = this.pushServiceSocket.getContactDiscoveryRegisteredUsers(authorization, request, attestationResponse.second(), mrenclave);
        byte[] data = cipher.getDiscoveryResponseData(response, remoteAttestation);
        Iterator<String> addressBookIterator = addressBook.iterator();
        List<String> results = new LinkedList<>();
        for (byte aData : data) {
            String candidate = addressBookIterator.next();
            if (aData != 0)
                results.add('+' + candidate);
        }
        return results;
    } catch (InvalidCiphertextException e) {
        throw new UnauthenticatedResponseException(e);
    }
}
Also used : ContactDiscoveryCipher(org.whispersystems.signalservice.internal.contacts.crypto.ContactDiscoveryCipher) DiscoveryResponse(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryResponse) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) RemoteAttestationResponse(org.whispersystems.signalservice.internal.contacts.entities.RemoteAttestationResponse) RemoteAttestationKeys(org.whispersystems.signalservice.internal.contacts.crypto.RemoteAttestationKeys) ByteString(com.google.protobuf.ByteString) LinkedList(java.util.LinkedList) Quote(org.whispersystems.signalservice.internal.contacts.crypto.Quote) RemoteAttestation(org.whispersystems.signalservice.internal.contacts.crypto.RemoteAttestation) RemoteAttestationRequest(org.whispersystems.signalservice.internal.contacts.entities.RemoteAttestationRequest) UnauthenticatedResponseException(org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException) Curve25519KeyPair(org.whispersystems.curve25519.Curve25519KeyPair) List(java.util.List) LinkedList(java.util.LinkedList) DiscoveryRequest(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest) Curve25519(org.whispersystems.curve25519.Curve25519)

Example 3 with DiscoveryRequest

use of org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest in project Signal-Android by WhisperSystems.

the class SignalServiceAccountManager method getRegisteredUsers.

@SuppressWarnings("SameParameterValue")
public Map<String, ACI> getRegisteredUsers(KeyStore iasKeyStore, Set<String> e164numbers, String mrenclave) throws IOException, Quote.InvalidQuoteFormatException, UnauthenticatedQuoteException, SignatureException, UnauthenticatedResponseException, InvalidKeyException {
    if (e164numbers.isEmpty()) {
        return Collections.emptyMap();
    }
    try {
        String authorization = this.pushServiceSocket.getContactDiscoveryAuthorization();
        Map<String, RemoteAttestation> attestations = RemoteAttestationUtil.getAndVerifyMultiRemoteAttestation(pushServiceSocket, PushServiceSocket.ClientSet.ContactDiscovery, iasKeyStore, mrenclave, mrenclave, authorization);
        List<String> addressBook = new ArrayList<>(e164numbers.size());
        for (String e164number : e164numbers) {
            addressBook.add(e164number.substring(1));
        }
        List<String> cookies = attestations.values().iterator().next().getCookies();
        DiscoveryRequest request = ContactDiscoveryCipher.createDiscoveryRequest(addressBook, attestations);
        DiscoveryResponse response = this.pushServiceSocket.getContactDiscoveryRegisteredUsers(authorization, request, cookies, mrenclave);
        byte[] data = ContactDiscoveryCipher.getDiscoveryResponseData(response, attestations.values());
        HashMap<String, ACI> results = new HashMap<>(addressBook.size());
        DataInputStream uuidInputStream = new DataInputStream(new ByteArrayInputStream(data));
        for (String candidate : addressBook) {
            long candidateUuidHigh = uuidInputStream.readLong();
            long candidateUuidLow = uuidInputStream.readLong();
            if (candidateUuidHigh != 0 || candidateUuidLow != 0) {
                results.put('+' + candidate, ACI.from(new UUID(candidateUuidHigh, candidateUuidLow)));
            }
        }
        return results;
    } catch (InvalidCiphertextException e) {
        throw new UnauthenticatedResponseException(e);
    }
}
Also used : DiscoveryResponse(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryResponse) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) HashMap(java.util.HashMap) ACI(org.whispersystems.signalservice.api.push.ACI) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) DataInputStream(java.io.DataInputStream) RemoteAttestation(org.whispersystems.signalservice.internal.contacts.crypto.RemoteAttestation) ByteArrayInputStream(java.io.ByteArrayInputStream) UnauthenticatedResponseException(org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException) DiscoveryRequest(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest) UUID(java.util.UUID)

Example 4 with DiscoveryRequest

use of org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest in project Signal-Android by signalapp.

the class SignalServiceAccountManager method getRegisteredUsers.

@SuppressWarnings("SameParameterValue")
public Map<String, ACI> getRegisteredUsers(KeyStore iasKeyStore, Set<String> e164numbers, String mrenclave) throws IOException, Quote.InvalidQuoteFormatException, UnauthenticatedQuoteException, SignatureException, UnauthenticatedResponseException, InvalidKeyException {
    if (e164numbers.isEmpty()) {
        return Collections.emptyMap();
    }
    try {
        String authorization = this.pushServiceSocket.getContactDiscoveryAuthorization();
        Map<String, RemoteAttestation> attestations = RemoteAttestationUtil.getAndVerifyMultiRemoteAttestation(pushServiceSocket, PushServiceSocket.ClientSet.ContactDiscovery, iasKeyStore, mrenclave, mrenclave, authorization);
        List<String> addressBook = new ArrayList<>(e164numbers.size());
        for (String e164number : e164numbers) {
            addressBook.add(e164number.substring(1));
        }
        List<String> cookies = attestations.values().iterator().next().getCookies();
        DiscoveryRequest request = ContactDiscoveryCipher.createDiscoveryRequest(addressBook, attestations);
        DiscoveryResponse response = this.pushServiceSocket.getContactDiscoveryRegisteredUsers(authorization, request, cookies, mrenclave);
        byte[] data = ContactDiscoveryCipher.getDiscoveryResponseData(response, attestations.values());
        HashMap<String, ACI> results = new HashMap<>(addressBook.size());
        DataInputStream uuidInputStream = new DataInputStream(new ByteArrayInputStream(data));
        for (String candidate : addressBook) {
            long candidateUuidHigh = uuidInputStream.readLong();
            long candidateUuidLow = uuidInputStream.readLong();
            if (candidateUuidHigh != 0 || candidateUuidLow != 0) {
                results.put('+' + candidate, ACI.from(new UUID(candidateUuidHigh, candidateUuidLow)));
            }
        }
        return results;
    } catch (InvalidCiphertextException e) {
        throw new UnauthenticatedResponseException(e);
    }
}
Also used : DiscoveryResponse(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryResponse) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) HashMap(java.util.HashMap) ACI(org.whispersystems.signalservice.api.push.ACI) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) DataInputStream(java.io.DataInputStream) RemoteAttestation(org.whispersystems.signalservice.internal.contacts.crypto.RemoteAttestation) ByteArrayInputStream(java.io.ByteArrayInputStream) UnauthenticatedResponseException(org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException) DiscoveryRequest(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest) UUID(java.util.UUID)

Example 5 with DiscoveryRequest

use of org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest in project libsignal-service-java by signalapp.

the class ContactDiscoveryCipher method createDiscoveryRequest.

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);
    }
}
Also used : InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) InvalidKeyException(java.security.InvalidKeyException) SecretKeySpec(javax.crypto.spec.SecretKeySpec) Cipher(javax.crypto.Cipher) DiscoveryRequest(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest)

Aggregations

DiscoveryRequest (org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest)6 HashMap (java.util.HashMap)4 ByteString (com.google.protobuf.ByteString)3 InvalidCiphertextException (org.whispersystems.signalservice.api.crypto.InvalidCiphertextException)3 RemoteAttestation (org.whispersystems.signalservice.internal.contacts.crypto.RemoteAttestation)3 UnauthenticatedResponseException (org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException)3 DiscoveryResponse (org.whispersystems.signalservice.internal.contacts.entities.DiscoveryResponse)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 DataInputStream (java.io.DataInputStream)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 UUID (java.util.UUID)2 ACI (org.whispersystems.signalservice.api.push.ACI)2 AESEncryptedResult (org.whispersystems.signalservice.internal.contacts.crypto.AESCipher.AESEncryptedResult)2 QueryEnvelope (org.whispersystems.signalservice.internal.contacts.entities.QueryEnvelope)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)1 InvalidKeyException (java.security.InvalidKeyException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1