use of com.quorum.tessera.partyinfo.model.Recipient in project tessera by ConsenSys.
the class PeerToPeerIT method benevolentNodeBecomesPossessedAndSendsInvalidKeyInRecipientList.
/*
A good node with valid key has a bad recipient in its party info
*/
@Test
public void benevolentNodeBecomesPossessedAndSendsInvalidKeyInRecipientList() throws Exception {
Party partyB = partyHelper.findByAlias(NodeAlias.B);
ServerConfig serverConfig = partyB.getConfig().getP2PServerConfig();
PublicKey publicKey = Optional.of(partyB).map(Party::getPublicKey).map(Base64.getDecoder()::decode).map(PublicKey::from).get();
Recipient itself = Recipient.of(publicKey, serverConfig.getServerUri().toString());
String validButIncorrectUrl = partyHelper.findByAlias(NodeAlias.C).getConfig().getP2PServerConfig().getServerAddress();
Recipient badRecipient = Recipient.of(PublicKey.from("OUCH".getBytes()), validButIncorrectUrl);
Set<Recipient> recipients = Stream.of(itself, badRecipient).collect(Collectors.toSet());
assertThat(recipients).containsExactlyInAnyOrder(itself, badRecipient);
PartyInfo partyInfo = new PartyInfo(serverConfig.getServerUri().toString(), recipients, Collections.emptySet());
Client client = new ClientFactory().buildFrom(serverConfig);
PartyInfoParser partyInfoParser = PartyInfoParser.create();
byte[] data = partyInfoParser.to(partyInfo);
StreamingOutput output = out -> out.write(data);
Response response = client.target(partyA.getP2PUri()).path("partyinfo").request().post(Entity.entity(output, MediaType.APPLICATION_OCTET_STREAM));
assertThat(response.getStatus()).isEqualTo(200);
}
use of com.quorum.tessera.partyinfo.model.Recipient in project tessera by ConsenSys.
the class PeerToPeerIT method maliciousNodeHasInvalidKey.
/*
If the sending node has an invalid key, we 200 as the secondary key
should not be validated.
*/
@Test
public void maliciousNodeHasInvalidKey() throws Exception {
Party highjackedParty = partyHelper.findByAlias(NodeAlias.B);
PublicKey bogusKey = PublicKey.from("BADKEY".getBytes());
ServerConfig serverConfig = highjackedParty.getConfig().getP2PServerConfig();
Recipient recipient = Recipient.of(bogusKey, serverConfig.getServerUri().toString());
PartyInfo partyInfo = new PartyInfo(serverConfig.getServerUri().toString(), Collections.singleton(recipient), Collections.emptySet());
Client client = clientFactory.buildFrom(serverConfig);
PartyInfoParser partyInfoParser = PartyInfoParser.create();
byte[] data = partyInfoParser.to(partyInfo);
StreamingOutput output = out -> out.write(data);
Response response = client.target(partyA.getP2PUri()).path("partyinfo").request().post(Entity.entity(output, MediaType.APPLICATION_OCTET_STREAM));
assertThat(response.getStatus()).isEqualTo(500);
}
use of com.quorum.tessera.partyinfo.model.Recipient in project tessera by ConsenSys.
the class PeerToPeerIT method benevolentNodeBecomesPosessedAndSendsInvalidUrlInRecipientList.
/*
A good node with valid key has a bad recipient in its party info.
The key is valid (node C's key) but there is a validation failure as
the url cannot be called.
*/
@Test
public void benevolentNodeBecomesPosessedAndSendsInvalidUrlInRecipientList() throws Exception {
Party partyB = partyHelper.findByAlias(NodeAlias.B);
ServerConfig serverConfig = Optional.of(partyB.getConfig()).map(Config::getP2PServerConfig).get();
PublicKey publicKey = Optional.of(partyB).map(Party::getPublicKey).map(Base64.getDecoder()::decode).map(PublicKey::from).get();
Recipient itself = Recipient.of(publicKey, serverConfig.getServerUri().toString());
String validKeyFromOtherNode = partyHelper.findByAlias(NodeAlias.C).getPublicKey();
PublicKey validButIncorrectKey = Optional.of(validKeyFromOtherNode).map(Base64.getDecoder()::decode).map(PublicKey::from).get();
Recipient badRecipient = Recipient.of(validButIncorrectKey, "http://bogus.supersnide.com:8829");
Set<Recipient> recipients = Stream.of(itself, badRecipient).collect(Collectors.toSet());
assertThat(recipients).containsExactlyInAnyOrder(itself, badRecipient);
PartyInfo partyInfo = new PartyInfo(serverConfig.getServerUri().toString(), recipients, Collections.emptySet());
Client client = new ClientFactory().buildFrom(serverConfig);
PartyInfoParser partyInfoParser = PartyInfoParser.create();
byte[] data = partyInfoParser.to(partyInfo);
StreamingOutput output = out -> out.write(data);
Response response = client.target(partyA.getP2PUri()).path("partyinfo").request().post(Entity.entity(output, MediaType.APPLICATION_OCTET_STREAM));
assertThat(response.getStatus()).isEqualTo(200);
}
use of com.quorum.tessera.partyinfo.model.Recipient in project tessera by ConsenSys.
the class PartyInfoResourceTest method partyInfoValidateThrowsException.
@Test
public void partyInfoValidateThrowsException() {
String url = "http://www.bogus.com";
PublicKey myKey = PublicKey.from("myKey".getBytes());
PublicKey recipientKey = PublicKey.from("recipientKey".getBytes());
String message = "I love sparrows";
byte[] payload = message.getBytes();
Recipient recipient = Recipient.of(recipientKey, url);
Set<Recipient> recipientList = Collections.singleton(recipient);
PartyInfo partyInfo = new PartyInfo(url, recipientList, Collections.emptySet());
when(partyInfoParser.from(payload)).thenReturn(partyInfo);
when(enclave.defaultPublicKey()).thenReturn(myKey);
when(partyInfoParser.to(partyInfo)).thenReturn(payload);
EncodedPayload encodedPayload = mock(EncodedPayload.class);
when(enclave.encryptPayload(any(byte[].class), any(PublicKey.class), anyList(), any(PrivacyMetadata.class))).thenReturn(encodedPayload);
when(payloadEncoder.encode(encodedPayload)).thenReturn(payload);
WebTarget webTarget = mock(WebTarget.class);
when(restClient.target(url)).thenReturn(webTarget);
when(webTarget.path(anyString())).thenReturn(webTarget);
Invocation.Builder invocationBuilder = mock(Invocation.Builder.class);
when(webTarget.request()).thenReturn(invocationBuilder);
when(invocationBuilder.post(any(Entity.class))).thenThrow(new UncheckedIOException(new IOException("GURU meditation")));
try {
partyInfoResource.partyInfo(payload, null);
failBecauseExceptionWasNotThrown(SecurityException.class);
} catch (SecurityException ex) {
verify(partyInfoParser).from(payload);
verify(enclave).defaultPublicKey();
verify(enclave).encryptPayload(any(byte[].class), any(PublicKey.class), anyList(), any(PrivacyMetadata.class));
verify(payloadEncoder).encode(encodedPayload);
verify(restClient).target(url);
}
}
use of com.quorum.tessera.partyinfo.model.Recipient in project tessera by ConsenSys.
the class PartyInfoResourceTest method partyInfoValidationEncryptsUniqueDataForEachKey.
@Test
public void partyInfoValidationEncryptsUniqueDataForEachKey() {
String url = "http://bogus";
Set<Party> parties = Collections.emptySet();
Set<Recipient> recipients = new HashSet<>();
recipients.add(Recipient.of(mock(PublicKey.class), url));
recipients.add(Recipient.of(mock(PublicKey.class), url));
PartyInfo partyInfo = new PartyInfo(url, recipients, parties);
byte[] payload = new byte[] {};
when(partyInfoParser.from(payload)).thenReturn(partyInfo);
when(enclave.defaultPublicKey()).thenReturn(PublicKey.from("defaultKey".getBytes()));
EncodedPayload encodedPayload = mock(EncodedPayload.class);
List<String> uuidList = new ArrayList<>();
doAnswer((invocation) -> {
byte[] d = invocation.getArgument(0);
uuidList.add(new String(d));
return encodedPayload;
}).when(enclave).encryptPayload(any(byte[].class), any(PublicKey.class), anyList(), any(PrivacyMetadata.class));
when(payloadEncoder.encode(any(EncodedPayload.class))).thenReturn("somedata".getBytes());
WebTarget webTarget = mock(WebTarget.class);
when(restClient.target(url)).thenReturn(webTarget);
when(webTarget.path(anyString())).thenReturn(webTarget);
Invocation.Builder invocationBuilder = mock(Invocation.Builder.class);
when(webTarget.request()).thenReturn(invocationBuilder);
Response response = mock(Response.class);
when(invocationBuilder.post(any(Entity.class))).thenReturn(response);
when(response.getStatus()).thenReturn(200);
when(response.getEntity()).thenReturn("");
doAnswer(new Answer() {
private int i = 0;
public Object answer(InvocationOnMock invocation) {
String result = uuidList.get(i);
i++;
return result;
}
}).when(response).readEntity(String.class);
// the test
partyInfoResource.partyInfo(payload, null);
ArgumentCaptor<byte[]> uuidCaptor = ArgumentCaptor.forClass(byte[].class);
verify(enclave, times(2)).encryptPayload(uuidCaptor.capture(), any(PublicKey.class), anyList(), any(PrivacyMetadata.class));
List<byte[]> capturedUUIDs = uuidCaptor.getAllValues();
assertThat(capturedUUIDs).hasSize(2);
assertThat(capturedUUIDs.get(0)).isNotEqualTo(capturedUUIDs.get(1));
// other verifications
verify(discovery).onUpdate(any(NodeInfo.class));
verify(partyInfoParser).from(payload);
verify(enclave).defaultPublicKey();
verify(payloadEncoder, times(2)).encode(encodedPayload);
verify(restClient, times(2)).target(url);
}
Aggregations