blob: 5457688ca26e1f708e2828ce25248487cf26f791 [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 tests.security;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import junit.framework.TestCase;
public abstract class MessageDigestTest extends TestCase {
private String digestAlgorithmName;
protected MessageDigestTest(String digestAlgorithmName) {
super();
this.digestAlgorithmName = digestAlgorithmName;
}
private MessageDigest digest;
private InputStream sourceData;
private byte[] checkDigest;
@Override
protected void setUp() throws Exception {
super.setUp();
this.source3 = getLongMessage(1000000);
this.digest = getMessageDigest();
this.sourceData = getSourceData();
this.checkDigest = getCheckDigest();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
// This is critical. The MessageDigest tests consume a lot of memory due
// to the 1 MB buffers being allocated. We need to make sure all data is
// freed after each test. Otherwise the Android runtime simply dies at
// some point.
source1 = null;
source2 = null;
source3 = null;
expected1 = null;
expected2 = null;
expected3 = null;
digest = null;
sourceData.close();
sourceData = null;
checkDigest = null;
System.gc();
}
MessageDigest getMessageDigest() {
try {
return MessageDigest.getInstance(digestAlgorithmName);
} catch (NoSuchAlgorithmException e) {
fail("failed to get digest instance: " + e);
return null;
}
}
InputStream getSourceData() {
InputStream sourceStream = getClass().getResourceAsStream(digestAlgorithmName + ".data");
assertNotNull("digest source data not found: " + digestAlgorithmName, sourceStream);
return sourceStream;
}
byte[] getCheckDigest() {
InputStream checkDigestStream =
getClass().getResourceAsStream(digestAlgorithmName + ".check");
byte[] checkDigest = new byte[digest.getDigestLength()];
int read = 0;
int index = 0;
try {
while ((read = checkDigestStream.read()) != -1) {
checkDigest[index++] = (byte)read;
}
checkDigestStream.close();
} catch (IOException e) {
fail("failed to read digest golden data: " + digestAlgorithmName);
}
return checkDigest;
}
public void testMessageDigest1() {
byte[] buf = new byte[128];
int read = 0;
try {
while ((read = sourceData.read(buf)) != -1) {
digest.update(buf, 0, read);
}
sourceData.close();
} catch (IOException e) {
fail("failed to read digest data");
}
byte[] computedDigest = digest.digest();
assertNotNull("computed digest is is null", computedDigest);
assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
for (int i = 0; i < checkDigest.length; i++) {
assertEquals("byte " + i + " of computed and check digest differ",
checkDigest[i], computedDigest[i]);
}
}
public void testMessageDigest2() {
int val;
try {
while ((val = sourceData.read()) != -1) {
digest.update((byte)val);
}
sourceData.close();
} catch (IOException e) {
fail("failed to read digest data");
}
byte[] computedDigest = digest.digest();
assertNotNull("computed digest is is null", computedDigest);
assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
for (int i = 0; i < checkDigest.length; i++) {
assertEquals("byte " + i + " of computed and check digest differ",
checkDigest[i], computedDigest[i]);
}
}
/**
* Official FIPS180-2 testcases
*/
protected String source1;
protected String source2;
protected String source3;
protected String expected1;
protected String expected2;
protected String expected3;
String getLongMessage(int length) {
StringBuilder sourceBuilder = new StringBuilder(length);
for (int i = 0; i < length / 10; i++) {
sourceBuilder.append("aaaaaaaaaa");
}
return sourceBuilder.toString();
}
public void testfips180_2_singleblock() {
digest.update(source1.getBytes(), 0, source1.length());
byte[] computedDigest = digest.digest();
assertNotNull("computed digest is null", computedDigest);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < computedDigest.length; i++) {
String res = Integer.toHexString(computedDigest[i] & 0xFF);
sb.append((res.length() == 1 ? "0" : "") + res);
}
assertEquals("computed and check digest differ", expected1, sb.toString());
}
public void testfips180_2_multiblock() {
digest.update(source2.getBytes(), 0, source2.length());
byte[] computedDigest = digest.digest();
assertNotNull("computed digest is null", computedDigest);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < computedDigest.length; i++) {
String res = Integer.toHexString(computedDigest[i] & 0xFF);
sb.append((res.length() == 1 ? "0" : "") + res);
}
assertEquals("computed and check digest differ", expected2, sb.toString());
}
public void testfips180_2_longMessage() {
digest.update(source3.getBytes(), 0, source3.length());
byte[] computedDigest = digest.digest();
assertNotNull("computed digest is null", computedDigest);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < computedDigest.length; i++) {
String res = Integer.toHexString(computedDigest[i] & 0xFF);
sb.append((res.length() == 1 ? "0" : "") + res);
}
assertEquals("computed and check digest differ", expected3, sb.toString());
}
}