Skip to content

Commit f7af06d

Browse files
committed
Add support for non-printable HTTP passwords
The OCPP 1.6 Security Whitepaper foresees that the AuthorizationKey, which is a hexadecimal string representation of the HTTP Basic Authentication password to be used, may use the full byte range, i.e. including non-printable characters. Thus, passing it as a Java String object is not suitable. In contrast, OCPP 2.0.1 specifies the password as being a string of printable UTF-8 characters. The library already supports that. To accomodate both, take advantage of the fact that JSONConfiguration treats all parameters as Objects, so either a String or a byte array can be set. Change the code adding the credentials to the HTTP header to correctly generate the Base64 encoded credentials from either a password string or a byte array, depending on the object type that was set as the password.
1 parent 441adb1 commit f7af06d

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

OCPP-J/src/main/java/eu/chargetime/ocpp/WebSocketTransmitter.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ of this software and associated documentation files (the "Software"), to deal
3131
import java.net.ConnectException;
3232
import java.net.Proxy;
3333
import java.net.URI;
34+
import java.nio.charset.StandardCharsets;
3435
import java.util.Base64;
3536
import java.util.HashMap;
3637
import java.util.Map;
@@ -68,10 +69,18 @@ public void connect(String uri, RadioEvents events) {
6869

6970
Map<String, String> httpHeaders = new HashMap<>();
7071
String username = configuration.getParameter(JSONConfiguration.USERNAME_PARAMETER);
71-
String password = configuration.getParameter(JSONConfiguration.PASSWORD_PARAMETER);
72+
Object password = configuration.getParameter(JSONConfiguration.PASSWORD_PARAMETER);
73+
byte[] credentials = null;
7274
if (username != null && password != null) {
73-
String credentials = username + ":" + password;
74-
byte[] base64Credentials = Base64.getEncoder().encode(credentials.getBytes());
75+
if (password instanceof String) {
76+
credentials = (username + ":" + password).getBytes(StandardCharsets.UTF_8);
77+
} else if (password instanceof byte[]) {
78+
credentials =
79+
joinByteArrays((username + ":").getBytes(StandardCharsets.UTF_8), (byte[]) password);
80+
}
81+
}
82+
if (credentials != null) {
83+
byte[] base64Credentials = Base64.getEncoder().encode(credentials);
7584
httpHeaders.put("Authorization", "Basic " + new String(base64Credentials));
7685
}
7786

@@ -132,6 +141,13 @@ public void onError(Exception ex) {
132141
}
133142
}
134143

144+
byte[] joinByteArrays(byte[] a, byte[] b) {
145+
byte[] result = new byte[a.length + b.length];
146+
System.arraycopy(a, 0, result, 0, a.length);
147+
System.arraycopy(b, 0, result, a.length, b.length);
148+
return result;
149+
}
150+
135151
void configure() {
136152
client.setReuseAddr(configuration.getParameter(JSONConfiguration.REUSE_ADDR_PARAMETER, false));
137153
client.setTcpNoDelay(

0 commit comments

Comments
 (0)