Showing
9 changed files
with
49 additions
and
35 deletions
@@ -77,13 +77,13 @@ mqtt: | @@ -77,13 +77,13 @@ mqtt: | ||
77 | timeout: "${MQTT_TIMEOUT:10000}" | 77 | timeout: "${MQTT_TIMEOUT:10000}" |
78 | # Uncomment the following lines to enable ssl for MQTT | 78 | # Uncomment the following lines to enable ssl for MQTT |
79 | # ssl: | 79 | # ssl: |
80 | -# key-store: keystore/mqttserver.jks | ||
81 | -# key-store-password: password | ||
82 | -# keyStoreType: JKS | 80 | +# key_store: keystore/mqttserver.jks |
81 | +# key_store_password: password | ||
82 | +# key_store_type: JKS | ||
83 | # TrustStore can be the same as KeyStore | 83 | # TrustStore can be the same as KeyStore |
84 | -# trust-store: keystore/mqttserver.jks | ||
85 | -# trust-store-password: password | ||
86 | -# trustStoreType: JKS | 84 | +# trust_store: keystore/mqttserver.jks |
85 | +# trust_store_password: password | ||
86 | +# trust_store_type: JKS | ||
87 | 87 | ||
88 | # CoAP server parameters | 88 | # CoAP server parameters |
89 | coap: | 89 | coap: |
@@ -27,8 +27,12 @@ public class EncryptionUtil { | @@ -27,8 +27,12 @@ public class EncryptionUtil { | ||
27 | private EncryptionUtil() { | 27 | private EncryptionUtil() { |
28 | } | 28 | } |
29 | 29 | ||
30 | + public static String trimNewLines(String input) { | ||
31 | + return input.replaceAll("\n","").replaceAll("\r",""); | ||
32 | + } | ||
33 | + | ||
30 | public static String getSha3Hash(String data) { | 34 | public static String getSha3Hash(String data) { |
31 | - String trimmedData = data.replaceAll("\n","").replaceAll("\r",""); | 35 | + String trimmedData = trimNewLines(data); |
32 | byte[] dataBytes = trimmedData.getBytes(); | 36 | byte[] dataBytes = trimmedData.getBytes(); |
33 | SHA3Digest md = new SHA3Digest(256); | 37 | SHA3Digest md = new SHA3Digest(256); |
34 | md.reset(); | 38 | md.reset(); |
@@ -29,8 +29,6 @@ import org.thingsboard.server.dao.exception.DataValidationException; | @@ -29,8 +29,6 @@ import org.thingsboard.server.dao.exception.DataValidationException; | ||
29 | import org.thingsboard.server.dao.model.DeviceCredentialsEntity; | 29 | import org.thingsboard.server.dao.model.DeviceCredentialsEntity; |
30 | import org.thingsboard.server.dao.service.DataValidator; | 30 | import org.thingsboard.server.dao.service.DataValidator; |
31 | 31 | ||
32 | -import java.util.Optional; | ||
33 | - | ||
34 | import static org.thingsboard.server.dao.DaoUtil.getData; | 32 | import static org.thingsboard.server.dao.DaoUtil.getData; |
35 | import static org.thingsboard.server.dao.service.Validator.validateId; | 33 | import static org.thingsboard.server.dao.service.Validator.validateId; |
36 | import static org.thingsboard.server.dao.service.Validator.validateString; | 34 | import static org.thingsboard.server.dao.service.Validator.validateString; |
@@ -73,16 +71,18 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService { | @@ -73,16 +71,18 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService { | ||
73 | 71 | ||
74 | private DeviceCredentials saveOrUpdare(DeviceCredentials deviceCredentials) { | 72 | private DeviceCredentials saveOrUpdare(DeviceCredentials deviceCredentials) { |
75 | if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { | 73 | if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { |
76 | - encryptDeviceId(deviceCredentials); | 74 | + formatCertData(deviceCredentials); |
77 | } | 75 | } |
78 | log.trace("Executing updateDeviceCredentials [{}]", deviceCredentials); | 76 | log.trace("Executing updateDeviceCredentials [{}]", deviceCredentials); |
79 | credentialsValidator.validate(deviceCredentials); | 77 | credentialsValidator.validate(deviceCredentials); |
80 | return getData(deviceCredentialsDao.save(deviceCredentials)); | 78 | return getData(deviceCredentialsDao.save(deviceCredentials)); |
81 | } | 79 | } |
82 | 80 | ||
83 | - private void encryptDeviceId(DeviceCredentials deviceCredentials) { | ||
84 | - String sha3Hash = EncryptionUtil.getSha3Hash(deviceCredentials.getCredentialsId()); | 81 | + private void formatCertData(DeviceCredentials deviceCredentials) { |
82 | + String cert = EncryptionUtil.trimNewLines(deviceCredentials.getCredentialsValue()); | ||
83 | + String sha3Hash = EncryptionUtil.getSha3Hash(cert); | ||
85 | deviceCredentials.setCredentialsId(sha3Hash); | 84 | deviceCredentials.setCredentialsId(sha3Hash); |
85 | + deviceCredentials.setCredentialsValue(cert); | ||
86 | } | 86 | } |
87 | 87 | ||
88 | @Override | 88 | @Override |
1 | /** | 1 | /** |
2 | * Copyright © 2016-2017 The Thingsboard Authors | 2 | * Copyright © 2016-2017 The Thingsboard Authors |
3 | - * | 3 | + * <p> |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at | 6 | * You may obtain a copy of the License at |
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | 7 | + * <p> |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * <p> | ||
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
@@ -45,18 +45,18 @@ import java.security.cert.X509Certificate; | @@ -45,18 +45,18 @@ import java.security.cert.X509Certificate; | ||
45 | public class MqttSslHandlerProvider { | 45 | public class MqttSslHandlerProvider { |
46 | 46 | ||
47 | public static final String TLS = "TLS"; | 47 | public static final String TLS = "TLS"; |
48 | - @Value("${mqtt.ssl.key-store}") | 48 | + @Value("${mqtt.ssl.key_store}") |
49 | private String keyStoreFile; | 49 | private String keyStoreFile; |
50 | - @Value("${mqtt.ssl.key-store-password}") | 50 | + @Value("${mqtt.ssl.key_store_password}") |
51 | private String keyStorePassword; | 51 | private String keyStorePassword; |
52 | - @Value("${mqtt.ssl.keyStoreType}") | 52 | + @Value("${mqtt.ssl.key_store_type}") |
53 | private String keyStoreType; | 53 | private String keyStoreType; |
54 | 54 | ||
55 | - @Value("${mqtt.ssl.trust-store}") | 55 | + @Value("${mqtt.ssl.trust_store}") |
56 | private String trustStoreFile; | 56 | private String trustStoreFile; |
57 | - @Value("${mqtt.ssl.trust-store-password}") | 57 | + @Value("${mqtt.ssl.trust_store_password}") |
58 | private String trustStorePassword; | 58 | private String trustStorePassword; |
59 | - @Value("${mqtt.ssl.trustStoreType}") | 59 | + @Value("${mqtt.ssl.trust_store_type}") |
60 | private String trustStoreType; | 60 | private String trustStoreType; |
61 | 61 | ||
62 | @Autowired | 62 | @Autowired |
@@ -108,8 +108,7 @@ public class MqttSslHandlerProvider { | @@ -108,8 +108,7 @@ public class MqttSslHandlerProvider { | ||
108 | break; | 108 | break; |
109 | } | 109 | } |
110 | } | 110 | } |
111 | - X509TrustManager x509TmWrapper = new ThingsboardMqttX509TrustManager(x509Tm, deviceCredentialsService); | ||
112 | - return x509TmWrapper; | 111 | + return new ThingsboardMqttX509TrustManager(x509Tm, deviceCredentialsService); |
113 | } | 112 | } |
114 | 113 | ||
115 | static class ThingsboardMqttX509TrustManager implements X509TrustManager { | 114 | static class ThingsboardMqttX509TrustManager implements X509TrustManager { |
@@ -136,18 +135,22 @@ public class MqttSslHandlerProvider { | @@ -136,18 +135,22 @@ public class MqttSslHandlerProvider { | ||
136 | @Override | 135 | @Override |
137 | public void checkClientTrusted(X509Certificate[] chain, | 136 | public void checkClientTrusted(X509Certificate[] chain, |
138 | String authType) throws CertificateException { | 137 | String authType) throws CertificateException { |
138 | + DeviceCredentials deviceCredentials = null; | ||
139 | for (X509Certificate cert : chain) { | 139 | for (X509Certificate cert : chain) { |
140 | try { | 140 | try { |
141 | String strCert = SslUtil.getX509CertificateString(cert); | 141 | String strCert = SslUtil.getX509CertificateString(cert); |
142 | String sha3Hash = EncryptionUtil.getSha3Hash(strCert); | 142 | String sha3Hash = EncryptionUtil.getSha3Hash(strCert); |
143 | - DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByCredentialsId(sha3Hash); | ||
144 | - if (deviceCredentials == null) { | ||
145 | - throw new CertificateException("Invalid Device Certificate"); | 143 | + deviceCredentials = deviceCredentialsService.findDeviceCredentialsByCredentialsId(sha3Hash); |
144 | + if (deviceCredentials != null && strCert.equals(deviceCredentials.getCredentialsValue())) { | ||
145 | + break; | ||
146 | } | 146 | } |
147 | } catch (IOException e) { | 147 | } catch (IOException e) { |
148 | - e.printStackTrace(); | 148 | + log.error(e.getMessage(), e); |
149 | } | 149 | } |
150 | } | 150 | } |
151 | + if (deviceCredentials == null) { | ||
152 | + throw new CertificateException("Invalid Device Certificate"); | ||
153 | + } | ||
151 | } | 154 | } |
152 | } | 155 | } |
153 | } | 156 | } |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.transport.mqtt.util; | 16 | package org.thingsboard.server.transport.mqtt.util; |
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | +import org.thingsboard.server.dao.EncryptionUtil; | ||
19 | import sun.misc.BASE64Encoder; | 20 | import sun.misc.BASE64Encoder; |
20 | 21 | ||
21 | import java.io.ByteArrayOutputStream; | 22 | import java.io.ByteArrayOutputStream; |
@@ -32,11 +33,12 @@ public class SslUtil { | @@ -32,11 +33,12 @@ public class SslUtil { | ||
32 | private SslUtil() { | 33 | private SslUtil() { |
33 | } | 34 | } |
34 | 35 | ||
35 | - public static String getX509CertificateString(X509Certificate cert) throws CertificateEncodingException, IOException { | 36 | + public static String getX509CertificateString(X509Certificate cert) |
37 | + throws CertificateEncodingException, IOException { | ||
36 | ByteArrayOutputStream out = new ByteArrayOutputStream(); | 38 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
37 | BASE64Encoder encoder = new BASE64Encoder(); | 39 | BASE64Encoder encoder = new BASE64Encoder(); |
38 | encoder.encodeBuffer(cert.getEncoded(), out); | 40 | encoder.encodeBuffer(cert.getEncoded(), out); |
39 | - return new String(out.toByteArray(), "UTF-8").trim(); | 41 | + return EncryptionUtil.trimNewLines(new String(out.toByteArray(), "UTF-8")); |
40 | } | 42 | } |
41 | 43 | ||
42 | public static String getX509CertificateString(javax.security.cert.X509Certificate cert) | 44 | public static String getX509CertificateString(javax.security.cert.X509Certificate cert) |
@@ -44,6 +46,6 @@ public class SslUtil { | @@ -44,6 +46,6 @@ public class SslUtil { | ||
44 | ByteArrayOutputStream out = new ByteArrayOutputStream(); | 46 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
45 | BASE64Encoder encoder = new BASE64Encoder(); | 47 | BASE64Encoder encoder = new BASE64Encoder(); |
46 | encoder.encodeBuffer(cert.getEncoded(), out); | 48 | encoder.encodeBuffer(cert.getEncoded(), out); |
47 | - return new String(out.toByteArray(), "UTF-8").trim(); | 49 | + return EncryptionUtil.trimNewLines(new String(out.toByteArray(), "UTF-8")); |
48 | } | 50 | } |
49 | } | 51 | } |
@@ -52,13 +52,16 @@ export default function ManageDeviceCredentialsController(deviceService, $scope, | @@ -52,13 +52,16 @@ export default function ManageDeviceCredentialsController(deviceService, $scope, | ||
52 | function valid() { | 52 | function valid() { |
53 | return vm.deviceCredentials && | 53 | return vm.deviceCredentials && |
54 | (vm.deviceCredentials.credentialsType === 'ACCESS_TOKEN' | 54 | (vm.deviceCredentials.credentialsType === 'ACCESS_TOKEN' |
55 | - || vm.deviceCredentials.credentialsType === 'X509_CERTIFICATE') | ||
56 | - && | ||
57 | - vm.deviceCredentials.credentialsId && vm.deviceCredentials.credentialsId.length > 0; | 55 | + && vm.deviceCredentials.credentialsId |
56 | + && vm.deviceCredentials.credentialsId.length > 0 | ||
57 | + || vm.deviceCredentials.credentialsType === 'X509_CERTIFICATE' | ||
58 | + && vm.deviceCredentials.credentialsValue | ||
59 | + && vm.deviceCredentials.credentialsValue.length > 0); | ||
58 | } | 60 | } |
59 | 61 | ||
60 | function clear() { | 62 | function clear() { |
61 | vm.deviceCredentials.credentialsId = null; | 63 | vm.deviceCredentials.credentialsId = null; |
64 | + vm.deviceCredentials.credentialsValue = null; | ||
62 | } | 65 | } |
63 | 66 | ||
64 | function save() { | 67 | function save() { |
@@ -51,7 +51,7 @@ | @@ -51,7 +51,7 @@ | ||
51 | </md-input-container> | 51 | </md-input-container> |
52 | <md-input-container class="md-block" ng-if="vm.deviceCredentials.credentialsType === 'X509_CERTIFICATE'"> | 52 | <md-input-container class="md-block" ng-if="vm.deviceCredentials.credentialsType === 'X509_CERTIFICATE'"> |
53 | <label translate>device.rsa-key</label> | 53 | <label translate>device.rsa-key</label> |
54 | - <textarea required name="rsaKey" ng-model="vm.deviceCredentials.credentialsId" | 54 | + <textarea required name="rsaKey" ng-model="vm.deviceCredentials.credentialsValue" |
55 | cols="15" rows="5" /> | 55 | cols="15" rows="5" /> |
56 | <div ng-messages="theForm.rsaKey.$error"> | 56 | <div ng-messages="theForm.rsaKey.$error"> |
57 | <div translate ng-message="required">device.rsa-key-required</div> | 57 | <div translate ng-message="required">device.rsa-key-required</div> |