diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/com/gitblit/models/UserModel.java | 10 | ||||
-rw-r--r-- | src/main/java/com/gitblit/utils/SecureRandom.java | 83 | ||||
-rw-r--r-- | src/test/java/com/gitblit/utils/SecureRandomTest.java | 33 |
3 files changed, 121 insertions, 5 deletions
diff --git a/src/main/java/com/gitblit/models/UserModel.java b/src/main/java/com/gitblit/models/UserModel.java index edbdf028..f8f7ed6d 100644 --- a/src/main/java/com/gitblit/models/UserModel.java +++ b/src/main/java/com/gitblit/models/UserModel.java @@ -37,6 +37,7 @@ import com.gitblit.Constants.PermissionType; import com.gitblit.Constants.RegistrantType;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.ModelUtils;
+import com.gitblit.utils.SecureRandom;
import com.gitblit.utils.StringUtils;
/**
@@ -53,6 +54,8 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> public static final UserModel ANONYMOUS = new UserModel();
+ private static final SecureRandom RANDOM = new SecureRandom();
+
// field names are reflectively mapped in EditUser page
public String username;
public String password;
@@ -661,11 +664,8 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> String projectPath = StringUtils.getFirstPathElement(repository);
return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase(getPersonalPath());
}
-
+
public String createCookie() {
- SecureRandom random = new SecureRandom();
- byte[] values = new byte[20];
- random.nextBytes(values);
- return StringUtils.getSHA1(String.valueOf(values));
+ return StringUtils.getSHA1(RANDOM.randomBytes(32));
}
}
diff --git a/src/main/java/com/gitblit/utils/SecureRandom.java b/src/main/java/com/gitblit/utils/SecureRandom.java new file mode 100644 index 00000000..119533d4 --- /dev/null +++ b/src/main/java/com/gitblit/utils/SecureRandom.java @@ -0,0 +1,83 @@ +/* + * Copyright 2016 gitblit.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.utils; + +/** + * Wrapper class for java.security.SecureRandom, which will periodically reseed + * the PRNG in case an instance of the class has been running for a long time. + * + * @author Florian Zschocke + */ +public class SecureRandom { + + /** Period (in ms) after which a new SecureRandom will be created in order to get a fresh random seed. */ + private static final long RESEED_PERIOD = 24 * 60 * 60 * 1000; /* 24 hours */ + + + private long last; + private java.security.SecureRandom random; + + + + public SecureRandom() { + // Make sure the SecureRandom is seeded right from the start. + // This also lets any blocks during seeding occur at creation + // and prevents it from happening when getting next random bytes. + seed(); + } + + + + public byte[] randomBytes(int num) { + byte[] bytes = new byte[num]; + nextBytes(bytes); + return bytes; + } + + + public void nextBytes(byte[] bytes) { + random.nextBytes(bytes); + reseed(false); + } + + + void reseed(boolean forced) { + long ts = System.currentTimeMillis(); + if (forced || (ts - last) > RESEED_PERIOD) { + last = ts; + runReseed(); + } + } + + + + private void seed() { + random = new java.security.SecureRandom(); + random.nextBytes(new byte[0]); + last = System.currentTimeMillis(); + } + + + private void runReseed() { + // Have some other thread hit the penalty potentially incurred by reseeding, + // so that we can immediately return and not block the operation in progress. + new Thread() { + public void run() { + seed(); + } + }.start(); + } +} diff --git a/src/test/java/com/gitblit/utils/SecureRandomTest.java b/src/test/java/com/gitblit/utils/SecureRandomTest.java new file mode 100644 index 00000000..c4098c2f --- /dev/null +++ b/src/test/java/com/gitblit/utils/SecureRandomTest.java @@ -0,0 +1,33 @@ +package com.gitblit.utils; + +import static org.junit.Assert.*; + +import java.util.Arrays; + +import org.junit.Test; + +public class SecureRandomTest { + + @Test + public void testRandomBytes() { + SecureRandom sr = new SecureRandom(); + byte[] bytes1 = sr.randomBytes(10); + assertEquals(10, bytes1.length); + byte[] bytes2 = sr.randomBytes(10); + assertEquals(10, bytes2.length); + assertFalse(Arrays.equals(bytes1, bytes2)); + + assertEquals(0, sr.randomBytes(0).length); + assertEquals(200, sr.randomBytes(200).length); + } + + @Test + public void testNextBytes() { + SecureRandom sr = new SecureRandom(); + byte[] bytes1 = new byte[32]; + sr.nextBytes(bytes1); + byte[] bytes2 = new byte[32]; + sr.nextBytes(bytes2); + assertFalse(Arrays.equals(bytes1, bytes2)); + } +} |