From b63ceb54bb494700b27e493c7486be7641d4ac54 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Tue, 09 Feb 2016 13:54:57 +0000
Subject: [PATCH] Added BCrypt unit test (port of the original JUnit tests to testNG).
---
opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 225 insertions(+), 0 deletions(-)
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java b/opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java
new file mode 100644
index 0000000..32c7c6f
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java
@@ -0,0 +1,225 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright (c) 2006 Damien Miller <djm@mindrot.org>
+ * Portions Copyright 2016 ForgeRock AS
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+package org.opends.server.extensions;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class BCryptTest extends ExtensionsTestCase {
+
+ /**
+ * Retrieves a set of passwords, salt and expected hashed passwords for tests.
+ */
+ @DataProvider(name = "PasswordsAndHash")
+ public Object[][] getPasswordsAndHash() {
+ return new Object[][]{
+ { "", "$2a$06$DCq7YPn5Rq63x1Lad4cll.",
+ "$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s." },
+ { "", "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.",
+ "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye" },
+ { "", "$2a$10$k1wbIrmNyFAPwPVPSVa/ze",
+ "$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW" },
+ { "", "$2a$12$k42ZFHFWqBp3vWli.nIn8u",
+ "$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO" },
+ { "a", "$2a$06$m0CrhHm10qJ3lXRY.5zDGO",
+ "$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe" },
+ { "a", "$2a$08$cfcvVd2aQ8CMvoMpP2EBfe",
+ "$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V." },
+ { "a", "$2a$10$k87L/MF28Q673VKh8/cPi.",
+ "$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u" },
+ { "a", "$2a$12$8NJH3LsPrANStV6XtBakCe",
+ "$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS" },
+ { "abc", "$2a$06$If6bvum7DFjUnE9p2uDeDu",
+ "$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i" },
+ { "abc", "$2a$08$Ro0CUfOqk6cXEKf3dyaM7O",
+ "$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm" },
+ { "abc", "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.",
+ "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi" },
+ { "abc", "$2a$12$EXRkfkdmXn2gzds2SSitu.",
+ "$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q" },
+ { "abcdefghijklmnopqrstuvwxyz", "$2a$06$.rCVZVOThsIa97pEDOxvGu",
+ "$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC" },
+ { "abcdefghijklmnopqrstuvwxyz", "$2a$08$aTsUwsyowQuzRrDqFflhge",
+ "$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz." },
+ { "abcdefghijklmnopqrstuvwxyz", "$2a$10$fVH8e28OQRj9tqiDXs1e1u",
+ "$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq" },
+ { "abcdefghijklmnopqrstuvwxyz", "$2a$12$D4G5f18o7aMMfwasBL7Gpu",
+ "$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG" },
+ { "~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$06$fPIsBO8qRqkjj273rfaOI.",
+ "$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO" },
+ { "~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$08$Eq2r4G/76Wv39MzSX262hu",
+ "$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW" },
+ { "~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$10$LgfYWkbzEvQ4JakH7rOvHe",
+ "$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS" },
+ { "~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$12$WApznUOJfkEGSmYRfnkrPO",
+ "$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC" }
+ };
+ }
+
+ /**
+ * Retrieves a set of passwords for tests.
+ */
+ @DataProvider(name = "Passwords")
+ public Object[][] getPasswords() {
+ return new Object[][]{
+ {""},
+ {"a"},
+ {"abc"},
+ {"abcdefghijklmnopqrstuvwxyz"},
+ {"~!@#$%^&*() ~!@#$%^&*()PNBFRD"}
+ };
+ }
+
+ /**
+ * Retrieves a pair of password and hashed passwords that don't match
+ */
+ @DataProvider(name = "BadPasswords")
+ public Object[][] getBadPasswords() {
+ return new Object[][]{
+ { "", "$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe" },
+ { "a", "$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i" },
+ { "abc", "$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC" },
+ { "abcdefghijklmnopqrstuvwxyz", "$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO" },
+ { "~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s." }
+ };
+ }
+
+
+ /**
+ * Test for BCrypt.hashpw(String, String).
+ *
+ * @param plain The plain text password.
+ * @param salt The salt to use when hashing the password.
+ * @param expected The expected hashed password.
+ *
+ */
+ @Test(dataProvider = "PasswordsAndHash")
+ public void hashpw(String plain, String salt, String expected) {
+ String hashed = BCrypt.hashpw(plain, salt);
+ assertEquals(hashed, expected);
+ }
+
+ /**
+ * Test for the BCrypt.hashpw(byte[], String) method.
+ *
+ * @param plain The plain text password.
+ * @param salt The salt to use when hashing the password.
+ * @param expected The expected hashed password.
+ *
+ */
+ @Test(dataProvider = "PasswordsAndHash")
+ public void hashpwBytes(String plain, String salt, String expected) {
+ String hashed = BCrypt.hashpw(plain.getBytes(), salt);
+ assertEquals(hashed, expected);
+ }
+
+ /**
+ * Test for the BCrypt.genSalt(int) method, with a cost varying from 4 to 12.
+ *
+ * @param plain The plain text password.
+ *
+ */
+ @Test(dataProvider = "Passwords")
+ public void genSaltInt(String plain) {
+ for (int i = 4; i <= 12; i++){
+ String salt = BCrypt.gensalt(i);
+ String hashed1 = BCrypt.hashpw(plain, salt);
+ String hashed2 = BCrypt.hashpw(plain, hashed1);
+ assertEquals(hashed1, hashed2);
+ }
+ }
+
+ /**
+ * Tests the BCrypt.genSalt method with default cost
+ *
+ * @param plain The plain text password.
+ *
+ */
+ @Test(dataProvider = "Passwords")
+ public void genSalt(String plain) {
+ String salt = BCrypt.gensalt();
+ String hashed1 = BCrypt.hashpw(plain, salt);
+ String hashed2 = BCrypt.hashpw(plain, hashed1);
+ assertEquals(hashed1, hashed2);
+ }
+
+ /**
+ * Test for the BCrypt.checkpw(String, String) method.
+ *
+ * @param plain The plain text password.
+ * @param salt The salt to use when hashing the password.
+ * @param expected The expected hashed password.
+ *
+ */
+ @Test(dataProvider = "PasswordsAndHash")
+ public void checkPw(String plain, String salt, String expected) {
+ assertTrue(BCrypt.checkpw(plain, expected));
+ }
+
+ /**
+ * Test for the BCrypt.checkpw(String, String) method, expecting failures.
+ *
+ * @param plain The plain text password.
+ * @param hashedValue A hashed password that doesn't match the plain text password.
+ *
+ */
+ @Test(dataProvider = "BadPasswords")
+ public void checkPw_Failure(String plain, String hashedValue) {
+ assertFalse(BCrypt.checkpw(plain, hashedValue));
+ }
+
+ /**
+ * Test for correct hashing of non-US-ASCII passwords.
+ */
+ @Test
+ public void testInternationalChars() {
+ String pw1 = "\u2605\u2605\u2605\u2605\u2605\u2605\u2605\u2605";
+ String pw2 = "????????";
+
+ String h1 = BCrypt.hashpw(pw1, BCrypt.gensalt());
+ assertFalse(BCrypt.checkpw(pw2, h1));
+
+ String h2 = BCrypt.hashpw(pw2, BCrypt.gensalt());
+ assertFalse(BCrypt.checkpw(pw1, h2));
+ }
+}
--
Gitblit v1.10.0