Always include UUID in UD certificate (#300)

This commit is contained in:
Ehren Kret 2020-12-01 08:56:55 -06:00 committed by GitHub
parent b1160af896
commit 299b680013
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 48 deletions

View File

@ -33,25 +33,18 @@ public class CertificateGenerator {
this.serverCertificate = ServerCertificate.parseFrom(serverCertificate);
}
public byte[] createFor(Account account, Device device, boolean includeE164, boolean includeUuid) throws IOException, InvalidKeyException {
public byte[] createFor(Account account, Device device, boolean includeE164) throws IOException, InvalidKeyException {
SenderCertificate.Certificate.Builder builder = SenderCertificate.Certificate.newBuilder()
.setSenderDevice(Math.toIntExact(device.getId()))
.setExpires(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(expiresDays))
.setIdentityKey(ByteString.copyFrom(Base64.decode(account.getIdentityKey())))
.setSigner(serverCertificate);
if (!includeE164 && !includeUuid) {
throw new IllegalArgumentException("Certificates must include one of a sender phone number or UUID");
}
.setSigner(serverCertificate)
.setSenderUuid(account.getUuid().toString());
if (includeE164) {
builder.setSender(account.getNumber());
}
if (includeUuid) {
builder.setSenderUuid(account.getUuid().toString());
}
byte[] certificate = builder.build().toByteArray();
byte[] signature = Curve.calculateSignature(privateKey, certificate);

View File

@ -6,6 +6,7 @@
package org.whispersystems.textsecuregcm.controllers;
import com.codahale.metrics.annotation.Timed;
import io.dropwizard.auth.Auth;
import org.signal.zkgroup.auth.ServerZkAuthOperations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -29,8 +30,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import io.dropwizard.auth.Auth;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Path("/v1/certificate")
public class CertificateController {
@ -52,24 +51,17 @@ public class CertificateController {
@Produces(MediaType.APPLICATION_JSON)
@Path("/delivery")
public DeliveryCertificate getDeliveryCertificate(@Auth Account account,
@QueryParam("includeE164") Optional<Boolean> includeE164,
@QueryParam("includeUuid") Optional<Boolean> includeUuid)
@QueryParam("includeE164") Optional<Boolean> includeE164)
throws IOException, InvalidKeyException
{
if (!account.getAuthenticatedDevice().isPresent()) throw new AssertionError();
if (account.getAuthenticatedDevice().isEmpty()) {
throw new AssertionError();
}
if (Util.isEmpty(account.getIdentityKey())) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
final boolean effectiveIncludeE164 = includeE164.orElse(true);
final boolean effectiveIncludeUuid = includeUuid.orElse(false);
if (!effectiveIncludeE164 && !effectiveIncludeUuid) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
return new DeliveryCertificate(certificateGenerator.createFor(account, account.getAuthenticatedDevice().get(), effectiveIncludeE164, effectiveIncludeUuid));
return new DeliveryCertificate(certificateGenerator.createFor(account, account.getAuthenticatedDevice().get(), includeE164.orElse(true)));
}
@Timed

View File

@ -15,7 +15,6 @@ import java.io.IOException;
import java.security.InvalidKeyException;
import java.util.UUID;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -37,10 +36,7 @@ public class CertificateGeneratorTest {
when(account.getNumber()).thenReturn("+18005551234");
when(device.getId()).thenReturn(4L);
assertTrue(certificateGenerator.createFor(account, device, true, true).length > 0);
assertTrue(certificateGenerator.createFor(account, device, false, true).length > 0);
assertTrue(certificateGenerator.createFor(account, device, true, false).length > 0);
assertThrows(IllegalArgumentException.class, () -> certificateGenerator.createFor(account, device, false, false));
assertTrue(certificateGenerator.createFor(account, device, true).length > 0);
assertTrue(certificateGenerator.createFor(account, device, false).length > 0);
}
}

View File

@ -6,6 +6,8 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import org.apache.commons.lang3.StringUtils;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.ClassRule;
@ -36,13 +38,9 @@ import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.Arrays;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static junit.framework.TestCase.assertTrue;
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
public class CertificateControllerTest {
@ -95,7 +93,8 @@ public class CertificateControllerTest {
assertEquals(certificate.getSender(), AuthHelper.VALID_NUMBER);
assertEquals(certificate.getSenderDevice(), 1L);
assertFalse(certificate.hasSenderUuid());
assertTrue(certificate.hasSenderUuid());
assertEquals(AuthHelper.VALID_UUID.toString(), certificate.getSenderUuid());
assertTrue(Arrays.equals(certificate.getIdentityKey().toByteArray(), Base64.decode(AuthHelper.VALID_IDENTITY)));
}
@ -150,19 +149,6 @@ public class CertificateControllerTest {
assertTrue(Arrays.equals(certificate.getIdentityKey().toByteArray(), Base64.decode(AuthHelper.VALID_IDENTITY)));
}
@Test
public void testValidCertificateWithNoUuidNoE164() throws Exception {
Response response = resources.getJerseyTest()
.target("/v1/certificate/delivery")
.queryParam("includeUuid", "false")
.queryParam("includeE164", "false")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get();
assertEquals(response.getStatus(), 400);
}
@Test
public void testBadAuthentication() throws Exception {
Response response = resources.getJerseyTest()