package org.bouncycastle.crypto.test.cavp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.engines.DESedeEngine;
import org.bouncycastle.crypto.macs.CMac;
import org.bouncycastle.crypto.macs.HMac;
public class CAVPReader
{
private static final Pattern = Pattern.compile("^\\s*\\#\\s*(.*)$");
private static final Pattern CONFIG_PATTERN = Pattern.compile("^\\s*+\\[\\s*+(.*?)\\s*+=\\s*+(.*?)\\s*+\\]\\s*+$");
private static final Pattern VECTOR_PATTERN = Pattern.compile("^\\s*+(.*?)\\s*+=\\s*+(.*?)\\s*+$");
private static final Pattern EMPTY_PATTERN = Pattern.compile("^\\s*+$");
static final Pattern PATTERN_FOR_R = Pattern.compile("(\\d+)_BITS");
private final CAVPListener listener;
private String name;
private BufferedReader lineReader;
public CAVPReader(CAVPListener listener)
{
this.listener = listener;
}
public void setInput(String name, Reader reader)
{
this.name = name;
this.lineReader = new BufferedReader(reader);
}
public void readAll()
throws IOException
{
listener.setup();
Properties config = new Properties();
boolean startNewVector = true;
Properties vectors = new Properties();
while (true)
{
final String line = lineReader.readLine();
if (line == null)
{
listener.receiveEnd();
break;
}
final Matcher commentMatcher = COMMENT_PATTERN.matcher(line);
if (commentMatcher.matches())
{
listener.receiveCommentLine(commentMatcher.group(1));
continue;
}
final Matcher configMatcher = CONFIG_PATTERN.matcher(line);
if (configMatcher.matches())
{
config.put(configMatcher.group(1), configMatcher.group(2));
continue;
}
final Matcher vectorMatcher = VECTOR_PATTERN.matcher(line);
if (vectorMatcher.matches())
{
vectors.put(vectorMatcher.group(1), vectorMatcher.group(2));
startNewVector = false;
continue;
}
final Matcher emptyMatcher = EMPTY_PATTERN.matcher(line);
if (emptyMatcher.matches())
{
if (startNewVector)
{
continue;
}
listener.receiveCAVPVectors(name, config, vectors);
vectors = new Properties();
startNewVector = true;
}
}
listener.tearDown();
}
static Mac createPRF(Properties config)
{
final Mac prf;
if (config.getProperty("PRF").matches("CMAC_AES\\d\\d\\d"))
{
BlockCipher blockCipher = new AESEngine();
prf = new CMac(blockCipher);
}
else if (config.getProperty("PRF").matches("CMAC_TDES\\d"))
{
BlockCipher blockCipher = new DESedeEngine();
prf = new CMac(blockCipher);
}
else if (config.getProperty("PRF").matches("HMAC_SHA1"))
{
Digest digest = new SHA1Digest();
prf = new HMac(digest);
}
else if (config.getProperty("PRF").matches("HMAC_SHA224"))
{
Digest digest = new SHA224Digest();
prf = new HMac(digest);
}
else if (config.getProperty("PRF").matches("HMAC_SHA256"))
{
Digest digest = new SHA256Digest();
prf = new HMac(digest);
}
else if (config.getProperty("PRF").matches("HMAC_SHA384"))
{
Digest digest = new SHA384Digest();
prf = new HMac(digest);
}
else if (config.getProperty("PRF").matches("HMAC_SHA512"))
{
Digest digest = new SHA512Digest();
prf = new HMac(digest);
}
else
{
throw new IllegalStateException("Unknown Mac for PRF");
}
return prf;
}
}