30
30
import javax .crypto .spec .SecretKeySpec ;
31
31
import javax .security .sasl .SaslClient ;
32
32
import javax .security .sasl .SaslException ;
33
- import java .io . UnsupportedEncodingException ;
33
+ import java .nio . charset . StandardCharsets ;
34
34
import java .security .InvalidKeyException ;
35
35
import java .security .MessageDigest ;
36
36
import java .security .NoSuchAlgorithmException ;
@@ -53,9 +53,9 @@ class ScramShaAuthenticator extends SaslAuthenticator {
53
53
private static final int MINIMUM_ITERATION_COUNT = 4096 ;
54
54
private static final String GS2_HEADER = "n,," ;
55
55
private static final int RANDOM_LENGTH = 24 ;
56
- private static final byte [] INT_1 = new byte [] {0 , 0 , 0 , 1 };
56
+ private static final byte [] INT_1 = {0 , 0 , 0 , 1 };
57
57
58
- ScramShaAuthenticator (final MongoCredentialWithCache credential , final @ Nullable ServerApi serverApi ) {
58
+ ScramShaAuthenticator (final MongoCredentialWithCache credential , @ Nullable final ServerApi serverApi ) {
59
59
this (credential , new DefaultRandomStringGenerator (), getAuthenicationHashGenerator (credential .getAuthenticationMechanism ()),
60
60
serverApi );
61
61
}
@@ -65,7 +65,7 @@ class ScramShaAuthenticator extends SaslAuthenticator {
65
65
}
66
66
67
67
ScramShaAuthenticator (final MongoCredentialWithCache credential , final RandomStringGenerator randomStringGenerator ,
68
- final AuthenticationHashGenerator authenticationHashGenerator , final @ Nullable ServerApi serverApi ) {
68
+ final AuthenticationHashGenerator authenticationHashGenerator , @ Nullable final ServerApi serverApi ) {
69
69
super (credential , serverApi );
70
70
this .randomStringGenerator = randomStringGenerator ;
71
71
this .authenticationHashGenerator = authenticationHashGenerator ;
@@ -171,7 +171,7 @@ public byte[] evaluateChallenge(final byte[] challenge) throws SaslException {
171
171
}
172
172
173
173
private byte [] validateServerSignature (final byte [] challenge ) throws SaslException {
174
- String serverResponse = encodeUTF8 (challenge );
174
+ String serverResponse = new String (challenge , StandardCharsets . UTF_8 );
175
175
HashMap <String , String > map = parseServerResponse (serverResponse );
176
176
if (!MessageDigest .isEqual (Base64 .getDecoder ().decode (map .get ("v" )), serverSignature )) {
177
177
throw new SaslException ("Server signature was invalid." );
@@ -199,15 +199,15 @@ public void dispose() {
199
199
// nothing to do
200
200
}
201
201
202
- private byte [] computeClientFirstMessage () throws SaslException {
202
+ private byte [] computeClientFirstMessage () {
203
203
clientNonce = randomStringGenerator .generate (RANDOM_LENGTH );
204
204
String clientFirstMessage = "n=" + getUserName () + ",r=" + clientNonce ;
205
205
clientFirstMessageBare = clientFirstMessage ;
206
- return decodeUTF8 (GS2_HEADER + clientFirstMessage );
206
+ return (GS2_HEADER + clientFirstMessage ). getBytes ( StandardCharsets . UTF_8 );
207
207
}
208
208
209
209
private byte [] computeClientFinalMessage (final byte [] challenge ) throws SaslException {
210
- String serverFirstMessage = encodeUTF8 (challenge );
210
+ String serverFirstMessage = new String (challenge , StandardCharsets . UTF_8 );
211
211
HashMap <String , String > map = parseServerResponse (serverFirstMessage );
212
212
String serverNonce = map .get ("r" );
213
213
if (!serverNonce .startsWith (clientNonce )) {
@@ -220,11 +220,11 @@ private byte[] computeClientFinalMessage(final byte[] challenge) throws SaslExce
220
220
throw new SaslException ("Invalid iteration count." );
221
221
}
222
222
223
- String clientFinalMessageWithoutProof = "c=" + Base64 .getEncoder ().encodeToString (decodeUTF8 ( GS2_HEADER )) + ",r=" + serverNonce ;
223
+ String clientFinalMessageWithoutProof = "c=" + Base64 .getEncoder ().encodeToString (GS2_HEADER . getBytes ( StandardCharsets . UTF_8 )) + ",r=" + serverNonce ;
224
224
String authMessage = clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof ;
225
225
String clientFinalMessage = clientFinalMessageWithoutProof + ",p="
226
226
+ getClientProof (getAuthenicationHash (), salt , iterationCount , authMessage );
227
- return decodeUTF8 ( clientFinalMessage );
227
+ return clientFinalMessage . getBytes ( StandardCharsets . UTF_8 );
228
228
}
229
229
230
230
/**
@@ -241,12 +241,12 @@ private byte[] computeClientFinalMessage(final byte[] challenge) throws SaslExce
241
241
*/
242
242
String getClientProof (final String password , final String salt , final int iterationCount , final String authMessage )
243
243
throws SaslException {
244
- String hashedPasswordAndSalt = encodeUTF8 (h (decodeUTF8 (password + salt )) );
244
+ String hashedPasswordAndSalt = new String (h ((password + salt ). getBytes ( StandardCharsets . UTF_8 )), StandardCharsets . UTF_8 );
245
245
246
246
CacheKey cacheKey = new CacheKey (hashedPasswordAndSalt , salt , iterationCount );
247
247
CacheValue cachedKeys = getMongoCredentialWithCache ().getFromCache (cacheKey , CacheValue .class );
248
248
if (cachedKeys == null ) {
249
- byte [] saltedPassword = hi (decodeUTF8 ( password ), Base64 .getDecoder ().decode (salt ), iterationCount );
249
+ byte [] saltedPassword = hi (password . getBytes ( StandardCharsets . UTF_8 ), Base64 .getDecoder ().decode (salt ), iterationCount );
250
250
byte [] clientKey = hmac (saltedPassword , "Client Key" );
251
251
byte [] serverKey = hmac (saltedPassword , "Server Key" );
252
252
cachedKeys = new CacheValue (clientKey , serverKey );
@@ -260,22 +260,6 @@ String getClientProof(final String password, final String salt, final int iterat
260
260
return Base64 .getEncoder ().encodeToString (clientProof );
261
261
}
262
262
263
- private byte [] decodeUTF8 (final String str ) throws SaslException {
264
- try {
265
- return str .getBytes ("UTF-8" );
266
- } catch (UnsupportedEncodingException e ) {
267
- throw new SaslException ("UTF-8 is not a supported encoding." , e );
268
- }
269
- }
270
-
271
- private String encodeUTF8 (final byte [] bytes ) throws SaslException {
272
- try {
273
- return new String (bytes , "UTF-8" );
274
- } catch (UnsupportedEncodingException e ) {
275
- throw new SaslException ("UTF-8 is not a supported encoding." , e );
276
- }
277
- }
278
-
279
263
private byte [] h (final byte [] data ) throws SaslException {
280
264
try {
281
265
return MessageDigest .getInstance (hAlgorithm ).digest (data );
@@ -310,7 +294,7 @@ private byte[] hmac(final byte[] bytes, final String key) throws SaslException {
310
294
try {
311
295
Mac mac = Mac .getInstance (hmacAlgorithm );
312
296
mac .init (new SecretKeySpec (bytes , hmacAlgorithm ));
313
- return mac .doFinal (decodeUTF8 ( key ));
297
+ return mac .doFinal (key . getBytes ( StandardCharsets . UTF_8 ));
314
298
} catch (NoSuchAlgorithmException e ) {
315
299
throw new SaslException (format ("Algorithm for '%s' could not be found." , hmacAlgorithm ), e );
316
300
} catch (InvalidKeyException e ) {
@@ -462,8 +446,8 @@ public int hashCode() {
462
446
}
463
447
464
448
private static class CacheValue {
465
- private byte [] clientKey ;
466
- private byte [] serverKey ;
449
+ private final byte [] clientKey ;
450
+ private final byte [] serverKey ;
467
451
468
452
CacheValue (final byte [] clientKey , final byte [] serverKey ) {
469
453
this .clientKey = clientKey ;
0 commit comments