package org.spongycastle.openssl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Reader;
import java.security.cert.CertificateFactory;
import java.util.HashMap;
import java.util.Map;
import org.spongycastle.util.io.pem.PemObject;
import org.spongycastle.util.io.pem.PemObjectParser;
import org.spongycastle.util.io.pem.PemReader;
/**
* Class for reading OpenSSL PEM encoded streams containing
* X509 certificates, PKCS8 encoded keys and PKCS7 objects.
* <p>
* In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and
* Certificates will be returned using the appropriate java.security type (KeyPair, PublicKey, X509Certificate,
* or X509CRL). In the case of a Certificate Request a PKCS10CertificationRequest will be returned.
* </p>
*/
public class PEMReader
extends PemReader
{
private final Map<String, PemObjectParser> parsers = new HashMap<String, PemObjectParser>();
/**
* Create a new PEMReader
*
* @param reader the Reader
*/
public PEMReader(
Reader reader)
{
this(reader, "BC");
}
/**
* Create a new PEMReader with a password finder and differing providers for secret and public key
* operations.
*
* @param reader the Reader
* @param pFinder the password finder
* @param symProvider provider to use for symmetric operations
* @param asymProvider provider to use for asymmetric (public/private key) operations
*/
public PEMReader(
Reader reader,
String asymProvider)
{
super(reader);
parsers.put("CERTIFICATE", new X509CertificateParser(asymProvider));
parsers.put("X509 CERTIFICATE", new X509CertificateParser(asymProvider));
}
public Object readObject()
throws IOException
{
PemObject obj = readPemObject();
if (obj != null)
{
String type = obj.getType();
if (parsers.containsKey(type))
{
return ((PemObjectParser)parsers.get(type)).parseObject(obj);
}
else
{
throw new IOException("unrecognised object: " + type);
}
}
return null;
}
private class X509CertificateParser
implements PemObjectParser
{
private String provider;
public X509CertificateParser(String provider)
{
this.provider = provider;
}
/**
* Reads in a X509Certificate.
*
* @return the X509Certificate
* @throws IOException if an I/O error occured
*/
public Object parseObject(PemObject obj)
throws IOException
{
ByteArrayInputStream bIn = new ByteArrayInputStream(obj.getContent());
try
{
CertificateFactory certFact
= CertificateFactory.getInstance("X.509", provider);
return certFact.generateCertificate(bIn);
}
catch (Exception e)
{
throw new PEMException("problem parsing cert: " + e.toString(), e);
}
}
}
}