Skip to content

Commit 658c1d4

Browse files
authored
0.55.0
- Fix dsid. - Update DSKeys for broker implementation. - Capture EndpointConfig in DSTransportWs onOpen. - Run reformat code on everything.
2 parents 7c89c0f + f202736 commit 658c1d4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+175
-189
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ subprojects {
55
apply plugin: 'maven'
66

77
group 'org.iot-dsa'
8-
version '0.54.0'
8+
version '0.55.0'
99

1010
sourceCompatibility = 1.8
1111
targetCompatibility = 1.8

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/DSKeys.java

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public static ECPublicKey decodePublic(byte[] bytes) {
132132
*/
133133
public String encodeKeys() {
134134
StringBuilder builder = new StringBuilder();
135-
builder.append(DSBase64.encodeUrl(encodePublic()));
135+
builder.append(urlEncodePublicKey());
136136
builder.append(" ");
137137
builder.append(DSBase64.encodeUrl(toUnsignedByteArray(getPrivateKey().getS())));
138138
return builder.toString();
@@ -142,7 +142,13 @@ public String encodeKeys() {
142142
* X9.63 encoding of the public key.
143143
*/
144144
public byte[] encodePublic() {
145-
ECPublicKey publicKey = getPublicKey();
145+
return encodePublic(getPublicKey());
146+
}
147+
148+
/**
149+
* X9.63 encoding of the public key.
150+
*/
151+
public byte[] encodePublic(ECPublicKey publicKey) {
146152
byte[] x = toUnsignedByteArray(publicKey.getW().getAffineX());
147153
byte[] y = toUnsignedByteArray(publicKey.getW().getAffineY());
148154
byte[] ret = new byte[x.length + y.length + 1]; //32 + 32 + 1
@@ -169,6 +175,42 @@ public String encodePublicHashDsId() {
169175
return ret;
170176
}
171177

178+
/**
179+
* Base64 encoding (no padding and url safe) of the SHA256 hash of the public key. This is used
180+
* to generate the DSID of a link.
181+
*
182+
* @throws DSException wrapping any security related exceptions.
183+
*/
184+
public static String encodePublicHashDsId(String publicKey) {
185+
String ret = null;
186+
try {
187+
byte[] pub = DSBase64.decode(publicKey);
188+
MessageDigest md = MessageDigest.getInstance("SHA-256");
189+
ret = DSBase64.encodeUrl(md.digest(pub));
190+
} catch (Exception x) {
191+
DSException.throwRuntime(x);
192+
}
193+
return ret;
194+
}
195+
196+
public String generateAuth(String saltStr, String pubKey) {
197+
String ret = null;
198+
try {
199+
byte[] salt = saltStr.getBytes("UTF-8");
200+
byte[] secret = generateSharedSecret(pubKey);
201+
byte[] bytes = new byte[salt.length + secret.length];
202+
System.arraycopy(salt, 0, bytes, 0, salt.length);
203+
System.arraycopy(secret, 0, bytes, salt.length, secret.length);
204+
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
205+
messageDigest.update(bytes);
206+
bytes = messageDigest.digest();
207+
ret = DSBase64.encodeUrl(bytes);
208+
} catch (Exception x) {
209+
DSException.throwRuntime(x);
210+
}
211+
return ret;
212+
}
213+
172214
public static byte[] generateHmacSHA256Signature(byte[] data, byte[] secretKeyBytes) {
173215
byte[] ret = null;
174216
try {
@@ -185,11 +227,11 @@ public static byte[] generateHmacSHA256Signature(byte[] data, byte[] secretKeyBy
185227
/**
186228
* Uses the given public key to generate an ECDH shared secret.
187229
*
188-
* @param publicKeyBytes Public key of the other party.
230+
* @param pubKeyBytes Public key of the other party.
189231
*/
190-
public byte[] generateSharedSecret(byte[] publicKeyBytes) {
232+
public byte[] generateSharedSecret(byte[] pubKeyBytes) {
191233
try {
192-
ECPublicKey pubKey = decodePublic(publicKeyBytes);
234+
ECPublicKey pubKey = decodePublic(pubKeyBytes);
193235
KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
194236
keyAgreement.init(getPrivateKey());
195237
keyAgreement.doPhase(pubKey, true);
@@ -203,10 +245,10 @@ public byte[] generateSharedSecret(byte[] publicKeyBytes) {
203245
/**
204246
* Uses the given public key to generate an ECDH shared secret.
205247
*
206-
* @param base64key Base64 encoded public key of the other party.
248+
* @param base64pubKey Base64 encoded public key of the other party.
207249
*/
208-
public byte[] generateSharedSecret(String base64key) {
209-
return generateSharedSecret(DSBase64.decode(base64key));
250+
public byte[] generateSharedSecret(String base64pubKey) {
251+
return generateSharedSecret(DSBase64.decode(base64pubKey));
210252
}
211253

212254
/**
@@ -388,6 +430,10 @@ public void store(OutputStream out) {
388430
}
389431
}
390432

433+
public String urlEncodePublicKey() {
434+
return DSBase64.encodeUrl(encodePublic());
435+
}
436+
391437
/**
392438
* A convenience that creates a verifier and validates the signature for the given bytes.
393439
*/

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/DSRootLink.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public class DSRootLink extends DSLink {
2626
// Instance Fields
2727
///////////////////////////////////////////////////////////////////////////
2828

29-
private String dsId;
3029
private DSKeys keys;
3130
private DSInfo main;
3231
private DSInfo sys = getInfo(SYS);
@@ -40,23 +39,6 @@ public class DSRootLink extends DSLink {
4039
// Public Methods
4140
///////////////////////////////////////////////////////////////////////////
4241

43-
/**
44-
* Returns the unique id of the connection. This is the link name + '-' + the hash of the
45-
* public key in base64.
46-
*
47-
* @return Never null, and url safe.
48-
*/
49-
public String getDsId() {
50-
if (dsId == null) {
51-
StringBuilder buf = new StringBuilder();
52-
buf.append(getLinkName());
53-
buf.append('-');
54-
buf.append(getKeys().encodePublicHashDsId());
55-
dsId = buf.toString();
56-
}
57-
return dsId;
58-
}
59-
6042
/**
6143
* Public / private keys of the link, used to prove identity with brokers.
6244
*/

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/DSSession.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ public abstract class DSSession extends DSNode implements DSIConnected {
3737
///////////////////////////////////////////////////////////////////////////
3838
// Instance Fields
3939
///////////////////////////////////////////////////////////////////////////
40-
41-
private final Object outgoingMutex = new Object();
4240
private int ackRcvd = -1;
4341
private int ackRequired = 0;
4442
private int ackToSend = -1;
@@ -48,6 +46,7 @@ public abstract class DSSession extends DSNode implements DSIConnected {
4846
private long lastTimeSend;
4947
private int messageId = 0;
5048
private int nextMessage = 1;
49+
private final Object outgoingMutex = new Object();
5150
private ConcurrentLinkedQueue<OutboundMessage> outgoingRequests = new ConcurrentLinkedQueue<OutboundMessage>();
5251
private ConcurrentLinkedQueue<OutboundMessage> outgoingResponses = new ConcurrentLinkedQueue<OutboundMessage>();
5352
private ReadThread readThread;

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/requester/DSOutboundSubscriptions.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,19 @@ public class DSOutboundSubscriptions extends DSLogger implements OutboundMessage
3434
///////////////////////////////////////////////////////////////////////////
3535
// Instance Fields
3636
///////////////////////////////////////////////////////////////////////////
37-
37+
private boolean connected = false;
38+
private DSRuntime.Timer disconnectedTimer;
39+
private boolean enqueued = false;
40+
private int nextSid = 1;
41+
private final Map<String, DSOutboundSubscription> pathMap =
42+
new ConcurrentHashMap<String, DSOutboundSubscription>();
3843
private final ConcurrentLinkedQueue<DSOutboundSubscription> pendingSubscribe =
3944
new ConcurrentLinkedQueue<DSOutboundSubscription>();
4045
private final ConcurrentLinkedQueue<DSOutboundSubscription> pendingUnsubscribe =
4146
new ConcurrentLinkedQueue<DSOutboundSubscription>();
42-
private final Map<String, DSOutboundSubscription> pathMap =
43-
new ConcurrentHashMap<String, DSOutboundSubscription>();
47+
private DSRequester requester;
4448
private final Map<Integer, DSOutboundSubscription> sidMap =
4549
new ConcurrentHashMap<Integer, DSOutboundSubscription>();
46-
private boolean connected = false;
47-
private DSRuntime.Timer disconnectedTimer;
48-
private boolean enqueued = false;
49-
private int nextSid = 1;
50-
private DSRequester requester;
5150

5251
///////////////////////////////////////////////////////////////////////////
5352
// Constructors

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/requester/DSRequester.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
import org.iot.dsa.dslink.requester.OutboundRequestHandler;
1515
import org.iot.dsa.dslink.requester.OutboundSubscribeHandler;
1616
import org.iot.dsa.node.DSIValue;
17-
import org.iot.dsa.node.DSInt;
18-
import org.iot.dsa.node.DSLong;
1917
import org.iot.dsa.node.DSMap;
2018
import org.iot.dsa.node.DSNode;
2119

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/responder/DSInboundList.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
import org.iot.dsa.node.DSValueType;
2525
import org.iot.dsa.node.action.ActionSpec;
2626
import org.iot.dsa.node.action.DSAction;
27+
import org.iot.dsa.node.event.DSEvent;
2728
import org.iot.dsa.node.event.DSISubscriber;
2829
import org.iot.dsa.node.event.DSISubscription;
29-
import org.iot.dsa.node.event.DSEvent;
3030
import org.iot.dsa.security.DSPermission;
3131

3232
/**

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/responder/DSInboundSubscription.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
import org.iot.dsa.node.DSInfo;
1414
import org.iot.dsa.node.DSNode;
1515
import org.iot.dsa.node.DSStatus;
16+
import org.iot.dsa.node.event.DSEvent;
1617
import org.iot.dsa.node.event.DSISubscriber;
1718
import org.iot.dsa.node.event.DSISubscription;
18-
import org.iot.dsa.node.event.DSEvent;
1919
import org.iot.dsa.time.DSTime;
2020

2121
/**

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/responder/DSResponder.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.acuity.iot.dsa.dslink.protocol.DSSession;
44
import com.acuity.iot.dsa.dslink.protocol.DSStream;
55
import com.acuity.iot.dsa.dslink.protocol.message.OutboundMessage;
6-
import com.acuity.iot.dsa.dslink.transport.DSTransport;
76
import java.util.Iterator;
87
import java.util.Map;
98
import java.util.Map.Entry;

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/v1/DS1ConnectionInit.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package com.acuity.iot.dsa.dslink.protocol.v1;
22

3-
import com.acuity.iot.dsa.dslink.io.DSBase64;
43
import com.acuity.iot.dsa.dslink.protocol.DSRootLink;
54
import java.io.ByteArrayOutputStream;
65
import java.io.IOException;
76
import java.io.InputStream;
87
import java.net.HttpURLConnection;
98
import java.net.URL;
10-
import java.security.MessageDigest;
119
import org.iot.dsa.dslink.DSLink;
1210
import org.iot.dsa.dslink.DSLinkOptions;
1311
import org.iot.dsa.io.json.Json;
@@ -167,23 +165,11 @@ String makeWsUrl(String wsPath) {
167165
if (wsPath.charAt(0) != '/') {
168166
buf.append('/');
169167
}
170-
buf.append(wsPath).append("?auth=");
171168
String saltStr = response.getString("salt");
172169
if (saltStr != null) {
173-
byte[] salt = saltStr.getBytes("UTF-8");
170+
buf.append(wsPath).append("?auth=");
174171
String tempKey = response.getString("tempKey");
175-
byte[] secret = getLink().getKeys().generateSharedSecret(tempKey);
176-
byte[] bytes = new byte[salt.length + secret.length];
177-
System.arraycopy(salt, 0, bytes, 0, salt.length);
178-
System.arraycopy(secret, 0, bytes, salt.length, secret.length);
179-
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
180-
messageDigest.update(bytes);
181-
bytes = messageDigest.digest();
182-
buf.append(DSBase64.encodeUrl(bytes));
183-
} else {
184-
//The comment for the following in the original sdk was
185-
//"Fake auth parameter". Maybe for testing?
186-
buf.append("_");
172+
buf.append(getLink().getKeys().generateAuth(saltStr, tempKey));
187173
}
188174
if (authToken != null) {
189175
buf.append("&token=").append(authToken);
@@ -244,7 +230,7 @@ void updateSalt(String salt) {
244230
*/
245231
void writeConnectionRequest(HttpURLConnection conn) throws Exception {
246232
DSMap map = new DSMap();
247-
map.put("publicKey", DSBase64.encodeUrl(getLink().getKeys().encodePublic()));
233+
map.put("publicKey", getLink().getKeys().urlEncodePublicKey());
248234
map.put("isRequester", link.getMain().isRequester());
249235
map.put("isResponder", link.getMain().isResponder());
250236
map.put("linkData", new DSMap());

0 commit comments

Comments
 (0)