Skip to content

Commit 8287b1e

Browse files
committed
clean up crypto and exceptions
1 parent 68a66a7 commit 8287b1e

11 files changed

+72
-180
lines changed

src/main/java/com/opentok/api/Session.java

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22

33
import java.io.UnsupportedEncodingException;
44
import java.net.URLEncoder;
5+
import java.security.InvalidKeyException;
6+
import java.security.NoSuchAlgorithmException;
7+
import java.security.SignatureException;
58
import java.util.Random;
69

10+
import com.opentok.util.Crypto;
11+
import org.apache.commons.codec.binary.Base64;
12+
713
import com.opentok.api.constants.SessionProperties;
814
import com.opentok.api.constants.TokenOptions;
915
import com.opentok.exception.OpenTokException;
1016
import com.opentok.exception.OpenTokInvalidArgumentException;
11-
import com.opentok.exception.OpenTokRequestException;
12-
import com.opentok.util.Base64;
13-
import com.opentok.util.GenerateMac;
1417

1518
public class Session {
1619

@@ -84,8 +87,13 @@ public String generateToken() throws OpenTokException {
8487
*
8588
* @return The token string.
8689
*/
87-
public String generateToken(TokenOptions tokenOptions) throws
88-
OpenTokInvalidArgumentException, OpenTokRequestException {
90+
public String generateToken(TokenOptions tokenOptions) throws OpenTokException {
91+
92+
// Token format
93+
//
94+
// | ------------------------------ tokenStringBuilder ----------------------------- |
95+
// | "T1=="+Base64Encode(| --------------------- innerBuilder --------------------- |)|
96+
// | "partner_id={apiKey}&sig={sig}:| -- dataStringBuilder -- |
8997

9098
if (tokenOptions == null) {
9199
throw new OpenTokInvalidArgumentException("Token options cannot be null");
@@ -94,10 +102,9 @@ public String generateToken(TokenOptions tokenOptions) throws
94102
String role = tokenOptions.getRole();
95103
double expireTime = tokenOptions.getExpireTime(); // will be 0 if nothing was explicitly set
96104
String data = tokenOptions.getData(); // will be null if nothing was explicitly set
97-
98105
Long create_time = new Long(System.currentTimeMillis() / 1000).longValue();
106+
99107
StringBuilder dataStringBuilder = new StringBuilder();
100-
//Build the string
101108
Random random = new Random();
102109
int nonce = random.nextInt();
103110
dataStringBuilder.append("session_id=");
@@ -147,16 +154,21 @@ public String generateToken(TokenOptions tokenOptions) throws
147154

148155
innerBuilder.append("&sig=");
149156

150-
// TODO: user a more concise crypto routine
151-
innerBuilder.append(GenerateMac.calculateRFC2104HMAC(dataStringBuilder.toString(),
152-
this.apiSecret));
157+
innerBuilder.append(Crypto.signData(dataStringBuilder.toString(), this.apiSecret));
153158
innerBuilder.append(":");
154159
innerBuilder.append(dataStringBuilder.toString());
155160

156-
tokenStringBuilder.append(Base64.encode(innerBuilder.toString()));
157-
158-
} catch (java.security.SignatureException e) {
159-
throw new OpenTokRequestException(500, e.getMessage());
161+
tokenStringBuilder.append(Base64.encodeBase64URLSafeString(innerBuilder.toString().getBytes("UTF-8")));
162+
163+
// if we only wanted Java 7 and above, we could DRY this into one catch clause
164+
} catch (SignatureException e) {
165+
throw new OpenTokException("Could not generate token, a signing error occurred.", e);
166+
} catch (NoSuchAlgorithmException e) {
167+
throw new OpenTokException("Could not generate token, a signing error occurred.", e);
168+
} catch (InvalidKeyException e) {
169+
throw new OpenTokException("Could not generate token, a signing error occurred.", e);
170+
} catch (UnsupportedEncodingException e) {
171+
throw new OpenTokException("Could not generate token, a signing error occurred.", e);
160172
}
161173

162174
return tokenStringBuilder.toString();

src/main/java/com/opentok/api/constants/TokenOptions.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public String getData() {
3333
return data;
3434
}
3535

36-
// TODO: toMap() method?
37-
3836
public static class Builder {
3937
private String role;
4038
private double expireTime = 0;

src/main/java/com/opentok/exception/OpenTokException.java

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,14 @@
33
/**
44
* Defines exceptions in the OpenTok SDK.
55
*/
6-
public abstract class OpenTokException extends Exception {
6+
public class OpenTokException extends Exception {
77
private static final long serialVersionUID = 6059658348908505724L;
88

9-
int errorCode;
10-
String statusMessage;
11-
12-
public OpenTokException(int code, String statusMessage) {
13-
super();
14-
this.errorCode = code;
15-
this.statusMessage = statusMessage;
16-
}
17-
18-
/**
19-
* Returns the status message, providing details about the error.
20-
*/
21-
public String getStatusMessage() {
22-
return statusMessage;
9+
public OpenTokException(String message) {
10+
super(message);
2311
}
2412

25-
/**
26-
* Returns the error code.
27-
*/
28-
public int getErrorCode() {
29-
return errorCode;
13+
public OpenTokException(String message, Throwable cause) {
14+
super(message, cause);
3015
}
3116
}

src/main/java/com/opentok/exception/OpenTokInvalidArgumentException.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ public class OpenTokInvalidArgumentException extends OpenTokException {
44

55
private static final long serialVersionUID = 6315168083117996091L;
66

7-
public OpenTokInvalidArgumentException(String statusMessage) {
8-
super(400, statusMessage);
7+
public OpenTokInvalidArgumentException(String message) {
8+
super(message);
99
}
10+
1011
}

src/main/java/com/opentok/exception/OpenTokRequestException.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ public class OpenTokRequestException extends OpenTokException {
44

55
private static final long serialVersionUID = -3852834447530956514L;
66

7-
public OpenTokRequestException(int code, String statusMessage) {
8-
super(code, statusMessage);
9-
7+
public OpenTokRequestException(String message) {
8+
super(message);
109
}
1110

1211
}

src/main/java/com/opentok/exception/OpenTokSessionNotFoundException.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ public class OpenTokSessionNotFoundException extends OpenTokException {
44

55
private static final long serialVersionUID = 1946440047275860231L;
66

7-
public OpenTokSessionNotFoundException(String statusMessage) {
8-
super(404, statusMessage);
7+
public OpenTokSessionNotFoundException(String message) {
8+
super(message);
99
}
10-
1110
}

src/main/java/com/opentok/util/Base64.java

Lines changed: 0 additions & 57 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.opentok.util;
2+
3+
import java.security.InvalidKeyException;
4+
import java.security.NoSuchAlgorithmException;
5+
import java.security.SignatureException;
6+
import java.util.Formatter;
7+
import javax.crypto.Mac;
8+
import javax.crypto.spec.SecretKeySpec;
9+
10+
public class Crypto {
11+
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
12+
13+
// -- credit: https://gist.github.com/ishikawa/88599
14+
15+
private static String toHexString(byte[] bytes) {
16+
Formatter formatter = new Formatter();
17+
for (byte b : bytes) {
18+
formatter.format("%02x", b);
19+
}
20+
return formatter.toString();
21+
}
22+
23+
public static String signData(String data, String key)
24+
throws SignatureException, NoSuchAlgorithmException, InvalidKeyException
25+
{
26+
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
27+
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
28+
mac.init(signingKey);
29+
return toHexString(mac.doFinal(data.getBytes()));
30+
}
31+
}

src/main/java/com/opentok/util/GenerateMac.java

Lines changed: 0 additions & 76 deletions
This file was deleted.

src/main/java/com/opentok/util/TokBoxUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static Node parseXML(String matchToken, NodeList nodelist) {
3333

3434
public static Document setupDocument(String xmlResponse) throws ParserConfigurationException, SAXException, IOException, OpenTokException {
3535
if(null == xmlResponse) {
36-
throw new OpenTokRequestException(500, "There was an error in retrieving the response");
36+
throw new OpenTokRequestException("There was an error in retrieving the response");
3737
}
3838

3939
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
@@ -45,7 +45,7 @@ public static Document setupDocument(String xmlResponse) throws ParserConfigurat
4545
Node errorNodes = TokBoxUtils.parseXML("error", document.getElementsByTagName("error"));
4646

4747
if(null != errorNodes) {
48-
throw new OpenTokRequestException(500, xmlResponse);
48+
throw new OpenTokRequestException(xmlResponse);
4949
}
5050

5151
return document;

0 commit comments

Comments
 (0)