*/
@Override
public PublicKey readPublicKey(String algorithm, Reader rdr)
throws CryptoException, IOException
{
PEMParser pp = new PEMParser(rdr);
try {
Object po = pp.readObject();
if (log.isDebugEnabled()) {
log.debug("Trying to read an {} public key and got {}", algorithm, po);
}
if (po instanceof SubjectPublicKeyInfo) {
SubjectPublicKeyInfo pk = (SubjectPublicKeyInfo)po;
AlgorithmIdentifier alg = pk.getAlgorithm();
if (!(alg.getParameters() instanceof ASN1Sequence)) {
throw new CryptoException("Invalid DSA public key format: Algorithm ID not a Sequence");
}
ASN1Sequence identifiers = (ASN1Sequence)(alg.getParameters());
if (identifiers.size() != 3) {
throw new CryptoException("Invalid DSA public key format: Identifier does not have 3 items");
}
DERInteger p = (DERInteger)identifiers.getObjectAt(0);
DERInteger q = (DERInteger)identifiers.getObjectAt(1);
DERInteger g = (DERInteger)identifiers.getObjectAt(2);
ASN1Primitive pkPrim = pk.parsePublicKey();
if (!(pkPrim instanceof ASN1Integer)) {
throw new CryptoException("Invalid DSA public key format: Public key is not an integer");
}
DERInteger y = (DERInteger)pkPrim;
try {
KeyFactory factory = KeyFactory.getInstance("DSA");
DSAPublicKeySpec pubSpec = new DSAPublicKeySpec(
y.getValue(),
p.getValue(),
q.getValue(),
g.getValue());
return factory.generatePublic(pubSpec);
} catch (GeneralSecurityException gse) {
throw new CryptoException(gse);
}
}
throw new CryptoException("Input data does not contain a public key");
} finally {
pp.close();
}
}