Skip to content

Commit

Permalink
SecurityTest: Add certificate usage unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Vesa Jääskeläinen <[email protected]>
Also-by : Simon Bernard <[email protected]>
  • Loading branch information
dachaac authored and sbernard31 committed Nov 19, 2020
1 parent 3e65c99 commit 0fa454c
Show file tree
Hide file tree
Showing 3 changed files with 981 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorResult;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -122,4 +125,21 @@ public static boolean contains(X509Certificate certificate, X509Certificate[] ce
}
return false;
}

/**
* Convert array of {@link Certificate} to array of {@link X509Certificate}
*/
public static X509Certificate[] asX509Certificates(Certificate[] certificates) throws CertificateException {
ArrayList<X509Certificate> x509Certificates = new ArrayList<>();

for (Certificate cert : certificates) {
if (!(cert instanceof X509Certificate)) {
throw new CertificateException(String.format(
"%s certificate format is not supported, Only X.509 certificate is supported", cert.getType()));
}
x509Certificates.add((X509Certificate) cert);
}

return x509Certificates.toArray(new X509Certificate[0]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.crypto.SecretKey;
Expand All @@ -53,13 +55,15 @@
import org.eclipse.californium.scandium.dtls.cipher.CipherSuite;
import org.eclipse.californium.scandium.dtls.pskstore.AdvancedPskStore;
import org.eclipse.leshan.client.californium.LeshanClientBuilder;
import org.eclipse.leshan.client.californium.X509Util;
import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory;
import org.eclipse.leshan.client.object.Device;
import org.eclipse.leshan.client.object.Security;
import org.eclipse.leshan.client.object.Server;
import org.eclipse.leshan.client.resource.DummyInstanceEnabler;
import org.eclipse.leshan.client.resource.LwM2mObjectEnabler;
import org.eclipse.leshan.client.resource.ObjectsInitializer;
import org.eclipse.leshan.core.CertificateUsage;
import org.eclipse.leshan.core.LwM2mId;
import org.eclipse.leshan.core.californium.EndpointFactory;
import org.eclipse.leshan.core.util.Hex;
Expand Down Expand Up @@ -89,8 +93,12 @@ public class SecureIntegrationTestHelper extends IntegrationTestHelper {

// client private key used for X509
public final PrivateKey clientPrivateKeyFromCert;
// mfg client private key used for X509
public final PrivateKey mfgClientPrivateKeyFromCert;
// server private key used for X509
public final PrivateKey serverPrivateKeyFromCert;
// server private key used for X509
public final PrivateKey serverIntPrivateKeyFromCert;
// client certificate signed by rootCA with a good CN (CN start by leshan_integration_test)
public final X509Certificate clientX509Cert;
// client certificate signed by rootCA but with bad CN (CN does not start by leshan_integration_test)
Expand All @@ -99,14 +107,25 @@ public class SecureIntegrationTestHelper extends IntegrationTestHelper {
public final X509Certificate clientX509CertSelfSigned;
// client certificate signed by another CA (not rootCA) with a good CN (CN start by leshan_integration_test)
public final X509Certificate clientX509CertNotTrusted;
// client certificate signed by manufacturer CA's with a good CN
// (CN=urn:dev:ops:32473-IoT_Device-K1234567,O=Manufacturer)
public final X509Certificate[] mfgClientX509CertChain;
// server certificate signed by rootCA
public final X509Certificate serverX509Cert;
// server certificate signed by intermediateCA
public final X509Certificate[] serverIntX509CertChain;
// self-signed server certificate
public final X509Certificate serverX509CertSelfSigned;
// self-signed server certificate
public final X509Certificate serverIntX509CertSelfSigned;
// rootCA used by the server
public final X509Certificate rootCAX509Cert;
// certificates trustedby the server (should contain rootCA)
public final Certificate[] trustedCertificates = new Certificate[1];
// client's initial trust store
public final List<Certificate> clientTrustStore;
// client's initial empty trust store
public final List<Certificate> clientEmptyTrustStore = new ArrayList<>();

public SecureIntegrationTestHelper() {
// create client credentials
Expand Down Expand Up @@ -145,6 +164,9 @@ public SecureIntegrationTestHelper() {
clientX509CertWithBadCN = (X509Certificate) clientKeyStore.getCertificate("client_bad_cn");
clientX509CertSelfSigned = (X509Certificate) clientKeyStore.getCertificate("client_self_signed");
clientX509CertNotTrusted = (X509Certificate) clientKeyStore.getCertificate("client_not_trusted");

mfgClientPrivateKeyFromCert = (PrivateKey) clientKeyStore.getKey("mfgClient", clientKeyStorePwd);
mfgClientX509CertChain = X509Util.asX509Certificates(clientKeyStore.getCertificateChain("mfgClient"));
} catch (GeneralSecurityException | IOException e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -181,11 +203,14 @@ public SecureIntegrationTestHelper() {
}

serverPrivateKeyFromCert = (PrivateKey) serverKeyStore.getKey("server", serverKeyStorePwd);
serverIntPrivateKeyFromCert = (PrivateKey) serverKeyStore.getKey("serverint", serverKeyStorePwd);
rootCAX509Cert = (X509Certificate) serverKeyStore.getCertificate("rootCA");
serverX509Cert = (X509Certificate) serverKeyStore.getCertificate("server");
serverX509CertSelfSigned = (X509Certificate) serverKeyStore.getCertificate("server_self_signed");
serverIntX509CertSelfSigned = (X509Certificate) serverKeyStore.getCertificate("serverInt_self_signed");
serverIntX509CertChain = X509Util.asX509Certificates(serverKeyStore.getCertificateChain("serverint"));
trustedCertificates[0] = rootCAX509Cert;

clientTrustStore = Arrays.asList(new Certificate[] { rootCAX509Cert });
} catch (GeneralSecurityException | IOException e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -333,6 +358,38 @@ public void createX509CertClient(Certificate clientCertificate, PrivateKey priva
setupClientMonitoring();
}

public void createX509CertClient(X509Certificate[] clientCertificate, PrivateKey privatekey,
List<Certificate> clientTrustStore, X509Certificate serverCertificate, CertificateUsage certificateUsage)
throws CertificateEncodingException {
/* Make sure there is only 1 certificate in chain before client certificate chains are supported */
assert (clientCertificate.length == 1);

ObjectsInitializer initializer = new ObjectsInitializer();
initializer.setInstancesForObject(LwM2mId.SECURITY,
Security.x509(
"coaps://" + server.getSecuredAddress().getHostString() + ":"
+ server.getSecuredAddress().getPort(),
12345, clientCertificate[0].getEncoded(), privatekey.getEncoded(),
serverCertificate.getEncoded(), certificateUsage.code));
initializer.setInstancesForObject(LwM2mId.SERVER, new Server(12345, LIFETIME));
initializer.setInstancesForObject(LwM2mId.DEVICE, new Device("Eclipse Leshan", MODEL_NUMBER, "12345"));
initializer.setClassForObject(LwM2mId.ACCESS_CONTROL, DummyInstanceEnabler.class);
List<LwM2mObjectEnabler> objects = initializer.createAll();

InetSocketAddress clientAddress = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
LeshanClientBuilder builder = new LeshanClientBuilder(getCurrentEndpoint());
builder.setLocalAddress(clientAddress.getHostString(), clientAddress.getPort());
builder.setTrustStore(clientTrustStore);

Builder dtlsConfig = new DtlsConnectorConfig.Builder();
dtlsConfig.setClientOnly();
builder.setDtlsConfig(dtlsConfig);

builder.setObjects(objects);
client = builder.build();
setupClientMonitoring();
}

@Override
protected LeshanServerBuilder createServerBuilder() {
return createServerBuilder(null);
Expand Down Expand Up @@ -367,9 +424,19 @@ public void createServerWithX509Cert() {
}

public void createServerWithX509Cert(X509Certificate serverCertificate, PrivateKey privateKey, Boolean serverOnly) {
createServerWithX509Cert(new X509Certificate[] { serverCertificate }, privateKey, serverOnly);
}

public void createServerWithX509Cert(X509Certificate serverCertificateChain[], PrivateKey privateKey,
Boolean serverOnly) {
createServerWithX509Cert(serverCertificateChain, privateKey, this.trustedCertificates, serverOnly);
}

public void createServerWithX509Cert(X509Certificate serverCertificateChain[], PrivateKey privateKey,
Certificate[] trustedCertificates, Boolean serverOnly) {
LeshanServerBuilder builder = createServerBuilder(serverOnly);
builder.setPrivateKey(privateKey);
builder.setCertificateChain(new X509Certificate[] { serverCertificate });
builder.setCertificateChain(serverCertificateChain);
builder.setTrustedCertificates(trustedCertificates);
builder.setAuthorizer(new DefaultAuthorizer(securityStore, new SecurityChecker() {
@Override
Expand Down
Loading

0 comments on commit 0fa454c

Please sign in to comment.