Improvements to key store read for lwm2m.
This commit is contained in:
		
							parent
							
								
									f58fe1647b
								
							
						
					
					
						commit
						ee55c0bf85
					
				@ -30,8 +30,12 @@ import java.math.BigInteger;
 | 
			
		||||
import java.security.AlgorithmParameters;
 | 
			
		||||
import java.security.GeneralSecurityException;
 | 
			
		||||
import java.security.KeyFactory;
 | 
			
		||||
import java.security.KeyStore;
 | 
			
		||||
import java.security.KeyStoreException;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.security.PrivateKey;
 | 
			
		||||
import java.security.PublicKey;
 | 
			
		||||
import java.security.UnrecoverableKeyException;
 | 
			
		||||
import java.security.cert.CertificateEncodingException;
 | 
			
		||||
import java.security.cert.X509Certificate;
 | 
			
		||||
import java.security.spec.ECGenParameterSpec;
 | 
			
		||||
@ -62,49 +66,23 @@ public class LwM2MServerSecurityInfoRepository {
 | 
			
		||||
        bsServ.setPort(serverConfig.getPort());
 | 
			
		||||
        bsServ.setSecurityHost(serverConfig.getSecureHost());
 | 
			
		||||
        bsServ.setSecurityPort(serverConfig.getSecurePort());
 | 
			
		||||
        bsServ.setServerPublicKey(getPublicKey(serverConfig.getCertificateAlias(), this.serverConfig.getPublicX(), this.serverConfig.getPublicY()));
 | 
			
		||||
        bsServ.setServerPublicKey(getPublicKey(serverConfig));
 | 
			
		||||
        return bsServ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getPublicKey(String alias, String publicServerX, String publicServerY) {
 | 
			
		||||
        String publicKey = getServerPublicKeyX509(alias);
 | 
			
		||||
        return publicKey != null ? publicKey : getRPKPublicKey(publicServerX, publicServerY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getServerPublicKeyX509(String alias) {
 | 
			
		||||
    private String getPublicKey(LwM2MSecureServerConfig config) {
 | 
			
		||||
        try {
 | 
			
		||||
            X509Certificate serverCertificate = (X509Certificate) serverConfig.getKeyStoreValue().getCertificate(alias);
 | 
			
		||||
            return Hex.encodeHexString(serverCertificate.getEncoded());
 | 
			
		||||
        } catch (CertificateEncodingException | KeyStoreException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getRPKPublicKey(String publicServerX, String publicServerY) {
 | 
			
		||||
        try {
 | 
			
		||||
            /** Get Elliptic Curve Parameter spec for secp256r1 */
 | 
			
		||||
            AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
 | 
			
		||||
            algoParameters.init(new ECGenParameterSpec("secp256r1"));
 | 
			
		||||
            ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
 | 
			
		||||
            if (publicServerX != null && !publicServerX.isEmpty() && publicServerY != null && !publicServerY.isEmpty()) {
 | 
			
		||||
                /** Get point values */
 | 
			
		||||
                byte[] publicX = Hex.decodeHex(publicServerX.toCharArray());
 | 
			
		||||
                byte[] publicY = Hex.decodeHex(publicServerY.toCharArray());
 | 
			
		||||
                /** Create key specs */
 | 
			
		||||
                KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
 | 
			
		||||
                        parameterSpec);
 | 
			
		||||
                /** Get keys */
 | 
			
		||||
                PublicKey publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
 | 
			
		||||
                if (publicKey != null && publicKey.getEncoded().length > 0) {
 | 
			
		||||
                    return Hex.encodeHexString(publicKey.getEncoded());
 | 
			
		||||
                }
 | 
			
		||||
            KeyStore keyStore = serverConfig.getKeyStoreValue();
 | 
			
		||||
            if (keyStore != null) {
 | 
			
		||||
                X509Certificate serverCertificate = (X509Certificate) serverConfig.getKeyStoreValue().getCertificate(config.getCertificateAlias());
 | 
			
		||||
                return Hex.encodeHexString(serverCertificate.getPublicKey().getEncoded());
 | 
			
		||||
            }
 | 
			
		||||
        } catch (GeneralSecurityException | IllegalArgumentException e) {
 | 
			
		||||
            log.error("[{}] Failed generate Server RPK for profile", e.getMessage());
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.trace("Failed to fetch public key from key store!", e);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -649,12 +649,9 @@ transport:
 | 
			
		||||
      security:
 | 
			
		||||
        bind_address: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}"
 | 
			
		||||
        bind_port: "${LWM2M_BIND_PORT_SECURITY:5686}"
 | 
			
		||||
        # Only for RPK: Public & Private Key. If the keystore file is missing or not working
 | 
			
		||||
        public_x: "${LWM2M_SERVER_PUBLIC_X:05064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f358}"
 | 
			
		||||
        public_y: "${LWM2M_SERVER_PUBLIC_Y:5eeb1838e4f9e37b31fa347aef5ce3431eb54e0a2506910c5e0298817445721b}"
 | 
			
		||||
        private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED:308193020100301306072a8648ce3d020106082a8648ce3d030107047930770201010420dc774b309e547ceb48fee547e104ce201a9c48c449dc5414cd04e7f5cf05f67ba00a06082a8648ce3d030107a1440342000405064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f3585eeb1838e4f9e37b31fa347aef5ce3431eb54e0a2506910c5e0298817445721b}"
 | 
			
		||||
        # Only Certificate_x509:
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_ALIAS_SERVER:server}"
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_SERVER_ALIAS:server}"
 | 
			
		||||
        password: "${LWM2M_KEYSTORE_SERVER_PASSWORD:server_ks_password}"
 | 
			
		||||
        skip_validity_check_for_client_cert: "${TB_LWM2M_SERVER_SECURITY_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}"
 | 
			
		||||
    bootstrap:
 | 
			
		||||
      enable: "${LWM2M_ENABLED_BS:true}"
 | 
			
		||||
@ -664,12 +661,9 @@ transport:
 | 
			
		||||
      security:
 | 
			
		||||
        bind_address: "${LWM2M_BIND_ADDRESS_SECURITY_BS:0.0.0.0}"
 | 
			
		||||
        bind_port: "${LWM2M_BIND_PORT_SECURITY_BS:5688}"
 | 
			
		||||
        #  Only for RPK: Public & Private Key. If the keystore file is missing or not working
 | 
			
		||||
        public_x: "${LWM2M_SERVER_PUBLIC_X_BS:5017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f91}"
 | 
			
		||||
        public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:3fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}"
 | 
			
		||||
        private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED_BS:308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104205ecafd90caa7be45c42e1f3f32571632b8409e6e6249d7124f4ba56fab3c8083a00a06082a8648ce3d030107a144034200045017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f913fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}"
 | 
			
		||||
        # Only Certificate_x509:
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_ALIAS_BS:bootstrap}"
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_BS_ALIAS:bootstrap}"
 | 
			
		||||
        password: "${LWM2M_KEYSTORE_BS_PASSWORD:server_ks_password}"
 | 
			
		||||
    security:
 | 
			
		||||
      # Certificate_x509:
 | 
			
		||||
      # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,7 @@
 | 
			
		||||
transport.lwm2m.security.key_store=lwm2m/credentials/serverKeyStore.jks
 | 
			
		||||
transport.lwm2m.security.key_store_password=server
 | 
			
		||||
edges.enabled=true
 | 
			
		||||
transport.lwm2m.bootstrap.security.alias=server
 | 
			
		||||
transport.lwm2m.server.security.alias=server
 | 
			
		||||
transport.lwm2m.server.security.password=server
 | 
			
		||||
transport.lwm2m.bootstrap.security.alias=server
 | 
			
		||||
transport.lwm2m.bootstrap.security.password=server
 | 
			
		||||
@ -31,6 +31,7 @@ import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBoots
 | 
			
		||||
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig;
 | 
			
		||||
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
 | 
			
		||||
import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC;
 | 
			
		||||
import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2mTransportService;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import javax.annotation.PreDestroy;
 | 
			
		||||
@ -65,10 +66,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.g
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' && '${transport.lwm2m.bootstrap.enable:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled:false}'=='true'&& '${transport.lwm2m.bootstrap.enable:false}'=='true')")
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
//TODO: @ybondarenko please refactor this to be similar to DefaultLwM2mTransportService
 | 
			
		||||
public class LwM2MTransportBootstrapService {
 | 
			
		||||
    private PublicKey publicKey;
 | 
			
		||||
    private PrivateKey privateKey;
 | 
			
		||||
    private boolean pskMode = false;
 | 
			
		||||
 | 
			
		||||
    private final LwM2MTransportServerConfig serverConfig;
 | 
			
		||||
@ -101,44 +99,34 @@ public class LwM2MTransportBootstrapService {
 | 
			
		||||
        builder.setLocalAddress(bootstrapConfig.getHost(), bootstrapConfig.getPort());
 | 
			
		||||
        builder.setLocalSecureAddress(bootstrapConfig.getSecureHost(), bootstrapConfig.getSecurePort());
 | 
			
		||||
 | 
			
		||||
        /** Create CoAP Config */
 | 
			
		||||
        /* Create CoAP Config */
 | 
			
		||||
        builder.setCoapConfig(getCoapConfig(bootstrapConfig.getPort(), bootstrapConfig.getSecurePort(), serverConfig));
 | 
			
		||||
 | 
			
		||||
        /** Define model provider (Create Models )*/
 | 
			
		||||
        /* Define model provider (Create Models )*/
 | 
			
		||||
 | 
			
		||||
        /**  Create credentials */
 | 
			
		||||
        /*  Create credentials */
 | 
			
		||||
        this.setServerWithCredentials(builder);
 | 
			
		||||
 | 
			
		||||
//        /** Set securityStore with new ConfigStore */
 | 
			
		||||
//        builder.setConfigStore(lwM2MInMemoryBootstrapConfigStore);
 | 
			
		||||
 | 
			
		||||
        /** SecurityStore */
 | 
			
		||||
        /* SecurityStore */
 | 
			
		||||
        builder.setSecurityStore(lwM2MBootstrapSecurityStore);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /** Create and Set DTLS Config */
 | 
			
		||||
        /* Create and Set DTLS Config */
 | 
			
		||||
        DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder();
 | 
			
		||||
        dtlsConfig.setRecommendedSupportedGroupsOnly(serverConfig.isRecommendedSupportedGroups());
 | 
			
		||||
        dtlsConfig.setRecommendedCipherSuitesOnly(serverConfig.isRecommendedCiphers());
 | 
			
		||||
        if (this.pskMode) {
 | 
			
		||||
            dtlsConfig.setSupportedCipherSuites(
 | 
			
		||||
                    TLS_PSK_WITH_AES_128_CCM_8,
 | 
			
		||||
                    TLS_PSK_WITH_AES_128_CBC_SHA256);
 | 
			
		||||
        } else {
 | 
			
		||||
            dtlsConfig.setSupportedCipherSuites(
 | 
			
		||||
                    TLS_PSK_WITH_AES_128_CCM_8,
 | 
			
		||||
                    TLS_PSK_WITH_AES_128_CBC_SHA256,
 | 
			
		||||
                    TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
 | 
			
		||||
                    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
 | 
			
		||||
        }
 | 
			
		||||
        dtlsConfig.setSupportedCipherSuites(this.pskMode ? DefaultLwM2mTransportService.PSK_CIPHER_SUITES : DefaultLwM2mTransportService.RPK_OR_X509_CIPHER_SUITES);
 | 
			
		||||
 | 
			
		||||
        /** Set DTLS Config */
 | 
			
		||||
        /* Set DTLS Config */
 | 
			
		||||
        builder.setDtlsConfig(dtlsConfig);
 | 
			
		||||
 | 
			
		||||
        BootstrapSessionManager sessionManager = new LwM2mDefaultBootstrapSessionManager(lwM2MBootstrapSecurityStore);
 | 
			
		||||
        builder.setSessionManager(sessionManager);
 | 
			
		||||
 | 
			
		||||
        /** Create BootstrapServer */
 | 
			
		||||
        /* Create BootstrapServer */
 | 
			
		||||
        return builder.build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -153,19 +141,15 @@ public class LwM2MTransportBootstrapService {
 | 
			
		||||
                        trustedCertificates[0] = rootCAX509Cert;
 | 
			
		||||
                        builder.setTrustedCertificates(trustedCertificates);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        /** by default trust all */
 | 
			
		||||
                        /* by default trust all */
 | 
			
		||||
                        builder.setTrustedCertificates(new X509Certificate[0]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else if (this.setServerRPK(builder)) {
 | 
			
		||||
                this.infoPramsUri("RPK");
 | 
			
		||||
                this.infoParamsBootstrapServerKey(this.publicKey, this.privateKey);
 | 
			
		||||
            } else {
 | 
			
		||||
                /** by default trust all */
 | 
			
		||||
                /* by default trust all */
 | 
			
		||||
                builder.setTrustedCertificates(new X509Certificate[0]);
 | 
			
		||||
                log.info("Unable to load X509 files for BootStrapServer");
 | 
			
		||||
                this.pskMode = true;
 | 
			
		||||
                this.infoPramsUri("PSK");
 | 
			
		||||
            }
 | 
			
		||||
        } catch (KeyStoreException ex) {
 | 
			
		||||
            log.error("[{}] Unable to load X509 files server", ex.getMessage());
 | 
			
		||||
@ -173,19 +157,14 @@ public class LwM2MTransportBootstrapService {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean setBuilderX509(LeshanBootstrapServerBuilder builder) {
 | 
			
		||||
        /**
 | 
			
		||||
         * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE
 | 
			
		||||
         * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks
 | 
			
		||||
         */
 | 
			
		||||
        try {
 | 
			
		||||
            X509Certificate serverCertificate = (X509Certificate) serverConfig.getKeyStoreValue().getCertificate(this.bootstrapConfig.getCertificateAlias());
 | 
			
		||||
            PrivateKey privateKey = (PrivateKey) serverConfig.getKeyStoreValue().getKey(this.bootstrapConfig.getCertificateAlias(), serverConfig.getKeyStorePassword() == null ? null : serverConfig.getKeyStorePassword().toCharArray());
 | 
			
		||||
            PrivateKey privateKey = (PrivateKey) serverConfig.getKeyStoreValue().getKey(this.bootstrapConfig.getCertificateAlias(), serverConfig.getCertificatePassword() == null ? null : serverConfig.getCertificatePassword().toCharArray());
 | 
			
		||||
            PublicKey publicKey = serverCertificate.getPublicKey();
 | 
			
		||||
            if (privateKey != null && privateKey.getEncoded().length > 0 && publicKey != null && publicKey.getEncoded().length > 0) {
 | 
			
		||||
                builder.setPublicKey(serverCertificate.getPublicKey());
 | 
			
		||||
                builder.setPrivateKey(privateKey);
 | 
			
		||||
                builder.setCertificateChain(new X509Certificate[]{serverCertificate});
 | 
			
		||||
                this.infoParamsServerX509(serverCertificate, publicKey, privateKey);
 | 
			
		||||
                return true;
 | 
			
		||||
            } else {
 | 
			
		||||
                return false;
 | 
			
		||||
@ -196,105 +175,4 @@ public class LwM2MTransportBootstrapService {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void infoParamsServerX509(X509Certificate certificate, PublicKey publicKey, PrivateKey privateKey) {
 | 
			
		||||
        try {
 | 
			
		||||
            this.infoPramsUri("X509");
 | 
			
		||||
            log.info("\n- X509 Certificate (Hex): [{}]",
 | 
			
		||||
                    Hex.encodeHexString(certificate.getEncoded()));
 | 
			
		||||
            this.infoParamsBootstrapServerKey(publicKey, privateKey);
 | 
			
		||||
        } catch (CertificateEncodingException e) {
 | 
			
		||||
            log.error("", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void infoPramsUri(String mode) {
 | 
			
		||||
        log.info("Bootstrap Server uses [{}]: serverNoSecureURI : [{}:{}], serverSecureURI : [{}:{}]",
 | 
			
		||||
                mode,
 | 
			
		||||
                this.bootstrapConfig.getHost(),
 | 
			
		||||
                this.bootstrapConfig.getPort(),
 | 
			
		||||
                this.bootstrapConfig.getSecureHost(),
 | 
			
		||||
                this.bootstrapConfig.getSecurePort());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private boolean setServerRPK(LeshanBootstrapServerBuilder builder) {
 | 
			
		||||
        try {
 | 
			
		||||
            this.generateKeyForBootstrapRPK();
 | 
			
		||||
            if (this.publicKey != null && this.publicKey.getEncoded().length > 0 &&
 | 
			
		||||
                    this.privateKey != null && this.privateKey.getEncoded().length > 0) {
 | 
			
		||||
                builder.setPublicKey(this.publicKey);
 | 
			
		||||
//                builder.setCertificateChain(new X509Certificate[] { serverCertificate });
 | 
			
		||||
                /// Trust all certificates.
 | 
			
		||||
                builder.setTrustedCertificates(new X509Certificate[0]);
 | 
			
		||||
                builder.setPrivateKey(this.privateKey);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (NoSuchAlgorithmException | InvalidParameterSpecException | InvalidKeySpecException e) {
 | 
			
		||||
            log.error("Fail create Bootstrap Server with RPK", e);
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * From yml: bootstrap
 | 
			
		||||
     * public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}"
 | 
			
		||||
     * public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}"
 | 
			
		||||
     * private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}"
 | 
			
		||||
     */
 | 
			
		||||
    private void generateKeyForBootstrapRPK() throws NoSuchAlgorithmException, InvalidParameterSpecException, InvalidKeySpecException {
 | 
			
		||||
        /** Get Elliptic Curve Parameter spec for secp256r1 */
 | 
			
		||||
        AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
 | 
			
		||||
        algoParameters.init(new ECGenParameterSpec("secp256r1"));
 | 
			
		||||
        ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
 | 
			
		||||
        LwM2MTransportBootstrapConfig serverConfig = this.bootstrapConfig;
 | 
			
		||||
        if (StringUtils.isNotEmpty(serverConfig.getPublicX()) && StringUtils.isNotEmpty(serverConfig.getPublicY())) {
 | 
			
		||||
            /** Get point values */
 | 
			
		||||
            byte[] publicX = Hex.decodeHex(serverConfig.getPublicX().toCharArray());
 | 
			
		||||
            byte[] publicY = Hex.decodeHex(serverConfig.getPublicY().toCharArray());
 | 
			
		||||
            /** Create key specs */
 | 
			
		||||
            KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
 | 
			
		||||
                    parameterSpec);
 | 
			
		||||
            /** Get public key */
 | 
			
		||||
            this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
 | 
			
		||||
        }
 | 
			
		||||
        String privateEncodedKey = serverConfig.getPrivateEncoded();
 | 
			
		||||
        if (StringUtils.isNotEmpty(privateEncodedKey)) {
 | 
			
		||||
            /** Get private key */
 | 
			
		||||
            byte[] privateS = Hex.decodeHex(privateEncodedKey.toCharArray());
 | 
			
		||||
            try {
 | 
			
		||||
                this.privateKey = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(privateS));
 | 
			
		||||
            } catch (InvalidKeySpecException ignore2) {
 | 
			
		||||
                log.error("Invalid Bootstrap Server rpk.PrivateKey.getEncoded () [{}}]. PrivateKey has no EC algorithm", privateEncodedKey);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void infoParamsBootstrapServerKey(PublicKey publicKey, PrivateKey privateKey) {
 | 
			
		||||
        /** Get x coordinate */
 | 
			
		||||
        byte[] x = ((ECPublicKey) publicKey).getW().getAffineX().toByteArray();
 | 
			
		||||
        if (x[0] == 0)
 | 
			
		||||
            x = Arrays.copyOfRange(x, 1, x.length);
 | 
			
		||||
 | 
			
		||||
        /** Get Y coordinate */
 | 
			
		||||
        byte[] y = ((ECPublicKey) publicKey).getW().getAffineY().toByteArray();
 | 
			
		||||
        if (y[0] == 0)
 | 
			
		||||
            y = Arrays.copyOfRange(y, 1, y.length);
 | 
			
		||||
 | 
			
		||||
        /** Get Curves params */
 | 
			
		||||
        String params = ((ECPublicKey) publicKey).getParams().toString();
 | 
			
		||||
        String privHex = Hex.encodeHexString(privateKey.getEncoded());
 | 
			
		||||
        log.info("\n- Public Key (Hex): [{}] \n" +
 | 
			
		||||
                        "- Private Key (Hex): [{}], \n" +
 | 
			
		||||
                        "public_x: \"${LWM2M_SERVER_PUBLIC_X_BS:{}}\" \n" +
 | 
			
		||||
                        "public_y: \"${LWM2M_SERVER_PUBLIC_Y_BS:{}}\" \n" +
 | 
			
		||||
                        "private_encoded: \"${LWM2M_SERVER_PRIVATE_ENCODED_BS:{}}\" \n" +
 | 
			
		||||
                        "- Elliptic Curve parameters  : [{}]",
 | 
			
		||||
                Hex.encodeHexString(publicKey.getEncoded()),
 | 
			
		||||
                privHex,
 | 
			
		||||
                Hex.encodeHexString(x),
 | 
			
		||||
                Hex.encodeHexString(y),
 | 
			
		||||
                privHex,
 | 
			
		||||
                params);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,12 +27,8 @@ public interface LwM2MSecureServerConfig {
 | 
			
		||||
 | 
			
		||||
    Integer getSecurePort();
 | 
			
		||||
 | 
			
		||||
    String getPublicX();
 | 
			
		||||
 | 
			
		||||
    String getPublicY();
 | 
			
		||||
 | 
			
		||||
    String getPrivateEncoded();
 | 
			
		||||
 | 
			
		||||
    String getCertificateAlias();
 | 
			
		||||
 | 
			
		||||
    String getCertificatePassword();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -46,20 +46,12 @@ public class LwM2MTransportBootstrapConfig implements LwM2MSecureServerConfig {
 | 
			
		||||
    @Value("${transport.lwm2m.bootstrap.security.bind_port:}")
 | 
			
		||||
    private Integer securePort;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.bootstrap.security.public_x:}")
 | 
			
		||||
    private String publicX;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.bootstrap.security.public_y:}")
 | 
			
		||||
    private String publicY;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.bootstrap.security.private_encoded:}")
 | 
			
		||||
    private String privateEncoded;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.bootstrap.security.alias:}")
 | 
			
		||||
    private String certificateAlias;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.bootstrap.security.password:}")
 | 
			
		||||
    private String certificatePassword;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -120,22 +120,14 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig {
 | 
			
		||||
    @Value("${transport.lwm2m.server.security.bind_port:}")
 | 
			
		||||
    private Integer securePort;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.server.security.public_x:}")
 | 
			
		||||
    private String publicX;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.server.security.public_y:}")
 | 
			
		||||
    private String publicY;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.server.security.private_encoded:}")
 | 
			
		||||
    private String privateEncoded;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.server.security.alias:}")
 | 
			
		||||
    private String certificateAlias;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.server.security.password:}")
 | 
			
		||||
    private String certificatePassword;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.lwm2m.log_max_length:}")
 | 
			
		||||
    private int logMaxLength;
 | 
			
		||||
 | 
			
		||||
@ -21,14 +21,12 @@ import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 | 
			
		||||
import org.eclipse.californium.scandium.dtls.cipher.CipherSuite;
 | 
			
		||||
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder;
 | 
			
		||||
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder;
 | 
			
		||||
import org.eclipse.leshan.core.util.Hex;
 | 
			
		||||
import org.eclipse.leshan.server.californium.LeshanServer;
 | 
			
		||||
import org.eclipse.leshan.server.californium.LeshanServerBuilder;
 | 
			
		||||
import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;
 | 
			
		||||
import org.eclipse.leshan.server.model.LwM2mModelProvider;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.thingsboard.server.cache.ota.OtaPackageDataCache;
 | 
			
		||||
import org.thingsboard.server.common.data.StringUtils;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
 | 
			
		||||
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
 | 
			
		||||
import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC;
 | 
			
		||||
@ -41,24 +39,9 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import javax.annotation.PreDestroy;
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
import java.security.AlgorithmParameters;
 | 
			
		||||
import java.security.KeyFactory;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.security.PrivateKey;
 | 
			
		||||
import java.security.PublicKey;
 | 
			
		||||
import java.security.cert.CertificateEncodingException;
 | 
			
		||||
import java.security.cert.X509Certificate;
 | 
			
		||||
import java.security.interfaces.ECPublicKey;
 | 
			
		||||
import java.security.spec.ECGenParameterSpec;
 | 
			
		||||
import java.security.spec.ECParameterSpec;
 | 
			
		||||
import java.security.spec.ECPoint;
 | 
			
		||||
import java.security.spec.ECPublicKeySpec;
 | 
			
		||||
import java.security.spec.InvalidKeySpecException;
 | 
			
		||||
import java.security.spec.InvalidParameterSpecException;
 | 
			
		||||
import java.security.spec.KeySpec;
 | 
			
		||||
import java.security.spec.PKCS8EncodedKeySpec;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
 | 
			
		||||
import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
 | 
			
		||||
@ -75,8 +58,6 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
 | 
			
		||||
 | 
			
		||||
    public static final CipherSuite[] RPK_OR_X509_CIPHER_SUITES = {TLS_PSK_WITH_AES_128_CCM_8, TLS_PSK_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256};
 | 
			
		||||
    public static final CipherSuite[] PSK_CIPHER_SUITES = {TLS_PSK_WITH_AES_128_CCM_8, TLS_PSK_WITH_AES_128_CBC_SHA256};
 | 
			
		||||
    private PublicKey publicKey;
 | 
			
		||||
    private PrivateKey privateKey;
 | 
			
		||||
 | 
			
		||||
    private final LwM2mTransportContext context;
 | 
			
		||||
    private final LwM2MTransportServerConfig config;
 | 
			
		||||
@ -97,14 +78,13 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
 | 
			
		||||
            new LWM2MGenerationPSkRPkECC();
 | 
			
		||||
        }
 | 
			
		||||
        this.server = getLhServer();
 | 
			
		||||
        /**
 | 
			
		||||
        /*
 | 
			
		||||
         * Add a resource to the server.
 | 
			
		||||
         * CoapResource ->
 | 
			
		||||
         * path = FW_PACKAGE or SW_PACKAGE
 | 
			
		||||
         * nameFile = "BC68JAR01A09_TO_BC68JAR01A10.bin"
 | 
			
		||||
         * "coap://host:port/{path}/{token}/{nameFile}"
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        LwM2mTransportCoapResource otaCoapResource = new LwM2mTransportCoapResource(otaPackageDataCache, FIRMWARE_UPDATE_COAP_RESOURCE);
 | 
			
		||||
        this.server.coap().getServer().add(otaCoapResource);
 | 
			
		||||
        this.startLhServer();
 | 
			
		||||
@ -170,29 +150,23 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
 | 
			
		||||
            dtlsConfig.setAdvancedCertificateVerifier(certificateVerifier);
 | 
			
		||||
            builder.setAuthorizer(authorizer);
 | 
			
		||||
            dtlsConfig.setSupportedCipherSuites(RPK_OR_X509_CIPHER_SUITES);
 | 
			
		||||
        } else if (this.setServerRPK(builder)) {
 | 
			
		||||
            this.infoPramsUri("RPK");
 | 
			
		||||
            this.infoParamsServerKey(this.publicKey, this.privateKey);
 | 
			
		||||
            dtlsConfig.setSupportedCipherSuites(RPK_OR_X509_CIPHER_SUITES);
 | 
			
		||||
        } else {
 | 
			
		||||
            /* by default trust all */
 | 
			
		||||
            builder.setTrustedCertificates(new X509Certificate[0]);
 | 
			
		||||
            log.info("Unable to load X509 files for LWM2MServer");
 | 
			
		||||
            dtlsConfig.setSupportedCipherSuites(PSK_CIPHER_SUITES);
 | 
			
		||||
            this.infoPramsUri("PSK");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean setBuilderX509(LeshanServerBuilder builder) {
 | 
			
		||||
        try {
 | 
			
		||||
            X509Certificate serverCertificate = (X509Certificate) config.getKeyStoreValue().getCertificate(config.getCertificateAlias());
 | 
			
		||||
            PrivateKey privateKey = (PrivateKey) config.getKeyStoreValue().getKey(config.getCertificateAlias(), config.getKeyStorePassword() == null ? null : config.getKeyStorePassword().toCharArray());
 | 
			
		||||
            PrivateKey privateKey = (PrivateKey) config.getKeyStoreValue().getKey(config.getCertificateAlias(), config.getCertificatePassword() == null ? null : config.getCertificatePassword().toCharArray());
 | 
			
		||||
            PublicKey publicKey = serverCertificate.getPublicKey();
 | 
			
		||||
            if (privateKey != null && privateKey.getEncoded().length > 0 && publicKey != null && publicKey.getEncoded().length > 0) {
 | 
			
		||||
                builder.setPublicKey(serverCertificate.getPublicKey());
 | 
			
		||||
                builder.setPrivateKey(privateKey);
 | 
			
		||||
                builder.setCertificateChain(new X509Certificate[]{serverCertificate});
 | 
			
		||||
                this.infoParamsServerX509(serverCertificate, publicKey, privateKey);
 | 
			
		||||
                return true;
 | 
			
		||||
            } else {
 | 
			
		||||
                return false;
 | 
			
		||||
@ -203,93 +177,6 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void infoParamsServerX509(X509Certificate certificate, PublicKey publicKey, PrivateKey privateKey) {
 | 
			
		||||
        try {
 | 
			
		||||
            infoPramsUri("X509");
 | 
			
		||||
            log.info("\n- X509 Certificate (Hex): [{}]",
 | 
			
		||||
                    Hex.encodeHexString(certificate.getEncoded()));
 | 
			
		||||
            this.infoParamsServerKey(publicKey, privateKey);
 | 
			
		||||
        } catch (CertificateEncodingException e) {
 | 
			
		||||
            log.error("", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void infoPramsUri(String mode) {
 | 
			
		||||
        LwM2MTransportServerConfig lwM2MTransportServerConfig = config;
 | 
			
		||||
        log.info("Server uses [{}]: serverNoSecureURI : [{}:{}], serverSecureURI : [{}:{}]", mode,
 | 
			
		||||
                lwM2MTransportServerConfig.getHost(),
 | 
			
		||||
                lwM2MTransportServerConfig.getPort(),
 | 
			
		||||
                lwM2MTransportServerConfig.getSecureHost(),
 | 
			
		||||
                lwM2MTransportServerConfig.getSecurePort());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean setServerRPK(LeshanServerBuilder builder) {
 | 
			
		||||
        try {
 | 
			
		||||
            this.loadOrGenerateRPKKeys();
 | 
			
		||||
            if (this.publicKey != null && this.publicKey.getEncoded().length > 0 &&
 | 
			
		||||
                    this.privateKey != null && this.privateKey.getEncoded().length > 0) {
 | 
			
		||||
                builder.setPublicKey(this.publicKey);
 | 
			
		||||
                builder.setPrivateKey(this.privateKey);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (NoSuchAlgorithmException | InvalidParameterSpecException | InvalidKeySpecException e) {
 | 
			
		||||
            log.error("Fail create Server with RPK", e);
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadOrGenerateRPKKeys() throws NoSuchAlgorithmException, InvalidParameterSpecException, InvalidKeySpecException {
 | 
			
		||||
        /* Get Elliptic Curve Parameter spec for secp256r1 */
 | 
			
		||||
        AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
 | 
			
		||||
        algoParameters.init(new ECGenParameterSpec("secp256r1"));
 | 
			
		||||
        ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
 | 
			
		||||
        LwM2MTransportServerConfig serverConfig = config;
 | 
			
		||||
        if (StringUtils.isNotEmpty(serverConfig.getPublicX()) && StringUtils.isNotEmpty(serverConfig.getPublicY())) {
 | 
			
		||||
            byte[] publicX = Hex.decodeHex(serverConfig.getPublicX().toCharArray());
 | 
			
		||||
            byte[] publicY = Hex.decodeHex(serverConfig.getPublicY().toCharArray());
 | 
			
		||||
            KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
 | 
			
		||||
                    parameterSpec);
 | 
			
		||||
            this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
 | 
			
		||||
        }
 | 
			
		||||
        String privateEncodedKey = serverConfig.getPrivateEncoded();
 | 
			
		||||
        if (StringUtils.isNotEmpty(privateEncodedKey)) {
 | 
			
		||||
            byte[] privateS = Hex.decodeHex(privateEncodedKey.toCharArray());
 | 
			
		||||
            try {
 | 
			
		||||
                this.privateKey = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(privateS));
 | 
			
		||||
            } catch (InvalidKeySpecException ignore2) {
 | 
			
		||||
                log.error("Invalid Server rpk.PrivateKey.getEncoded () [{}}]. PrivateKey has no EC algorithm", privateEncodedKey);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void infoParamsServerKey(PublicKey publicKey, PrivateKey privateKey) {
 | 
			
		||||
        /* Get x coordinate */
 | 
			
		||||
        byte[] x = ((ECPublicKey) publicKey).getW().getAffineX().toByteArray();
 | 
			
		||||
        if (x[0] == 0)
 | 
			
		||||
            x = Arrays.copyOfRange(x, 1, x.length);
 | 
			
		||||
 | 
			
		||||
        /* Get Y coordinate */
 | 
			
		||||
        byte[] y = ((ECPublicKey) publicKey).getW().getAffineY().toByteArray();
 | 
			
		||||
        if (y[0] == 0)
 | 
			
		||||
            y = Arrays.copyOfRange(y, 1, y.length);
 | 
			
		||||
 | 
			
		||||
        /* Get Curves params */
 | 
			
		||||
        String params = ((ECPublicKey) publicKey).getParams().toString();
 | 
			
		||||
        String privHex = Hex.encodeHexString(privateKey.getEncoded());
 | 
			
		||||
        log.info(" \n- Public Key (Hex): [{}] \n" +
 | 
			
		||||
                        "- Private Key (Hex): [{}], \n" +
 | 
			
		||||
                        "public_x: \"${LWM2M_SERVER_PUBLIC_X:{}}\" \n" +
 | 
			
		||||
                        "public_y: \"${LWM2M_SERVER_PUBLIC_Y:{}}\" \n" +
 | 
			
		||||
                        "private_encoded: \"${LWM2M_SERVER_PRIVATE_ENCODED:{}}\" \n" +
 | 
			
		||||
                        "- Elliptic Curve parameters  : [{}]",
 | 
			
		||||
                Hex.encodeHexString(publicKey.getEncoded()),
 | 
			
		||||
                privHex,
 | 
			
		||||
                Hex.encodeHexString(x),
 | 
			
		||||
                Hex.encodeHexString(y),
 | 
			
		||||
                privHex,
 | 
			
		||||
                params);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return "LWM2M";
 | 
			
		||||
 | 
			
		||||
@ -108,12 +108,9 @@ transport:
 | 
			
		||||
      security:
 | 
			
		||||
        bind_address: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}"
 | 
			
		||||
        bind_port: "${LWM2M_BIND_PORT_SECURITY:5686}"
 | 
			
		||||
        # Only for RPK: Public & Private Key. If the keystore file is missing or not working
 | 
			
		||||
        public_x: "${LWM2M_SERVER_PUBLIC_X:05064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f358}"
 | 
			
		||||
        public_y: "${LWM2M_SERVER_PUBLIC_Y:5eeb1838e4f9e37b31fa347aef5ce3431eb54e0a2506910c5e0298817445721b}"
 | 
			
		||||
        private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED:308193020100301306072a8648ce3d020106082a8648ce3d030107047930770201010420dc774b309e547ceb48fee547e104ce201a9c48c449dc5414cd04e7f5cf05f67ba00a06082a8648ce3d030107a1440342000405064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f3585eeb1838e4f9e37b31fa347aef5ce3431eb54e0a2506910c5e0298817445721b}"
 | 
			
		||||
        # Only Certificate_x509:
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_ALIAS_SERVER:server}"
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_SERVER_ALIAS:server}"
 | 
			
		||||
        password: "${LWM2M_KEYSTORE_SERVER_PASSWORD:server_ks_password}"
 | 
			
		||||
        skip_validity_check_for_client_cert: "${TB_LWM2M_SERVER_SECURITY_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}"
 | 
			
		||||
    bootstrap:
 | 
			
		||||
      enable: "${LWM2M_ENABLED_BS:true}"
 | 
			
		||||
@ -123,12 +120,9 @@ transport:
 | 
			
		||||
      security:
 | 
			
		||||
        bind_address: "${LWM2M_BIND_ADDRESS_SECURITY_BS:0.0.0.0}"
 | 
			
		||||
        bind_port: "${LWM2M_BIND_PORT_SECURITY_BS:5688}"
 | 
			
		||||
        #  Only for RPK: Public & Private Key. If the keystore file is missing or not working
 | 
			
		||||
        public_x: "${LWM2M_SERVER_PUBLIC_X_BS:5017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f91}"
 | 
			
		||||
        public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:3fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}"
 | 
			
		||||
        private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED_BS:308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104205ecafd90caa7be45c42e1f3f32571632b8409e6e6249d7124f4ba56fab3c8083a00a06082a8648ce3d030107a144034200045017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f913fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}"
 | 
			
		||||
        # Only Certificate_x509:
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_ALIAS_BS:bootstrap}"
 | 
			
		||||
        alias: "${LWM2M_KEYSTORE_BS_ALIAS:bootstrap}"
 | 
			
		||||
        password: "${LWM2M_KEYSTORE_BS_PASSWORD:server_ks_password}"
 | 
			
		||||
    security:
 | 
			
		||||
      # Certificate_x509:
 | 
			
		||||
      # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user