MiscPemGenerator
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Security.Certificates;
using Org.BouncyCastle.Utilities;
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 MiscPemGenerator : PemObjectGenerator
{
private readonly object obj;
private readonly string algorithm;
private readonly char[] password;
private readonly SecureRandom random;
public MiscPemGenerator(object obj)
: this(obj, null, null, null)
{
}
public MiscPemGenerator(object obj, string algorithm, char[] password, SecureRandom random)
{
this.obj = obj;
this.algorithm = algorithm;
this.password = password;
this.random = random;
}
private static PemObject CreatePemObject(object obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
AsymmetricCipherKeyPair asymmetricCipherKeyPair = obj as AsymmetricCipherKeyPair;
if (asymmetricCipherKeyPair != null)
return CreatePemObject(asymmetricCipherKeyPair.Private);
PemObject pemObject = obj as PemObject;
if (pemObject != null)
return pemObject;
PemObjectGenerator pemObjectGenerator = obj as PemObjectGenerator;
if (pemObjectGenerator != null)
return pemObjectGenerator.Generate();
X509Certificate x509Certificate = obj as X509Certificate;
string keyType;
byte[] content;
if (x509Certificate != null) {
keyType = "CERTIFICATE";
try {
content = x509Certificate.GetEncoded();
} catch (CertificateEncodingException ex) {
throw new IOException("Cannot Encode object: " + ex.ToString());
}
} else {
X509Crl x509Crl = obj as X509Crl;
if (x509Crl != null) {
keyType = "X509 CRL";
try {
content = x509Crl.GetEncoded();
} catch (CrlException ex2) {
throw new IOException("Cannot Encode object: " + ex2.ToString());
}
} else {
AsymmetricKeyParameter asymmetricKeyParameter = obj as AsymmetricKeyParameter;
if (asymmetricKeyParameter != null)
content = ((!asymmetricKeyParameter.IsPrivate) ? EncodePublicKey(asymmetricKeyParameter, out keyType) : EncodePrivateKey(asymmetricKeyParameter, out keyType));
else {
PrivateKeyInfo privateKeyInfo = obj as PrivateKeyInfo;
if (privateKeyInfo != null)
content = EncodePrivateKeyInfo(privateKeyInfo, out keyType);
else {
SubjectPublicKeyInfo subjectPublicKeyInfo = obj as SubjectPublicKeyInfo;
if (subjectPublicKeyInfo != null)
content = EncodePublicKeyInfo(subjectPublicKeyInfo, out keyType);
else {
X509V2AttributeCertificate x509V2AttributeCertificate = obj as X509V2AttributeCertificate;
if (x509V2AttributeCertificate != null) {
keyType = "ATTRIBUTE CERTIFICATE";
content = x509V2AttributeCertificate.GetEncoded();
} else {
Pkcs8EncryptedPrivateKeyInfo pkcs8EncryptedPrivateKeyInfo = obj as Pkcs8EncryptedPrivateKeyInfo;
if (pkcs8EncryptedPrivateKeyInfo != null) {
keyType = "ENCRYPTED PRIVATE KEY";
content = pkcs8EncryptedPrivateKeyInfo.GetEncoded();
} else {
Pkcs10CertificationRequest pkcs10CertificationRequest = obj as Pkcs10CertificationRequest;
if (pkcs10CertificationRequest != null) {
keyType = "CERTIFICATE REQUEST";
content = pkcs10CertificationRequest.GetEncoded();
} else {
Org.BouncyCastle.Asn1.Cms.ContentInfo contentInfo = obj as Org.BouncyCastle.Asn1.Cms.ContentInfo;
if (contentInfo != null) {
keyType = "PKCS7";
content = contentInfo.GetEncoded();
} else {
Org.BouncyCastle.Asn1.Pkcs.ContentInfo contentInfo2 = obj as Org.BouncyCastle.Asn1.Pkcs.ContentInfo;
if (contentInfo2 == null)
throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj));
keyType = "PKCS7";
content = contentInfo2.GetEncoded();
}
}
}
}
}
}
}
}
}
return new PemObject(keyType, content);
}
private static PemObject CreatePemObject(object obj, string algorithm, char[] password, SecureRandom random)
{
if (obj == null)
throw new ArgumentNullException("obj");
if (algorithm == null)
throw new ArgumentNullException("algorithm");
if (password == null)
throw new ArgumentNullException("password");
if (random == null)
throw new ArgumentNullException("random");
AsymmetricCipherKeyPair asymmetricCipherKeyPair = obj as AsymmetricCipherKeyPair;
if (asymmetricCipherKeyPair != null)
return CreatePemObject(asymmetricCipherKeyPair.Private, algorithm, password, random);
string keyType = null;
byte[] array = null;
AsymmetricKeyParameter asymmetricKeyParameter = obj as AsymmetricKeyParameter;
if (asymmetricKeyParameter != null && asymmetricKeyParameter.IsPrivate)
array = EncodePrivateKey(asymmetricKeyParameter, out keyType);
if (keyType == null || array == null)
throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj));
string text = algorithm.ToUpperInvariant();
if (text == "DESEDE")
text = "DES-EDE3-CBC";
byte[] array2 = new byte[Platform.StartsWith(text, "AES-") ? 16 : 8];
random.NextBytes(array2);
byte[] content = PemUtilities.Crypt(true, array, password, text, array2);
List<PemHeader> list = new List<PemHeader>(2);
list.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
list.Add(new PemHeader("DEK-Info", text + "," + Hex.ToHexString(array2, true)));
return new PemObject(keyType, list, content);
}
public PemObject Generate()
{
try {
if (algorithm == null)
return CreatePemObject(obj);
return CreatePemObject(obj, algorithm, password, random);
} catch (IOException innerException) {
throw new PemGenerationException("encoding exception", innerException);
}
}
private static byte[] EncodePrivateKey(AsymmetricKeyParameter akp, out string keyType)
{
return EncodePrivateKeyInfo(PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp), out keyType);
}
private static byte[] EncodePrivateKeyInfo(PrivateKeyInfo info, out string keyType)
{
AlgorithmIdentifier privateKeyAlgorithm = info.PrivateKeyAlgorithm;
DerObjectIdentifier derObjectIdentifier = privateKeyAlgorithm.Algorithm;
if (derObjectIdentifier.Equals(PkcsObjectIdentifiers.RsaEncryption)) {
keyType = "RSA PRIVATE KEY";
return info.ParsePrivateKey().GetEncoded();
}
if (derObjectIdentifier.Equals(X9ObjectIdentifiers.IdECPublicKey) || derObjectIdentifier.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) {
keyType = "EC PRIVATE KEY";
return info.ParsePrivateKey().GetEncoded();
}
if (derObjectIdentifier.Equals(X9ObjectIdentifiers.IdDsa) || derObjectIdentifier.Equals(OiwObjectIdentifiers.DsaWithSha1)) {
keyType = "DSA PRIVATE KEY";
DsaParameter instance = DsaParameter.GetInstance(privateKeyAlgorithm.Parameters);
BigInteger value = DerInteger.GetInstance(info.ParsePrivateKey()).Value;
BigInteger value2 = instance.G.ModPow(value, instance.P);
return new DerSequence(DerInteger.Zero, new DerInteger(instance.P), new DerInteger(instance.Q), new DerInteger(instance.G), new DerInteger(value2), new DerInteger(value)).GetEncoded();
}
keyType = "PRIVATE KEY";
return info.GetEncoded();
}
private static byte[] EncodePublicKey(AsymmetricKeyParameter akp, out string keyType)
{
return EncodePublicKeyInfo(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(akp), out keyType);
}
private static byte[] EncodePublicKeyInfo(SubjectPublicKeyInfo info, out string keyType)
{
keyType = "PUBLIC KEY";
return info.GetEncoded();
}
}
}