Skip to content

Commit 9feae9e

Browse files
committed
Refactoring: Move CertificateVerifier from cf to core module.
So it can be reused by other transport layer.
1 parent 35cbd1e commit 9feae9e

File tree

12 files changed

+384
-256
lines changed

12 files changed

+384
-256
lines changed

leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/BaseCertificateVerifier.java

-122
This file was deleted.

leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coaps/CoapsClientEndpointFactory.java

+7-58
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,18 @@
5555
import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier;
5656
import org.eclipse.californium.scandium.dtls.x509.SingleCertificateProvider;
5757
import org.eclipse.californium.scandium.dtls.x509.StaticNewAdvancedCertificateVerifier;
58-
import org.eclipse.leshan.client.californium.CaConstraintCertificateVerifier;
5958
import org.eclipse.leshan.client.californium.CaliforniumConnectionController;
60-
import org.eclipse.leshan.client.californium.DomainIssuerCertificateVerifier;
61-
import org.eclipse.leshan.client.californium.ServiceCertificateConstraintCertificateVerifier;
62-
import org.eclipse.leshan.client.californium.TrustAnchorAssertionCertificateVerifier;
6359
import org.eclipse.leshan.client.californium.endpoint.coap.CoapClientEndpointFactory;
6460
import org.eclipse.leshan.client.endpoint.ClientEndpointToolbox;
61+
import org.eclipse.leshan.client.security.CertificateVerifierFactory;
6562
import org.eclipse.leshan.client.servers.LwM2mServer;
6663
import org.eclipse.leshan.client.servers.ServerInfo;
67-
import org.eclipse.leshan.core.CertificateUsage;
6864
import org.eclipse.leshan.core.SecurityMode;
6965
import org.eclipse.leshan.core.californium.DefaultExceptionTranslator;
7066
import org.eclipse.leshan.core.californium.ExceptionTranslator;
7167
import org.eclipse.leshan.core.californium.Lwm2mEndpointContextMatcher;
7268
import org.eclipse.leshan.core.californium.identity.IdentityHandler;
69+
import org.eclipse.leshan.core.californium.security.LwM2mCertificateVerifier;
7370
import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
7471
import org.eclipse.leshan.core.endpoint.Protocol;
7572
import org.eclipse.leshan.core.peer.IpPeer;
@@ -80,6 +77,7 @@
8077
import org.eclipse.leshan.core.request.exception.TimeoutException;
8178
import org.eclipse.leshan.core.request.exception.TimeoutException.Type;
8279
import org.eclipse.leshan.core.security.certificate.util.X509CertUtil;
80+
import org.eclipse.leshan.core.security.certificate.verifier.X509CertificateVerifier;
8381
import org.slf4j.Logger;
8482
import org.slf4j.LoggerFactory;
8583

@@ -88,6 +86,7 @@ public class CoapsClientEndpointFactory extends CoapClientEndpointFactory {
8886
private static final Logger LOG = LoggerFactory.getLogger(CoapsClientEndpointFactory.class);
8987

9088
protected final String loggingTagPrefix;
89+
protected final CertificateVerifierFactory certificateVerifierFactory = new CertificateVerifierFactory();
9190

9291
public CoapsClientEndpointFactory() {
9392
this("LWM2M Client");
@@ -184,59 +183,9 @@ protected DtlsConnectorConfig.Builder createEffectiveDtlsConnectorConfigBuilder(
184183
singleCertificateProvider.setVerifyKeyPair(false);
185184
effectiveBuilder.setCertificateIdentityProvider(singleCertificateProvider);
186185

187-
// LWM2M v1.1.1 - 5.2.8.7. Certificate Usage Field
188-
//
189-
// 0: Certificate usage 0 ("CA constraint")
190-
// - trustStore is client's configured trust store
191-
// - must do PKIX validation with trustStore to build certPath
192-
// - must check that given certificate is part of certPath
193-
// - validate server name
194-
//
195-
// 1: Certificate usage 1 ("service certificate constraint")
196-
// - trustStore is client's configured trust store
197-
// - must do PKIX validation with trustStore
198-
// - target certificate must match what is provided certificate in server info
199-
// - validate server name
200-
//
201-
// 2: Certificate usage 2 ("trust anchor assertion")
202-
// - trustStore is only the provided certificate in server info
203-
// - must do PKIX validation with trustStore
204-
// - validate server name
205-
//
206-
// 3: Certificate usage 3 ("domain-issued certificate") (default mode if missing)
207-
// - no trustStore used in this mode
208-
// - target certificate must match what is provided certificate in server info
209-
// - validate server name
210-
211-
CertificateUsage certificateUsage = serverInfo.certificateUsage != null ? serverInfo.certificateUsage
212-
: CertificateUsage.DOMAIN_ISSUER_CERTIFICATE;
213-
214-
if (certificateUsage == CertificateUsage.CA_CONSTRAINT) {
215-
X509Certificate[] trustedCertificates = null;
216-
if (trustStore != null) {
217-
trustedCertificates = CertPathUtil.toX509CertificatesList(trustStore)
218-
.toArray(new X509Certificate[trustStore.size()]);
219-
}
220-
effectiveBuilder.setAdvancedCertificateVerifier(new CaConstraintCertificateVerifier(
221-
serverInfo.serverCertificate, trustedCertificates, serverInfo.sni));
222-
} else if (certificateUsage == CertificateUsage.SERVICE_CERTIFICATE_CONSTRAINT) {
223-
X509Certificate[] trustedCertificates = null;
224-
225-
// - trustStore is client's configured trust store
226-
if (trustStore != null) {
227-
trustedCertificates = CertPathUtil.toX509CertificatesList(trustStore)
228-
.toArray(new X509Certificate[trustStore.size()]);
229-
}
230-
231-
effectiveBuilder.setAdvancedCertificateVerifier(new ServiceCertificateConstraintCertificateVerifier(
232-
serverInfo.serverCertificate, trustedCertificates, serverInfo.sni));
233-
} else if (certificateUsage == CertificateUsage.TRUST_ANCHOR_ASSERTION) {
234-
effectiveBuilder.setAdvancedCertificateVerifier(new TrustAnchorAssertionCertificateVerifier(
235-
(X509Certificate) serverInfo.serverCertificate, serverInfo.sni));
236-
} else if (certificateUsage == CertificateUsage.DOMAIN_ISSUER_CERTIFICATE) {
237-
effectiveBuilder.setAdvancedCertificateVerifier(
238-
new DomainIssuerCertificateVerifier(serverInfo.serverCertificate));
239-
}
186+
// set certificate verifier
187+
X509CertificateVerifier certificateVerifier = certificateVerifierFactory.create(serverInfo, trustStore);
188+
effectiveBuilder.setAdvancedCertificateVerifier(new LwM2mCertificateVerifier(certificateVerifier));
240189

241190
// TODO We set CN with '*' as we are not able to know the CN for some certificate usage and so this is
242191
// not used anymore to identify a server with x509.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Sierra Wireless and others.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License v2.0
6+
* and Eclipse Distribution License v1.0 which accompany this distribution.
7+
*
8+
* The Eclipse Public License is available at
9+
* http://www.eclipse.org/legal/epl-v20.html
10+
* and the Eclipse Distribution License is available at
11+
* http://www.eclipse.org/org/documents/edl-v10.html.
12+
*
13+
* Contributors:
14+
* Sierra Wireless - initial API and implementation
15+
*******************************************************************************/
16+
package org.eclipse.leshan.client.security;
17+
18+
import java.security.cert.Certificate;
19+
import java.security.cert.X509Certificate;
20+
import java.util.List;
21+
22+
import org.eclipse.leshan.client.servers.ServerInfo;
23+
import org.eclipse.leshan.core.CertificateUsage;
24+
import org.eclipse.leshan.core.security.certificate.util.X509CertUtil;
25+
import org.eclipse.leshan.core.security.certificate.verifier.CaConstraintCertificateVerifier;
26+
import org.eclipse.leshan.core.security.certificate.verifier.DomainIssuerCertificateVerifier;
27+
import org.eclipse.leshan.core.security.certificate.verifier.ServiceCertificateConstraintCertificateVerifier;
28+
import org.eclipse.leshan.core.security.certificate.verifier.TrustAnchorAssertionCertificateVerifier;
29+
import org.eclipse.leshan.core.security.certificate.verifier.X509CertificateVerifier;
30+
31+
/**
32+
* Create {@link X509CertificateVerifier} from {@link ServerInfo} and a list of trusted {@link Certificate}.
33+
*/
34+
public class CertificateVerifierFactory {
35+
36+
public X509CertificateVerifier create(ServerInfo serverInfo, List<Certificate> trustStore) {
37+
38+
// LWM2M v1.1.1 - 5.2.8.7. Certificate Usage Field
39+
//
40+
// 0: Certificate usage 0 ("CA constraint")
41+
// - trustStore is client's configured trust store
42+
// - must do PKIX validation with trustStore to build certPath
43+
// - must check that given certificate is part of certPath
44+
// - validate server name
45+
//
46+
// 1: Certificate usage 1 ("service certificate constraint")
47+
// - trustStore is client's configured trust store
48+
// - must do PKIX validation with trustStore
49+
// - target certificate must match what is provided certificate in server info
50+
// - validate server name
51+
//
52+
// 2: Certificate usage 2 ("trust anchor assertion")
53+
// - trustStore is only the provided certificate in server info
54+
// - must do PKIX validation with trustStore
55+
// - validate server name
56+
//
57+
// 3: Certificate usage 3 ("domain-issued certificate") (default mode if missing)
58+
// - no trustStore used in this mode
59+
// - target certificate must match what is provided certificate in server info
60+
// - validate server name
61+
62+
CertificateUsage certificateUsage = serverInfo.certificateUsage != null ? serverInfo.certificateUsage
63+
: CertificateUsage.DOMAIN_ISSUER_CERTIFICATE;
64+
65+
if (certificateUsage == CertificateUsage.CA_CONSTRAINT) {
66+
X509Certificate[] trustedCertificates = null;
67+
if (trustStore != null) {
68+
trustedCertificates = X509CertUtil.toX509CertificatesList(trustStore)
69+
.toArray(new X509Certificate[trustStore.size()]);
70+
}
71+
return new CaConstraintCertificateVerifier(serverInfo.serverCertificate, trustedCertificates,
72+
serverInfo.sni);
73+
} else if (certificateUsage == CertificateUsage.SERVICE_CERTIFICATE_CONSTRAINT) {
74+
X509Certificate[] trustedCertificates = null;
75+
76+
// - trustStore is client's configured trust store
77+
if (trustStore != null) {
78+
trustedCertificates = X509CertUtil.toX509CertificatesList(trustStore)
79+
.toArray(new X509Certificate[trustStore.size()]);
80+
}
81+
82+
return new ServiceCertificateConstraintCertificateVerifier(serverInfo.serverCertificate,
83+
trustedCertificates, serverInfo.sni);
84+
} else if (certificateUsage == CertificateUsage.TRUST_ANCHOR_ASSERTION) {
85+
return new TrustAnchorAssertionCertificateVerifier((X509Certificate) serverInfo.serverCertificate,
86+
serverInfo.sni);
87+
} else if (certificateUsage == CertificateUsage.DOMAIN_ISSUER_CERTIFICATE) {
88+
return new DomainIssuerCertificateVerifier(serverInfo.serverCertificate);
89+
}
90+
throw new IllegalStateException(String.format("Unsupported Certificate Usage %s", certificateUsage));
91+
}
92+
}

0 commit comments

Comments
 (0)