PrivateKeyFactory
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cryptlib;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.EdEC;
using Org.BouncyCastle.Asn1.Gnu;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Rosstandart;
using Org.BouncyCastle.Asn1.Sec;
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.Utilities;
using System;
using System.IO;
namespace Org.BouncyCastle.Security
{
public static class PrivateKeyFactory
{
public static AsymmetricKeyParameter CreateKey(byte[] privateKeyInfoData)
{
return CreateKey(PrivateKeyInfo.GetInstance(privateKeyInfoData));
}
public static AsymmetricKeyParameter CreateKey(Stream inStr)
{
return CreateKey(PrivateKeyInfo.GetInstance(Asn1Object.FromStream(inStr)));
}
public static AsymmetricKeyParameter CreateKey(PrivateKeyInfo keyInfo)
{
AlgorithmIdentifier privateKeyAlgorithm = keyInfo.PrivateKeyAlgorithm;
DerObjectIdentifier algorithm = privateKeyAlgorithm.Algorithm;
if (algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption) || algorithm.Equals(X509ObjectIdentifiers.IdEARsa) || algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss) || algorithm.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) {
RsaPrivateKeyStructure instance = RsaPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
return new RsaPrivateCrtKeyParameters(instance.Modulus, instance.PublicExponent, instance.PrivateExponent, instance.Prime1, instance.Prime2, instance.Exponent1, instance.Exponent2, instance.Coefficient);
}
if (algorithm.Equals(PkcsObjectIdentifiers.DhKeyAgreement)) {
DHParameter instance2 = DHParameter.GetInstance(privateKeyAlgorithm.Parameters);
DerInteger obj = (DerInteger)keyInfo.ParsePrivateKey();
return new DHPrivateKeyParameters(parameters: new DHParameters(l: instance2.L?.IntValue ?? 0, p: instance2.P, g: instance2.G, q: null), x: obj.Value, algorithmOid: algorithm);
}
if (algorithm.Equals(OiwObjectIdentifiers.ElGamalAlgorithm)) {
ElGamalParameter instance3 = ElGamalParameter.GetInstance(privateKeyAlgorithm.Parameters);
return new ElGamalPrivateKeyParameters(((DerInteger)keyInfo.ParsePrivateKey()).Value, new ElGamalParameters(instance3.P, instance3.G));
}
if (algorithm.Equals(X9ObjectIdentifiers.IdDsa)) {
DerInteger obj2 = (DerInteger)keyInfo.ParsePrivateKey();
Asn1Encodable parameters2 = privateKeyAlgorithm.Parameters;
DsaParameters parameters3 = null;
if (parameters2 != null) {
DsaParameter instance4 = DsaParameter.GetInstance(parameters2.ToAsn1Object());
parameters3 = new DsaParameters(instance4.P, instance4.Q, instance4.G);
}
return new DsaPrivateKeyParameters(obj2.Value, parameters3);
}
if (algorithm.Equals(X9ObjectIdentifiers.IdECPublicKey)) {
ECPrivateKeyStructure instance5 = ECPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
ECDomainParameters parameters4 = ECDomainParameters.FromX962Parameters(X962Parameters.GetInstance(privateKeyAlgorithm.Parameters));
return new ECPrivateKeyParameters("EC", instance5.GetKey(), parameters4);
}
if (algorithm.Equals(CryptoProObjectIdentifiers.GostR3410x2001) || algorithm.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) || algorithm.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256)) {
Asn1Object asn1Object = privateKeyAlgorithm.Parameters.ToAsn1Object();
Gost3410PublicKeyAlgParameters instance6 = Gost3410PublicKeyAlgParameters.GetInstance(asn1Object);
ECGost3410Parameters dp = null;
Asn1Sequence asn1Sequence = asn1Object as Asn1Sequence;
BigInteger d;
if (asn1Sequence != null && (asn1Sequence.Count == 2 || asn1Sequence.Count == 3)) {
X9ECParameters byOid = ECGost3410NamedCurves.GetByOid(instance6.PublicKeyParamSet);
if (byOid == null)
throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
dp = new ECGost3410Parameters(new ECNamedDomainParameters(instance6.PublicKeyParamSet, byOid), instance6.PublicKeyParamSet, instance6.DigestParamSet, instance6.EncryptionParamSet);
int privateKeyLength = keyInfo.PrivateKeyLength;
if (privateKeyLength == 32 || privateKeyLength == 64)
d = new BigInteger(1, keyInfo.PrivateKey.GetOctets(), false);
else {
Asn1Object asn1Object2 = keyInfo.ParsePrivateKey();
DerInteger derInteger = asn1Object2 as DerInteger;
if (derInteger != null)
d = derInteger.PositiveValue;
else {
byte[] octets = Asn1OctetString.GetInstance(asn1Object2).GetOctets();
d = new BigInteger(1, octets, false);
}
}
} else {
X962Parameters instance7 = X962Parameters.GetInstance(asn1Object);
if (!instance7.IsImplicitlyCA)
dp = new ECGost3410Parameters(ECDomainParameters.FromX962Parameters(instance7), instance6.PublicKeyParamSet, instance6.DigestParamSet, instance6.EncryptionParamSet);
Asn1Object asn1Object3 = keyInfo.ParsePrivateKey();
DerInteger derInteger2 = asn1Object3 as DerInteger;
d = ((derInteger2 == null) ? ECPrivateKeyStructure.GetInstance(asn1Object3).GetKey() : derInteger2.Value);
}
return new ECPrivateKeyParameters(d, new ECGost3410Parameters(dp, instance6.PublicKeyParamSet, instance6.DigestParamSet, instance6.EncryptionParamSet));
}
if (algorithm.Equals(CryptoProObjectIdentifiers.GostR3410x94)) {
Gost3410PublicKeyAlgParameters instance8 = Gost3410PublicKeyAlgParameters.GetInstance(privateKeyAlgorithm.Parameters);
Asn1Object asn1Object4 = keyInfo.ParsePrivateKey();
BigInteger x = (!(asn1Object4 is DerInteger)) ? new BigInteger(1, Asn1OctetString.GetInstance(asn1Object4).GetOctets(), false) : DerInteger.GetInstance(asn1Object4).PositiveValue;
return new Gost3410PrivateKeyParameters(x, instance8.PublicKeyParamSet);
}
if (algorithm.Equals(EdECObjectIdentifiers.id_X25519) || algorithm.Equals(CryptlibObjectIdentifiers.curvey25519)) {
if (X25519PrivateKeyParameters.KeySize == keyInfo.PrivateKeyLength)
return new X25519PrivateKeyParameters(keyInfo.PrivateKey.GetOctets());
return new X25519PrivateKeyParameters(GetRawKey(keyInfo));
}
if (algorithm.Equals(EdECObjectIdentifiers.id_X448)) {
if (X448PrivateKeyParameters.KeySize == keyInfo.PrivateKeyLength)
return new X448PrivateKeyParameters(keyInfo.PrivateKey.GetOctets());
return new X448PrivateKeyParameters(GetRawKey(keyInfo));
}
if (algorithm.Equals(EdECObjectIdentifiers.id_Ed25519) || algorithm.Equals(GnuObjectIdentifiers.Ed25519))
return new Ed25519PrivateKeyParameters(GetRawKey(keyInfo));
if (algorithm.Equals(EdECObjectIdentifiers.id_Ed448))
return new Ed448PrivateKeyParameters(GetRawKey(keyInfo));
if (algorithm.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) || algorithm.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) || algorithm.Equals(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_256) || algorithm.Equals(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_512)) {
Gost3410PublicKeyAlgParameters instance9 = Gost3410PublicKeyAlgParameters.GetInstance(keyInfo.PrivateKeyAlgorithm.Parameters);
ECGost3410Parameters dp2 = null;
Asn1Object asn1Object5 = keyInfo.PrivateKeyAlgorithm.Parameters.ToAsn1Object();
BigInteger d2;
if (asn1Object5 is Asn1Sequence && (Asn1Sequence.GetInstance(asn1Object5).Count == 2 || Asn1Sequence.GetInstance(asn1Object5).Count == 3)) {
X9ECParameters byOid2 = ECGost3410NamedCurves.GetByOid(instance9.PublicKeyParamSet);
dp2 = new ECGost3410Parameters(new ECNamedDomainParameters(instance9.PublicKeyParamSet, byOid2), instance9.PublicKeyParamSet, instance9.DigestParamSet, instance9.EncryptionParamSet);
int privateKeyLength2 = keyInfo.PrivateKeyLength;
if (privateKeyLength2 == 32 || privateKeyLength2 == 64)
d2 = new BigInteger(1, keyInfo.PrivateKey.GetOctets(), false);
else {
Asn1Encodable asn1Encodable = keyInfo.ParsePrivateKey();
DerInteger optional = DerInteger.GetOptional(asn1Encodable);
if (optional != null)
d2 = optional.PositiveValue;
else {
byte[] octets2 = Asn1OctetString.GetInstance(asn1Encodable).GetOctets();
d2 = new BigInteger(1, octets2, false);
}
}
} else {
X962Parameters instance10 = X962Parameters.GetInstance(keyInfo.PrivateKeyAlgorithm.Parameters);
if (!instance10.IsImplicitlyCA)
dp2 = new ECGost3410Parameters(ECDomainParameters.FromX962Parameters(instance10), instance9.PublicKeyParamSet, instance9.DigestParamSet, instance9.EncryptionParamSet);
Asn1Encodable asn1Encodable2 = keyInfo.ParsePrivateKey();
DerInteger optional2 = DerInteger.GetOptional(asn1Encodable2);
d2 = ((optional2 == null) ? ECPrivateKeyStructure.GetInstance(asn1Encodable2).GetKey() : optional2.Value);
}
return new ECPrivateKeyParameters(d2, new ECGost3410Parameters(dp2, instance9.PublicKeyParamSet, instance9.DigestParamSet, instance9.EncryptionParamSet));
}
if (MLDsaParameters.ByOid.TryGetValue(algorithm, out MLDsaParameters value)) {
Asn1OctetString privateKey = keyInfo.PrivateKey;
int octetsLength = privateKey.GetOctetsLength();
MLDsaParameterSet parameterSet = value.ParameterSet;
if (octetsLength == parameterSet.SeedLength)
return MLDsaPrivateKeyParameters.FromSeed(value, privateKey.GetOctets());
if (octetsLength == parameterSet.PrivateKeyLength)
return MLDsaPrivateKeyParameters.FromEncoding(value, privateKey.GetOctets());
try {
Asn1Object asn1Object6 = Asn1Object.FromByteArray(privateKey.GetOctets());
Asn1TaggedObject asn1TaggedObject = asn1Object6 as Asn1TaggedObject;
if (asn1TaggedObject != null) {
if (asn1TaggedObject.HasContextTag(0)) {
byte[] octets3 = Asn1OctetString.GetInstance(asn1TaggedObject, false).GetOctets();
return MLDsaPrivateKeyParameters.FromSeed(value, octets3);
}
} else {
Asn1OctetString asn1OctetString = asn1Object6 as Asn1OctetString;
if (asn1OctetString != null) {
byte[] octets4 = asn1OctetString.GetOctets();
return MLDsaPrivateKeyParameters.FromEncoding(value, octets4);
}
Asn1Sequence asn1Sequence2 = asn1Object6 as Asn1Sequence;
if (asn1Sequence2 != null && asn1Sequence2.Count == 2) {
byte[] octets5 = Asn1OctetString.GetInstance(asn1Sequence2[0]).GetOctets();
byte[] octets6 = Asn1OctetString.GetInstance(asn1Sequence2[1]).GetOctets();
MLDsaPrivateKeyParameters mLDsaPrivateKeyParameters = MLDsaPrivateKeyParameters.FromSeed(value, octets5, MLDsaPrivateKeyParameters.Format.SeedAndEncoding);
if (!Arrays.FixedTimeEquals(mLDsaPrivateKeyParameters.GetEncoded(), octets6))
throw new ArgumentException("inconsistent " + value.Name + " private key");
return mLDsaPrivateKeyParameters;
}
}
} catch (Exception) {
}
throw new ArgumentException("invalid " + value.Name + " private key");
}
if (MLKemParameters.ByOid.TryGetValue(algorithm, out MLKemParameters value2)) {
Asn1OctetString privateKey2 = keyInfo.PrivateKey;
int octetsLength2 = privateKey2.GetOctetsLength();
MLKemParameterSet parameterSet2 = value2.ParameterSet;
if (octetsLength2 == parameterSet2.SeedLength)
return MLKemPrivateKeyParameters.FromSeed(value2, privateKey2.GetOctets());
if (octetsLength2 == parameterSet2.PrivateKeyLength)
return MLKemPrivateKeyParameters.FromEncoding(value2, privateKey2.GetOctets());
try {
Asn1Object asn1Object7 = Asn1Object.FromByteArray(privateKey2.GetOctets());
Asn1TaggedObject asn1TaggedObject2 = asn1Object7 as Asn1TaggedObject;
if (asn1TaggedObject2 != null) {
if (asn1TaggedObject2.HasContextTag(0)) {
byte[] octets7 = Asn1OctetString.GetInstance(asn1TaggedObject2, false).GetOctets();
return MLKemPrivateKeyParameters.FromSeed(value2, octets7);
}
} else {
Asn1OctetString asn1OctetString2 = asn1Object7 as Asn1OctetString;
if (asn1OctetString2 != null) {
byte[] octets8 = asn1OctetString2.GetOctets();
return MLKemPrivateKeyParameters.FromEncoding(value2, octets8);
}
Asn1Sequence asn1Sequence3 = asn1Object7 as Asn1Sequence;
if (asn1Sequence3 != null && asn1Sequence3.Count == 2) {
byte[] octets9 = Asn1OctetString.GetInstance(asn1Sequence3[0]).GetOctets();
byte[] octets10 = Asn1OctetString.GetInstance(asn1Sequence3[1]).GetOctets();
MLKemPrivateKeyParameters mLKemPrivateKeyParameters = MLKemPrivateKeyParameters.FromSeed(value2, octets9, MLKemPrivateKeyParameters.Format.SeedAndEncoding);
if (!Arrays.FixedTimeEquals(mLKemPrivateKeyParameters.GetEncoded(), octets10))
throw new ArgumentException("inconsistent " + value2.Name + " private key");
return mLKemPrivateKeyParameters;
}
}
} catch (Exception) {
}
throw new ArgumentException("invalid " + value2.Name + " private key");
}
if (SlhDsaParameters.ByOid.TryGetValue(algorithm, out SlhDsaParameters value3)) {
int privateKeyLength3 = value3.ParameterSet.PrivateKeyLength;
Asn1OctetString privateKey3 = keyInfo.PrivateKey;
int octetsLength3 = privateKey3.GetOctetsLength();
if (octetsLength3 == privateKeyLength3)
return SlhDsaPrivateKeyParameters.FromEncoding(value3, privateKey3.GetOctets());
if (octetsLength3 > privateKeyLength3)
try {
Asn1OctetString asn1OctetString3 = Asn1Object.FromByteArray(privateKey3.GetOctets()) as Asn1OctetString;
if (asn1OctetString3 != null) {
byte[] octets11 = asn1OctetString3.GetOctets();
return MLKemPrivateKeyParameters.FromEncoding(value2, octets11);
}
} catch (Exception) {
}
throw new ArgumentException("invalid " + value3.Name + " private key");
}
throw new SecurityUtilityException("algorithm identifier in private key not recognised");
}
private static ReadOnlySpan<byte> GetRawKey(PrivateKeyInfo keyInfo)
{
return Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctetsSpan();
}
public static AsymmetricKeyParameter DecryptKey(char[] passPhrase, EncryptedPrivateKeyInfo encInfo)
{
return CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(passPhrase, encInfo));
}
public static AsymmetricKeyParameter DecryptKey(char[] passPhrase, byte[] encryptedPrivateKeyInfoData)
{
return DecryptKey(passPhrase, EncryptedPrivateKeyInfo.GetInstance(encryptedPrivateKeyInfoData));
}
public static AsymmetricKeyParameter DecryptKey(char[] passPhrase, Stream encryptedPrivateKeyInfoStream)
{
return DecryptKey(passPhrase, EncryptedPrivateKeyInfo.GetInstance(Asn1Object.FromStream(encryptedPrivateKeyInfoStream)));
}
public static byte[] EncryptKey(DerObjectIdentifier algorithm, char[] passPhrase, byte[] salt, int iterationCount, AsymmetricKeyParameter key)
{
return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(algorithm, passPhrase, salt, iterationCount, key).GetEncoded();
}
public static byte[] EncryptKey(string algorithm, char[] passPhrase, byte[] salt, int iterationCount, AsymmetricKeyParameter key)
{
return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(algorithm, passPhrase, salt, iterationCount, key).GetEncoded();
}
}
}