Skip to content

Commit df16ae3

Browse files
committed
Remove the dependency to java.util.Base64
Generate a random string satisfying the specification's requirements without using Base64 so that the plugin can be used with installations using Java 7
1 parent 8d51832 commit df16ae3

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

src/main/java/org/jenkinsci/plugins/GithubSecurityRealm.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ of this software and associated documentation files (the "Software"), to deal
9090
import java.net.Proxy;
9191
import java.security.SecureRandom;
9292
import java.util.Arrays;
93-
import java.util.Base64;
9493
import java.util.HashSet;
9594
import java.util.Set;
9695
import java.util.logging.Logger;
@@ -339,7 +338,9 @@ public String getOauthScopes() {
339338

340339
public HttpResponse doCommenceLogin(StaplerRequest request, @QueryParameter String from, @Header("Referer") final String referer)
341340
throws IOException {
342-
final String state = getSecureRandomString();
341+
// https://tools.ietf.org/html/rfc6749#section-10.10 dictates that probability that an attacker guesses the string
342+
// SHOULD be less than or equal to 2^(-160) and our Strings consist of 65 chars. (65^27 ~= 2^160)
343+
final String state = getSecureRandomString(27);
343344
String redirectOnFinish;
344345
if (from != null && Util.isSafeToRedirectTo(from)) {
345346
redirectOnFinish = from;
@@ -479,14 +480,19 @@ private String getAccessToken(@Nonnull String code) throws IOException {
479480
}
480481

481482
/**
482-
* Generates a random 20 byte String that conforms to the <a href="https://tools.ietf.org/html/rfc6749#section-10.10">specification</a>
483-
* requirements
484-
* @return a string that can be used as a state parameter
483+
* Generates a random URL Safe String of n characters
485484
*/
486-
private String getSecureRandomString() {
487-
final byte[] bytes = new byte[20];
488-
SECURE_RANDOM.nextBytes(bytes);
489-
return BASE64_ENCODER.encodeToString(bytes);
485+
private String getSecureRandomString(int n) {
486+
if (n < 0){
487+
throw new IllegalArgumentException("Length must be a positive integer");
488+
}
489+
// See RFC3986
490+
final String urlSafeChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_";
491+
final StringBuilder sb = new StringBuilder();
492+
for (int i = 0; i < n ; i++){
493+
sb.append(urlSafeChars.charAt(SECURE_RANDOM.nextInt(urlSafeChars.length())));
494+
}
495+
return sb.toString();
490496
}
491497
/**
492498
* Returns the proxy to be used when connecting to the given URI.
@@ -821,8 +827,6 @@ static Jenkins getJenkins() {
821827

822828
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
823829

824-
private static final Base64.Encoder BASE64_ENCODER = Base64.getUrlEncoder().withoutPadding();
825-
826830
/**
827831
* Asks for the password.
828832
*/

0 commit comments

Comments
 (0)