22 changed files with 437 additions and 15 deletions
@ -0,0 +1,39 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.common.data.security; |
||||
|
|
||||
|
/** |
||||
|
* @author Valerii Sosliuk |
||||
|
*/ |
||||
|
public class DeviceX509Credentials implements DeviceCredentialsFilter { |
||||
|
|
||||
|
private final String sha3Hash; |
||||
|
|
||||
|
public DeviceX509Credentials(String sha3Hash) { |
||||
|
this.sha3Hash = sha3Hash; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getCredentialsId() { return sha3Hash; } |
||||
|
|
||||
|
@Override |
||||
|
public DeviceCredentialsType getCredentialsType() { return DeviceCredentialsType.X509_CERTIFICATE; } |
||||
|
|
||||
|
@Override |
||||
|
public String toString() { |
||||
|
return "DeviceX509Credentials [SHA3=" + sha3Hash + "]"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.bouncycastle.crypto.digests.SHA3Digest; |
||||
|
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; |
||||
|
/** |
||||
|
* @author Valerii Sosliuk |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
public class EncryptionUtil { |
||||
|
|
||||
|
private EncryptionUtil() { |
||||
|
} |
||||
|
|
||||
|
public static String getSha3Hash(String data) { |
||||
|
String trimmedData = data.replaceAll("\n","").replaceAll("\r",""); |
||||
|
byte[] dataBytes = trimmedData.getBytes(); |
||||
|
SHA3Digest md = new SHA3Digest(256); |
||||
|
md.reset(); |
||||
|
md.update(dataBytes, 0, dataBytes.length); |
||||
|
byte[] hashedBytes = new byte[256 / 8]; |
||||
|
md.doFinal(hashedBytes, 0); |
||||
|
String sha3Hash = ByteUtils.toHexString(hashedBytes); |
||||
|
return sha3Hash; |
||||
|
} |
||||
|
} |
||||
@ -1,7 +1,9 @@ |
|||||
HOSTNAME="$(hostname)" |
HOSTNAME="$(hostname)" |
||||
PASSWORD="password" |
PASSWORD="password" |
||||
|
|
||||
CLIENT_TRUSTSTORE="client_truststore.crt" |
CLIENT_TRUSTSTORE="client_truststore.pem" |
||||
|
CLIENT_KEY_ALIAS="clientalias" |
||||
|
CLIENT_FILE_PREFIX="mqttclient" |
||||
|
|
||||
SERVER_KEY_ALIAS="serveralias" |
SERVER_KEY_ALIAS="serveralias" |
||||
SERVER_FILE_PREFIX="mqttserver" |
SERVER_FILE_PREFIX="mqttserver" |
||||
|
|||||
@ -0,0 +1,59 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# |
||||
|
# Copyright © 2016 The Thingsboard Authors |
||||
|
# |
||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
# you may not use this file except in compliance with the License. |
||||
|
# You may obtain a copy of the License at |
||||
|
# |
||||
|
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
# |
||||
|
# Unless required by applicable law or agreed to in writing, software |
||||
|
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
# See the License for the specific language governing permissions and |
||||
|
# limitations under the License. |
||||
|
# |
||||
|
|
||||
|
import paho.mqtt.client as mqtt |
||||
|
import ssl, socket |
||||
|
|
||||
|
# The callback for when the client receives a CONNACK response from the server. |
||||
|
def on_connect(client, userdata, rc): |
||||
|
print('Connected with result code '+str(rc)) |
||||
|
# Subscribing in on_connect() means that if we lose the connection and |
||||
|
# reconnect then subscriptions will be renewed. |
||||
|
client.subscribe('v1/devices/me/attributes') |
||||
|
client.subscribe('v1/devices/me/attributes/response/+') |
||||
|
client.subscribe('v1/devices/me/rpc/request/+') |
||||
|
|
||||
|
|
||||
|
# The callback for when a PUBLISH message is received from the server. |
||||
|
def on_message(client, userdata, msg): |
||||
|
print 'Topic: ' + msg.topic + '\nMessage: ' + str(msg.payload) |
||||
|
if msg.topic.startswith( 'v1/devices/me/rpc/request/'): |
||||
|
requestId = msg.topic[len('v1/devices/me/rpc/request/'):len(msg.topic)] |
||||
|
print 'This is a RPC call. RequestID: ' + requestId + '. Going to reply now!' |
||||
|
client.publish('v1/devices/me/rpc/response/' + requestId, "{\"value1\":\"A\", \"value2\":\"B\"}", 1) |
||||
|
|
||||
|
|
||||
|
client = mqtt.Client() |
||||
|
client.on_connect = on_connect |
||||
|
client.on_message = on_message |
||||
|
client.publish('v1/devices/me/attributes/request/1', "{\"clientKeys\":\"model\"}", 1) |
||||
|
|
||||
|
#client.tls_set(ca_certs="client_truststore.pem", certfile="mqttclient.nopass.pem", keyfile=None, cert_reqs=ssl.CERT_REQUIRED, |
||||
|
# tls_version=ssl.PROTOCOL_TLSv1, ciphers=None); |
||||
|
client.tls_set(ca_certs="client_truststore.pem", certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED, |
||||
|
tls_version=ssl.PROTOCOL_TLSv1, ciphers=None); |
||||
|
|
||||
|
client.username_pw_set("B1_TEST_TOKEN") |
||||
|
client.tls_insecure_set(False) |
||||
|
client.connect(socket.gethostname(), 1883, 1) |
||||
|
|
||||
|
|
||||
|
# Blocking call that processes network traffic, dispatches callbacks and |
||||
|
# handles reconnecting. |
||||
|
# Other loop*() functions are available that give a threaded interface and a |
||||
|
# manual interface. |
||||
|
client.loop_forever() |
||||
@ -0,0 +1,63 @@ |
|||||
|
#!/bin/sh |
||||
|
# |
||||
|
# Copyright © 2016 The Thingsboard Authors |
||||
|
# |
||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
# you may not use this file except in compliance with the License. |
||||
|
# You may obtain a copy of the License at |
||||
|
# |
||||
|
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
# |
||||
|
# Unless required by applicable law or agreed to in writing, software |
||||
|
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
# See the License for the specific language governing permissions and |
||||
|
# limitations under the License. |
||||
|
# |
||||
|
|
||||
|
|
||||
|
. keygen.properties |
||||
|
|
||||
|
echo "Generating SSL Key Pair..." |
||||
|
|
||||
|
keytool -genkeypair -v \ |
||||
|
-alias $CLIENT_KEY_ALIAS \ |
||||
|
-dname "CN=$HOSTNAME, OU=Thingsboard, O=Thingsboard, L=Piscataway, ST=NJ, C=US" \ |
||||
|
-keystore $CLIENT_FILE_PREFIX.jks \ |
||||
|
-keypass $PASSWORD \ |
||||
|
-storepass $PASSWORD \ |
||||
|
-keyalg RSA \ |
||||
|
-keysize 2048 \ |
||||
|
-validity 9999 |
||||
|
echo "Converting keystore to pkcs12" |
||||
|
keytool -importkeystore \ |
||||
|
-srckeystore $CLIENT_FILE_PREFIX.jks \ |
||||
|
-destkeystore $CLIENT_FILE_PREFIX.p12 \ |
||||
|
-srcalias $CLIENT_KEY_ALIAS \ |
||||
|
-srcstoretype jks \ |
||||
|
-deststoretype pkcs12 \ |
||||
|
-keypass $PASSWORD \ |
||||
|
-srcstorepass $PASSWORD \ |
||||
|
-deststorepass $PASSWORD \ |
||||
|
-srckeypass $PASSWORD \ |
||||
|
-destkeypass $PASSWORD |
||||
|
|
||||
|
echo "Converting pkcs12 to pem" |
||||
|
openssl pkcs12 -in $CLIENT_FILE_PREFIX.p12 \ |
||||
|
-out $CLIENT_FILE_PREFIX.pem \ |
||||
|
-passin pass:$PASSWORD \ |
||||
|
-passout pass:$PASSWORD \ |
||||
|
|
||||
|
echo "Importing server public key..." |
||||
|
keytool -export \ |
||||
|
-alias $SERVER_KEY_ALIAS \ |
||||
|
-keystore $SERVER_KEYSTORE_DIR/$SERVER_FILE_PREFIX.jks \ |
||||
|
-file $CLIENT_TRUSTSTORE -rfc \ |
||||
|
-storepass $PASSWORD |
||||
|
|
||||
|
echo "Exporting no-password pem certificate" |
||||
|
openssl rsa -in $CLIENT_FILE_PREFIX.pem -out $CLIENT_FILE_PREFIX.nopass.pem -passin pass:$PASSWORD |
||||
|
tail -n +$(($(grep -m1 -n -e '-----BEGIN CERTIFICATE' $CLIENT_FILE_PREFIX.pem | cut -d: -f1) )) \ |
||||
|
$CLIENT_FILE_PREFIX.pem >> $CLIENT_FILE_PREFIX.nopass.pem |
||||
|
|
||||
|
echo "Done." |
||||
@ -0,0 +1,49 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.transport.mqtt.util; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import sun.misc.BASE64Encoder; |
||||
|
|
||||
|
import java.io.ByteArrayOutputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.security.cert.CertificateEncodingException; |
||||
|
import java.security.cert.X509Certificate; |
||||
|
|
||||
|
/** |
||||
|
* @author Valerii Sosliuk |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
public class SslUtil { |
||||
|
|
||||
|
private SslUtil() { |
||||
|
} |
||||
|
|
||||
|
public static String getX509CertificateString(X509Certificate cert) throws CertificateEncodingException, IOException { |
||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
|
BASE64Encoder encoder = new BASE64Encoder(); |
||||
|
encoder.encodeBuffer(cert.getEncoded(), out); |
||||
|
return new String(out.toByteArray(), "UTF-8").trim(); |
||||
|
} |
||||
|
|
||||
|
public static String getX509CertificateString(javax.security.cert.X509Certificate cert) |
||||
|
throws javax.security.cert.CertificateEncodingException, IOException { |
||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
|
BASE64Encoder encoder = new BASE64Encoder(); |
||||
|
encoder.encodeBuffer(cert.getEncoded(), out); |
||||
|
return new String(out.toByteArray(), "UTF-8").trim(); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue