/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.usergrid.security.crypto.command; import java.io.UnsupportedEncodingException; import java.util.UUID; import org.junit.Test; import org.apache.usergrid.persistence.CredentialsInfo; import com.yammer.metrics.Metrics; import com.yammer.metrics.core.MetricPredicate; import com.yammer.metrics.core.Timer; import com.yammer.metrics.core.TimerContext; import com.yammer.metrics.reporting.ConsoleReporter; import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString; import static org.junit.Assert.assertArrayEquals; /** @author tnine */ public class BcryptCommandTest { /** Tests bcrypt hashing with a default number of rounds */ @Test public void hashWithNoExistingImpl() throws UnsupportedEncodingException { int cryptIterations = 2 ^ 4; BcryptCommand command = new BcryptCommand(); command.setDefaultIterations( cryptIterations ); String baseString = "I am a test password for hashing"; CredentialsInfo info = new CredentialsInfo(); byte[] result = command.hash( baseString.getBytes( "UTF-8" ), info, null, null ); String stringResults = encodeBase64URLSafeString( result ); info.setSecret( stringResults ); //now check we can auth with the same phrase byte[] authed = command.auth( baseString.getBytes( "UTF-8" ), info, null, null ); assertArrayEquals( result, authed ); } /** Tests bcrypt hashing then auth. This should fail if there's no secret. */ @Test(expected = IllegalArgumentException.class) public void authNoSecret() throws UnsupportedEncodingException { int cryptIterations = 2 ^ 4; BcryptCommand command = new BcryptCommand(); command.setDefaultIterations( cryptIterations ); String baseString = "I am a test password for hashing"; CredentialsInfo info = new CredentialsInfo(); command.hash( baseString.getBytes( "UTF-8" ), info, null, null ); //now check we can't auth since the CI doesn't have any secret on it command.auth( baseString.getBytes( "UTF-8" ), info, null, null ); } /** Tests bcrypt hashing fails when the existing secret is wrong */ @Test(expected = IllegalArgumentException.class) public void authInvalidSecret() throws UnsupportedEncodingException { int cryptIterations = 2 ^ 4; BcryptCommand command = new BcryptCommand(); command.setDefaultIterations( cryptIterations ); String baseString = "I am a test password for hashing"; CredentialsInfo info = new CredentialsInfo(); byte[] result = command.hash( baseString.getBytes( "UTF-8" ), info, null, null ); info.setSecret( "I'm a junk secret that's not bcrypted" ); //now check we can auth with the same phrase byte[] authed = command.auth( baseString.getBytes( "UTF-8" ), info, null, null ); assertArrayEquals( result, authed ); } /** * Tests bcrypt hashing with a default number of rounds. Note that via the console output, this test should take * about 5 seconds to run since we want to force 500 ms per authentication attempt with bcrypt */ @Test public void testHashRoundSpeed() throws UnsupportedEncodingException { int cryptIterations = 2 ^ 11; int numberOfTests = 10; BcryptCommand command = new BcryptCommand(); command.setDefaultIterations( cryptIterations ); String baseString = "I am a test password for hashing"; CredentialsInfo info = new CredentialsInfo(); UUID user = UUID.randomUUID(); UUID applicationId = UUID.randomUUID(); byte[] result = command.hash( baseString.getBytes( "UTF-8" ), info, user, applicationId ); String stringResults = encodeBase64URLSafeString( result ); info.setSecret( stringResults ); Timer timer = Metrics.newTimer( BcryptCommandTest.class, "hashtimer" ); for ( int i = 0; i < numberOfTests; i++ ) { TimerContext timerCtx = timer.time(); //now check we can auth with the same phrase byte[] authed = command.auth( baseString.getBytes( "UTF-8" ), info, user, applicationId ); timerCtx.stop(); assertArrayEquals( result, authed ); } /** * Print out the data */ ConsoleReporter reporter = new ConsoleReporter( Metrics.defaultRegistry(), System.out, MetricPredicate.ALL ); reporter.run(); } }