PemReader
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Utilities.IO.Pem;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.IO;
namespace Org.BouncyCastle.OpenSsl
{
public class PemReader : Org.BouncyCastle.Utilities.IO.Pem.PemReader
{
private readonly IPasswordFinder pFinder;
static PemReader()
{
}
public PemReader(TextReader reader)
: this(reader, null)
{
}
public PemReader(TextReader reader, IPasswordFinder pFinder)
: base(reader)
{
this.pFinder = pFinder;
}
public object ReadObject()
{
PemObject pemObject = ReadPemObject();
if (pemObject == null)
return null;
if (Platform.EndsWith(pemObject.Type, "PRIVATE KEY"))
return ReadPrivateKey(pemObject);
string type = pemObject.Type;
if (type != null) {
switch (type.Length) {
case 10:
if (type == "PUBLIC KEY")
return ReadPublicKey(pemObject);
break;
case 14:
if (type == "RSA PUBLIC KEY")
return ReadRsaPublicKey(pemObject);
break;
case 19:
if (!(type == "CERTIFICATE REQUEST"))
break;
goto IL_015d;
case 23:
if (!(type == "NEW CERTIFICATE REQUEST"))
break;
goto IL_015d;
case 11:
if (!(type == "CERTIFICATE"))
break;
goto IL_0165;
case 16:
if (!(type == "X509 CERTIFICATE"))
break;
goto IL_0165;
case 5:
if (!(type == "PKCS7"))
break;
goto IL_016d;
case 3:
if (!(type == "CMS"))
break;
goto IL_016d;
case 8:
if (type == "X509 CRL")
return ReadCrl(pemObject);
break;
case 21:
{
if (type == "ATTRIBUTE CERTIFICATE")
return ReadAttributeCertificate(pemObject);
break;
}
IL_016d:
return ReadPkcs7(pemObject);
IL_0165:
return ReadCertificate(pemObject);
IL_015d:
return ReadCertificateRequest(pemObject);
}
}
throw new IOException("unrecognised object: " + pemObject.Type);
}
private AsymmetricKeyParameter ReadRsaPublicKey(PemObject pemObject)
{
RsaPublicKeyStructure instance = RsaPublicKeyStructure.GetInstance(pemObject.Content);
return new RsaKeyParameters(false, instance.Modulus, instance.PublicExponent);
}
private AsymmetricKeyParameter ReadPublicKey(PemObject pemObject)
{
return PublicKeyFactory.CreateKey(pemObject.Content);
}
private X509Certificate ReadCertificate(PemObject pemObject)
{
try {
return new X509Certificate(pemObject.Content);
} catch (Exception ex) {
throw new PemException("problem parsing cert: " + ex.ToString());
}
}
private X509Crl ReadCrl(PemObject pemObject)
{
try {
return new X509Crl(pemObject.Content);
} catch (Exception ex) {
throw new PemException("problem parsing cert: " + ex.ToString());
}
}
private Pkcs10CertificationRequest ReadCertificateRequest(PemObject pemObject)
{
try {
return new Pkcs10CertificationRequest(pemObject.Content);
} catch (Exception ex) {
throw new PemException("problem parsing cert: " + ex.ToString());
}
}
private X509V2AttributeCertificate ReadAttributeCertificate(PemObject pemObject)
{
return new X509V2AttributeCertificate(pemObject.Content);
}
private Org.BouncyCastle.Asn1.Cms.ContentInfo ReadPkcs7(PemObject pemObject)
{
try {
return Org.BouncyCastle.Asn1.Cms.ContentInfo.GetInstance(pemObject.Content);
} catch (Exception ex) {
throw new PemException("problem parsing PKCS7 object: " + ex.ToString());
}
}
private object ReadPrivateKey(PemObject pemObject)
{
string text = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();
byte[] array = pemObject.Content;
Dictionary<string, string> dictionary = new Dictionary<string, string>();
foreach (PemHeader header in pemObject.Headers) {
dictionary[header.Name] = header.Value;
}
if (CollectionUtilities.GetValueOrNull(dictionary, "Proc-Type") == "4,ENCRYPTED") {
if (pFinder == null)
throw new PasswordException("No password finder specified, but a password is required");
char[] password = pFinder.GetPassword();
if (password == null)
throw new PasswordException("Password is null, but a password is required");
if (!dictionary.TryGetValue("DEK-Info", out string value))
throw new PemException("missing DEK-info");
string[] array2 = value.Split(',', StringSplitOptions.None);
string dekAlgName = array2[0].Trim();
byte[] array3 = Hex.Decode(array2[1].Trim());
array = PemUtilities.Crypt(false, array, password, dekAlgName, array3);
}
try {
Asn1Sequence instance = Asn1Sequence.GetInstance(array);
AsymmetricKeyParameter publicParameter;
AsymmetricKeyParameter asymmetricKeyParameter;
switch (text) {
default:
if (text.Length == 0)
return PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(instance));
goto case null;
case "RSA": {
if (instance.Count != 9)
throw new PemException("malformed sequence in RSA private key");
RsaPrivateKeyStructure instance3 = RsaPrivateKeyStructure.GetInstance(instance);
publicParameter = new RsaKeyParameters(false, instance3.Modulus, instance3.PublicExponent);
asymmetricKeyParameter = new RsaPrivateCrtKeyParameters(instance3.Modulus, instance3.PublicExponent, instance3.PrivateExponent, instance3.Prime1, instance3.Prime2, instance3.Exponent1, instance3.Exponent2, instance3.Coefficient);
break;
}
case "DSA": {
if (instance.Count != 6)
throw new PemException("malformed sequence in DSA private key");
DerInteger derInteger = (DerInteger)instance[1];
DerInteger derInteger2 = (DerInteger)instance[2];
DerInteger derInteger3 = (DerInteger)instance[3];
DerInteger obj = (DerInteger)instance[4];
DerInteger obj2 = (DerInteger)instance[5];
DsaParameters parameters = new DsaParameters(derInteger.Value, derInteger2.Value, derInteger3.Value);
asymmetricKeyParameter = new DsaPrivateKeyParameters(obj2.Value, parameters);
publicParameter = new DsaPublicKeyParameters(obj.Value, parameters);
break;
}
case "EC": {
ECPrivateKeyStructure instance2 = ECPrivateKeyStructure.GetInstance(instance);
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, instance2.Parameters);
asymmetricKeyParameter = PrivateKeyFactory.CreateKey(new PrivateKeyInfo(algorithmIdentifier, instance2.ToAsn1Object()));
DerBitString publicKey = instance2.PublicKey;
publicParameter = ((publicKey == null) ? ECKeyPairGenerator.GetCorrespondingPublicKey((ECPrivateKeyParameters)asymmetricKeyParameter) : PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(algorithmIdentifier, publicKey)));
break;
}
case "ENCRYPTED": {
char[] password2 = pFinder.GetPassword();
if (password2 == null)
throw new PasswordException("Password is null, but a password is required");
return PrivateKeyFactory.DecryptKey(password2, EncryptedPrivateKeyInfo.GetInstance(instance));
}
case null:
throw new ArgumentException("Unknown key type: " + text, "type");
}
return new AsymmetricCipherKeyPair(publicParameter, asymmetricKeyParameter);
} catch (IOException) {
throw;
} catch (Exception ex2) {
throw new PemException("problem creating " + text + " private key: " + ex2.ToString());
}
}
}
}