Always include UUID in UD certificate (#300)
This commit is contained in:
		
							parent
							
								
									b1160af896
								
							
						
					
					
						commit
						299b680013
					
				| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue