Skip to content

Commit

Permalink
GH-1457: Add Optional Endpoint Name support.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Oct 3, 2024
1 parent a878c18 commit 8e5e952
Show file tree
Hide file tree
Showing 50 changed files with 1,105 additions and 191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import org.eclipse.leshan.core.ResponseCode;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.link.LinkParseException;
import org.eclipse.leshan.core.request.ReadRequest;
import org.eclipse.leshan.core.request.exception.RequestCanceledException;
import org.eclipse.leshan.core.response.ErrorCallback;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.integration.tests.util.Failure;
import org.eclipse.leshan.integration.tests.util.LeshanTestClient;
import org.eclipse.leshan.integration.tests.util.LeshanTestClientBuilder;
import org.eclipse.leshan.integration.tests.util.LeshanTestServer;
Expand Down Expand Up @@ -289,4 +291,22 @@ public void register_with_additional_attributes(Protocol protocol, String client
assertThat(registration.getAdditionalRegistrationAttributes())
.containsExactlyEntriesOf(expectedAdditionalAttributes);
}

@TestAllTransportLayer
public void register_without_sending_endpoint(Protocol protocol, String clientEndpointProvider,
String serverEndpointProvider) throws InterruptedException, LinkParseException {

client = givenClient.dontSendEndpointName().build();

// Check client is not registered
assertThat(client).isNotRegisteredAt(server);

// Start it and wait for registration failure
client.start();
Failure failure = client.waitForRegistrationFailureTo(server);
assertThat(failure).failedWith(ResponseCode.FORBIDDEN);

// Check we are registered with the expected attributes
assertThat(client).isNotRegisteredAt(server);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.util.TestLwM2mId;
import org.eclipse.leshan.integration.tests.util.BootstrapRequestChecker;
import org.eclipse.leshan.integration.tests.util.Failure;
import org.eclipse.leshan.integration.tests.util.LeshanTestBootstrapServer;
import org.eclipse.leshan.integration.tests.util.LeshanTestBootstrapServerBuilder;
import org.eclipse.leshan.integration.tests.util.LeshanTestClient;
Expand Down Expand Up @@ -157,6 +158,29 @@ public void bootstrap(Protocol givenProtocol, String givenClientEndpointProvider
assertThat(client).isRegisteredAt(server);
}

@TestAllTransportLayer
public void bootstrap_without_endpoint_name(Protocol givenProtocol, String givenClientEndpointProvider,
String givenServerEndpointProvider, String givenBootstrapServerEndpointProvider)
throws InvalidConfigurationException {
// Create and start bootstrap server
bootstrapServer = givenBootstrapServer.build();
bootstrapServer.start();

// Create Client and check it is not already registered
client = givenClient.connectingTo(bootstrapServer).dontSendEndpointName().build();

// Add config for this client
bootstrapServer.getConfigStore().add(client.getEndpointName(), //
givenBootstrapConfig() //
.adding(givenProtocol, bootstrapServer) //
.build());

// Start it and wait for registration
client.start();
Failure cause = client.waitForBootstrapFailure(bootstrapServer, 2, TimeUnit.SECONDS);
assertThat(cause).failedWith(ResponseCode.BAD_REQUEST);
}

@TestAllTransportLayer
public void bootstrap_tlv_only(Protocol givenProtocol, String givenClientEndpointProvider,
String givenServerEndpointProvider, String givenBootstrapServerEndpointProvider)
Expand Down Expand Up @@ -501,8 +525,8 @@ public void bootstrap_create_2_bsserver(Protocol givenProtocol, String givenClie
client.start();

// ensure bootstrap session failed because of invalid state
Exception cause = client.waitForBootstrapFailure(bootstrapServer, 2, TimeUnit.SECONDS);
assertThat(cause).isExactlyInstanceOf(InvalidStateException.class);
Failure cause = client.waitForBootstrapFailure(bootstrapServer, 2, TimeUnit.SECONDS);
assertThat(cause).failedWith(InvalidStateException.class);
BootstrapFailureCause failure = bootstrapServer.waitForBootstrapFailure(1, TimeUnit.SECONDS);
assertThat(failure).isEqualTo(BootstrapFailureCause.FINISH_FAILED);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@

import org.eclipse.leshan.bsserver.InvalidConfigurationException;
import org.eclipse.leshan.core.CertificateUsage;
import org.eclipse.leshan.core.ResponseCode;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.integration.tests.util.Credentials;
import org.eclipse.leshan.integration.tests.util.Failure;
import org.eclipse.leshan.integration.tests.util.LeshanTestBootstrapServer;
import org.eclipse.leshan.integration.tests.util.LeshanTestBootstrapServerBuilder;
import org.eclipse.leshan.integration.tests.util.LeshanTestClient;
Expand Down Expand Up @@ -118,6 +120,41 @@ public void bootstrap_using_psk() throws NonUniqueSecurityInfoException, Invalid
assertThat(client).isRegisteredAt(server);
}

@Test
public void bootstrap_using_psk_without_endpointname()
throws NonUniqueSecurityInfoException, InvalidConfigurationException {
// Create DM Server without security & start it
server = givenServer.using(Protocol.COAP).build();
server.start();

// Create and start bootstrap server
bootstrapServer = givenBootstrapServer.using(Protocol.COAPS).build();
bootstrapServer.start();

// Create Client and check it is not already registered
client = givenClient.connectingTo(bootstrapServer).named(GOOD_PSK_ID).sendEndpointNameIfNecessary()
.using(Protocol.COAPS).usingPsk(GOOD_PSK_ID, GOOD_PSK_KEY).build();
assertThat(client).isNotRegisteredAt(server);

// Add client credentials to the server
bootstrapServer.getEditableSecurityStore()
.add(SecurityInfo.newPreSharedKeyInfo(client.getEndpointName(), GOOD_PSK_ID, GOOD_PSK_KEY));

// Add config for this client
bootstrapServer.getConfigStore().add(client.getEndpointName(), //
givenBootstrapConfig() //
.adding(Protocol.COAPS, bootstrapServer, GOOD_PSK_ID, GOOD_PSK_KEY) //
.adding(Protocol.COAP, server) //
.build());

// Start it and wait for registration
client.start();
server.waitForNewRegistrationOf(client);

// check the client is registered
assertThat(client).isRegisteredAt(server);
}

@Test
public void bootstrap_failed_using_bad_psk() throws InvalidConfigurationException, NonUniqueSecurityInfoException {
// Create DM Server without security & start it
Expand Down Expand Up @@ -185,6 +222,42 @@ public void bootstrap_using_rpk() throws NonUniqueSecurityInfoException, Invalid
assertThat(client).isRegisteredAt(server);
}

@Test
public void bootstrap_using_rpk_without_endpoint()
throws NonUniqueSecurityInfoException, InvalidConfigurationException {
// Create DM Server without security & start it
server = givenServer.using(Protocol.COAP).build();
server.start();

// Create and start bootstrap server
bootstrapServer = givenBootstrapServer.using(Protocol.COAPS).using(serverPublicKey, serverPrivateKey).build();
bootstrapServer.start();

// Create Client and check it is not already registered
client = givenClient.connectingTo(bootstrapServer).using(Protocol.COAPS) //
.dontSendEndpointName()//
.using(clientPublicKey, clientPrivateKey)//
.trusting(serverPublicKey).build();

assertThat(client).isNotRegisteredAt(server);

// Add client credentials to the server
bootstrapServer.getEditableSecurityStore()
.add(SecurityInfo.newRawPublicKeyInfo(client.getEndpointName(), clientPublicKey));

// Add config for this client
bootstrapServer.getConfigStore().add(client.getEndpointName(), //
givenBootstrapConfig() //
.adding(Protocol.COAPS, bootstrapServer, clientPublicKey, clientPrivateKey, serverPublicKey) //
.adding(Protocol.COAP, server) //
.build());

// Start it and wait for registration
client.start();
Failure cause = client.waitForBootstrapFailure(bootstrapServer, 2, TimeUnit.SECONDS);
assertThat(cause).failedWith(ResponseCode.BAD_REQUEST);
}

@Test
public void bootstrap_using_x509()
throws NonUniqueSecurityInfoException, InvalidConfigurationException, CertificateEncodingException {
Expand Down Expand Up @@ -225,6 +298,47 @@ public void bootstrap_using_x509()
assertThat(client).isRegisteredAt(server);
}

@Test
public void bootstrap_using_x509_without_endpoint()
throws NonUniqueSecurityInfoException, InvalidConfigurationException, CertificateEncodingException {

// Create DM Server without security & start it
server = givenServer.using(Protocol.COAP).build();
server.start();

// Create and start bootstrap server
bootstrapServer = givenBootstrapServer.using(Protocol.COAPS)
.using(serverX509CertSignedByRoot, serverPrivateKeyFromCert)//
.trusting(trustedCertificatesByServer).build();
bootstrapServer.start();

// Create Client and check it is not already registered
client = givenClient.connectingTo(bootstrapServer).using(Protocol.COAPS) //
.sendEndpointNameIfNecessary() // by default LeshanClientTest is using CN of certificate
.using(clientX509CertSignedByRoot, clientPrivateKeyFromCert)//
.trusting(serverX509CertSignedByRoot).build();

assertThat(client).isNotRegisteredAt(server);

// Add client credentials to the server
bootstrapServer.getEditableSecurityStore().add(SecurityInfo.newX509CertInfo(client.getEndpointName()));

// Add config for this client
bootstrapServer.getConfigStore().add(client.getEndpointName(), //
givenBootstrapConfig() //
.adding(Protocol.COAPS, bootstrapServer, clientX509CertSignedByRoot, clientPrivateKeyFromCert,
serverX509CertSignedByRoot) //
.adding(Protocol.COAP, server) //
.build());

// Start it and wait for registration
client.start();
server.waitForNewRegistrationOf(client);

// check the client is registered
assertThat(client).isRegisteredAt(server);
}

@Test
public void bootstrap_using_x509_with_sni()
throws NonUniqueSecurityInfoException, InvalidConfigurationException, CertificateEncodingException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,42 @@ public void bootstrapViaOscoreToUnsecuredServer()
// check the client is registered
assertThat(client).isRegisteredAt(server);
}

@Test
public void bootstrap_via_oscore_to_unsecured_server_without_endpoint()
throws OSException, NonUniqueSecurityInfoException, InvalidConfigurationException {
// Create DM Server without security & start it
server = givenServer.build();
server.start();

// Create and start bootstrap server
bootstrapServer = givenBootstrapServer.with(new InMemorySecurityStore()).build();
bootstrapServer.start();

// Create Client and check it is not already registered
client = givenClient.connectingTo(bootstrapServer) //
.named(new String(getClientOscoreSetting().getSenderId())) //
.sendEndpointNameIfNecessary() //
.using(getBootstrapClientOscoreSetting()).build();
assertThat(client).isNotRegisteredAt(server);

// Add client credentials to the Bootstrap server
bootstrapServer.getEditableSecurityStore()
.add(SecurityInfo.newOscoreInfo(client.getEndpointName(), getBootstrapServerOscoreSetting()));

// Add config for this client
bootstrapServer.getConfigStore().add(client.getEndpointName(), //
givenBootstrapConfig() //
.adding(Protocol.COAP, bootstrapServer,
getOscoreBootstrapObject(getBootstrapClientOscoreSetting())) //
.adding(Protocol.COAP, server) //
.build());

// Start it and wait for registration
client.start();
server.waitForNewRegistrationOf(client);

// check the client is registered
assertThat(client).isRegisteredAt(server);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,34 @@ public void registered_device_with_oscore_to_server_with_oscore()
assertThat(response.isSuccess()).isTrue();
}

@Test
public void registered_device_with_oscore_to_server_with_oscore_without_endpoint_name()
throws NonUniqueSecurityInfoException, InterruptedException {
// Create OSCORE Client
client = givenClient.connectingTo(server) //
.named(new String(getClientOscoreSetting().getSenderId())) //
.dontSendEndpointName() //
.using(getClientOscoreSetting()).build();

// Add client credentials to the server
server.getSecurityStore().add(SecurityInfo.newOscoreInfo(client.getEndpointName(), getServerOscoreSetting()));

// Check client is not registered
assertThat(client).isNotRegisteredAt(server);

// Start it and wait for registration
client.start();
server.waitForNewRegistrationOf(client);

// Check client is well registered
assertThat(client).isRegisteredAt(server);
Registration registration = server.getRegistrationFor(client);

// check we can send request to client.
ReadResponse response = server.send(registration, new ReadRequest(3, 0, 1), 500);
assertThat(response.isSuccess()).isTrue();
}

@Test
public void registered_device_with_oscore_to_server_with_oscore_then_removed_security_info_then_server_fails_to_send_request()
throws NonUniqueSecurityInfoException, InterruptedException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,39 @@ public void registered_device_with_psk_to_server_with_psk(Protocol givenProtocol
assertThat(response.isSuccess()).isTrue();
}

@TestAllTransportLayer
public void registered_device_with_psk_to_server_with_psk_without_endpointname(Protocol givenProtocol,
String givenClientEndpointProvider, String givenServerEndpointProvider)
throws NonUniqueSecurityInfoException, InterruptedException {

// Create PSK server & start it
server = givenServer.build(); // default server support PSK
server.start();

// Create PSK Client
client = givenClient.connectingTo(server).named(GOOD_PSK_ID).dontSendEndpointName()
.usingPsk(GOOD_PSK_ID, GOOD_PSK_KEY).build();

// Add client credentials to the server
server.getSecurityStore()
.add(SecurityInfo.newPreSharedKeyInfo(client.getEndpointName(), GOOD_PSK_ID, GOOD_PSK_KEY));

// Check client is not registered
assertThat(client).isNotRegisteredAt(server);

// Start it and wait for registration
client.start();
server.waitForNewRegistrationOf(client);

// Check client is well registered
assertThat(client).isRegisteredAt(server);
Registration registration = server.getRegistrationFor(client);

// check we can send request to client.
ReadResponse response = server.send(registration, new ReadRequest(3, 0, 1), 500);
assertThat(response.isSuccess()).isTrue();
}

@TestAllTransportLayer
public void register_update_deregister_reregister_device_with_psk_to_server_with_psk(Protocol givenProtocol,
String givenClientEndpointProvider, String givenServerEndpointProvider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import org.eclipse.leshan.core.ResponseCode;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.request.ReadRequest;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.integration.tests.util.Failure;
import org.eclipse.leshan.integration.tests.util.LeshanTestClient;
import org.eclipse.leshan.integration.tests.util.LeshanTestClientBuilder;
import org.eclipse.leshan.integration.tests.util.LeshanTestServer;
Expand Down Expand Up @@ -128,6 +130,36 @@ public void registered_device_with_rpk_to_server_with_rpk(Protocol givenProtocol
assertThat(response.isSuccess()).isTrue();
}

@TestAllTransportLayer
public void registered_device_with_rpk_to_server_with_rpk_without_endpointname(Protocol givenProtocol,
String givenClientEndpointProvider, String givenServerEndpointProvider)
throws NonUniqueSecurityInfoException, InterruptedException {
// Create RPK server & start it
server = givenServer.using(serverPublicKey, serverPrivateKey).build();
server.start();

// Create RPK Client
client = givenClient.connectingTo(server) //
.using(clientPublicKey, clientPrivateKey)//
.trusting(serverPublicKey)//
.dontSendEndpointName() //
.build();

// Add client credentials to the server
server.getSecurityStore().add(SecurityInfo.newRawPublicKeyInfo(client.getEndpointName(), clientPublicKey));

// Check client is not registered
assertThat(client).isNotRegisteredAt(server);

// Start it and wait for registration
client.start();
Failure failure = client.waitForRegistrationFailureTo(server);
assertThat(failure).failedWith(ResponseCode.FORBIDDEN);

// Check we are registered with the expected attributes
assertThat(client).isNotRegisteredAt(server);
}

@TestAllTransportLayer
public void registered_device_with_bad_rpk_to_server_with_rpk(Protocol givenProtocol,
String givenClientEndpointProvider, String givenServerEndpointProvider)
Expand Down
Loading

0 comments on commit 8e5e952

Please sign in to comment.