summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/gitblit/models/UserModel.java10
-rw-r--r--src/main/java/com/gitblit/utils/SecureRandom.java83
-rw-r--r--src/test/java/com/gitblit/utils/SecureRandomTest.java33
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));
+ }
+}