Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/OpenSsl/MiscPemGenerator.cs
2025-10-09 09:57:24 +09:00

222 lines
6.0 KiB
C#

using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
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;
namespace Org.BouncyCastle.OpenSsl;
public class MiscPemGenerator : PemObjectGenerator
{
private object obj;
private string algorithm;
private char[] password;
private SecureRandom random;
public MiscPemGenerator(object obj)
{
this.obj = obj;
}
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");
}
if (obj is AsymmetricCipherKeyPair)
{
return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private);
}
if (obj is PemObject)
{
return (PemObject)obj;
}
if (obj is PemObjectGenerator)
{
return ((PemObjectGenerator)obj).Generate();
}
string type;
byte[] content;
if (obj is X509Certificate)
{
type = "CERTIFICATE";
try
{
content = ((X509Certificate)obj).GetEncoded();
}
catch (CertificateEncodingException ex)
{
throw new IOException("Cannot Encode object: " + ex.ToString());
}
}
else if (obj is X509Crl)
{
type = "X509 CRL";
try
{
content = ((X509Crl)obj).GetEncoded();
}
catch (CrlException ex2)
{
throw new IOException("Cannot Encode object: " + ex2.ToString());
}
}
else if (obj is AsymmetricKeyParameter)
{
AsymmetricKeyParameter asymmetricKeyParameter = (AsymmetricKeyParameter)obj;
if (asymmetricKeyParameter.IsPrivate)
{
content = EncodePrivateKey(asymmetricKeyParameter, out var keyType);
type = keyType + " PRIVATE KEY";
}
else
{
type = "PUBLIC KEY";
content = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(asymmetricKeyParameter).GetDerEncoded();
}
}
else if (obj is IX509AttributeCertificate)
{
type = "ATTRIBUTE CERTIFICATE";
content = ((X509V2AttributeCertificate)obj).GetEncoded();
}
else if (obj is Pkcs10CertificationRequest)
{
type = "CERTIFICATE REQUEST";
content = ((Pkcs10CertificationRequest)obj).GetEncoded();
}
else
{
if (!(obj is Org.BouncyCastle.Asn1.Cms.ContentInfo))
{
throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj));
}
type = "PKCS7";
content = ((Org.BouncyCastle.Asn1.Cms.ContentInfo)obj).GetEncoded();
}
return new PemObject(type, 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");
}
if (obj is AsymmetricCipherKeyPair)
{
return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random);
}
string text = null;
byte[] array = null;
if (obj is AsymmetricKeyParameter)
{
AsymmetricKeyParameter asymmetricKeyParameter = (AsymmetricKeyParameter)obj;
if (asymmetricKeyParameter.IsPrivate)
{
array = EncodePrivateKey(asymmetricKeyParameter, out var keyType);
text = keyType + " PRIVATE KEY";
}
}
if (text == null || array == null)
{
throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj));
}
string text2 = Platform.ToUpperInvariant(algorithm);
if (text2 == "DESEDE")
{
text2 = "DES-EDE3-CBC";
}
int num = (Platform.StartsWith(text2, "AES-") ? 16 : 8);
byte[] array2 = new byte[num];
random.NextBytes(array2);
byte[] content = PemUtilities.Crypt(encrypt: true, array, password, text2, array2);
IList list = Platform.CreateArrayList(2);
list.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
list.Add(new PemHeader("DEK-Info", text2 + "," + Hex.ToHexString(array2)));
return new PemObject(text, list, content);
}
private static byte[] EncodePrivateKey(AsymmetricKeyParameter akp, out string keyType)
{
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp);
AlgorithmIdentifier privateKeyAlgorithm = privateKeyInfo.PrivateKeyAlgorithm;
DerObjectIdentifier derObjectIdentifier = privateKeyAlgorithm.Algorithm;
if (derObjectIdentifier.Equals(X9ObjectIdentifiers.IdDsa))
{
keyType = "DSA";
DsaParameter instance = DsaParameter.GetInstance(privateKeyAlgorithm.Parameters);
BigInteger x = ((DsaPrivateKeyParameters)akp).X;
BigInteger value = instance.G.ModPow(x, instance.P);
return new DerSequence(new DerInteger(0), new DerInteger(instance.P), new DerInteger(instance.Q), new DerInteger(instance.G), new DerInteger(value), new DerInteger(x)).GetEncoded();
}
if (derObjectIdentifier.Equals(PkcsObjectIdentifiers.RsaEncryption))
{
keyType = "RSA";
}
else
{
if (!derObjectIdentifier.Equals(CryptoProObjectIdentifiers.GostR3410x2001) && !derObjectIdentifier.Equals(X9ObjectIdentifiers.IdECPublicKey))
{
throw new ArgumentException("Cannot handle private key of type: " + Platform.GetTypeName(akp), "akp");
}
keyType = "EC";
}
return privateKeyInfo.ParsePrivateKey().GetEncoded();
}
public PemObject Generate()
{
try
{
if (algorithm != null)
{
return CreatePemObject(obj, algorithm, password, random);
}
return CreatePemObject(obj);
}
catch (IOException exception)
{
throw new PemGenerationException("encoding exception", exception);
}
}
}