init commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class AsymmetricKeyEntry : Pkcs12Entry
|
||||
{
|
||||
private readonly AsymmetricKeyParameter key;
|
||||
|
||||
public AsymmetricKeyParameter Key => key;
|
||||
|
||||
public AsymmetricKeyEntry(AsymmetricKeyParameter key)
|
||||
: base(Platform.CreateHashtable())
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public AsymmetricKeyEntry(AsymmetricKeyParameter key, Hashtable attributes)
|
||||
: base(attributes)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public AsymmetricKeyEntry(AsymmetricKeyParameter key, IDictionary attributes)
|
||||
: base(attributes)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is AsymmetricKeyEntry asymmetricKeyEntry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return key.Equals(asymmetricKeyEntry.key);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ~key.GetHashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public sealed class EncryptedPrivateKeyInfoFactory
|
||||
{
|
||||
private EncryptedPrivateKeyInfoFactory()
|
||||
{
|
||||
}
|
||||
|
||||
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(DerObjectIdentifier algorithm, char[] passPhrase, byte[] salt, int iterationCount, AsymmetricKeyParameter key)
|
||||
{
|
||||
return CreateEncryptedPrivateKeyInfo(algorithm.Id, passPhrase, salt, iterationCount, PrivateKeyInfoFactory.CreatePrivateKeyInfo(key));
|
||||
}
|
||||
|
||||
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(string algorithm, char[] passPhrase, byte[] salt, int iterationCount, AsymmetricKeyParameter key)
|
||||
{
|
||||
return CreateEncryptedPrivateKeyInfo(algorithm, passPhrase, salt, iterationCount, PrivateKeyInfoFactory.CreatePrivateKeyInfo(key));
|
||||
}
|
||||
|
||||
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(string algorithm, char[] passPhrase, byte[] salt, int iterationCount, PrivateKeyInfo keyInfo)
|
||||
{
|
||||
if (!(PbeUtilities.CreateEngine(algorithm) is IBufferedCipher bufferedCipher))
|
||||
{
|
||||
throw new Exception("Unknown encryption algorithm: " + algorithm);
|
||||
}
|
||||
Asn1Encodable asn1Encodable = PbeUtilities.GenerateAlgorithmParameters(algorithm, salt, iterationCount);
|
||||
ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(algorithm, passPhrase, asn1Encodable);
|
||||
bufferedCipher.Init(forEncryption: true, parameters);
|
||||
byte[] encoding = bufferedCipher.DoFinal(keyInfo.GetEncoded());
|
||||
DerObjectIdentifier objectIdentifier = PbeUtilities.GetObjectIdentifier(algorithm);
|
||||
AlgorithmIdentifier algId = new AlgorithmIdentifier(objectIdentifier, asn1Encodable);
|
||||
return new EncryptedPrivateKeyInfo(algId, encoding);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Asn1.Oiw;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.TeleTrust;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Operators;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class Pkcs10CertificationRequest : CertificationRequest
|
||||
{
|
||||
protected static readonly IDictionary algorithms;
|
||||
|
||||
protected static readonly IDictionary exParams;
|
||||
|
||||
protected static readonly IDictionary keyAlgorithms;
|
||||
|
||||
protected static readonly IDictionary oids;
|
||||
|
||||
protected static readonly ISet noParams;
|
||||
|
||||
static Pkcs10CertificationRequest()
|
||||
{
|
||||
algorithms = Platform.CreateHashtable();
|
||||
exParams = Platform.CreateHashtable();
|
||||
keyAlgorithms = Platform.CreateHashtable();
|
||||
oids = Platform.CreateHashtable();
|
||||
noParams = new HashSet();
|
||||
algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption);
|
||||
algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption);
|
||||
algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption);
|
||||
algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption);
|
||||
algorithms.Add("RSAWITHMD5", PkcsObjectIdentifiers.MD5WithRsaEncryption);
|
||||
algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
|
||||
algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
|
||||
algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
|
||||
algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
|
||||
algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
|
||||
algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
|
||||
algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
|
||||
algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
|
||||
algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
|
||||
algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
|
||||
algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("RSAWITHSHA1", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
|
||||
algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
|
||||
algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
|
||||
algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
|
||||
algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
|
||||
algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
|
||||
algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
|
||||
algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1);
|
||||
algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1);
|
||||
algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
|
||||
algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
|
||||
algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384);
|
||||
algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512);
|
||||
algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
|
||||
algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
|
||||
algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
|
||||
algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
|
||||
algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
|
||||
algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
|
||||
algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
|
||||
algorithms.Add("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
|
||||
algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
oids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1WITHRSA");
|
||||
oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA");
|
||||
oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA");
|
||||
oids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384WITHRSA");
|
||||
oids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512WITHRSA");
|
||||
oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, "GOST3411WITHGOST3410");
|
||||
oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001, "GOST3411WITHECGOST3410");
|
||||
oids.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption, "MD5WITHRSA");
|
||||
oids.Add(PkcsObjectIdentifiers.MD2WithRsaEncryption, "MD2WITHRSA");
|
||||
oids.Add(X9ObjectIdentifiers.IdDsaWithSha1, "SHA1WITHDSA");
|
||||
oids.Add(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1WITHECDSA");
|
||||
oids.Add(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224WITHECDSA");
|
||||
oids.Add(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256WITHECDSA");
|
||||
oids.Add(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384WITHECDSA");
|
||||
oids.Add(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512WITHECDSA");
|
||||
oids.Add(OiwObjectIdentifiers.MD5WithRsa, "MD5WITHRSA");
|
||||
oids.Add(OiwObjectIdentifiers.Sha1WithRsa, "SHA1WITHRSA");
|
||||
oids.Add(OiwObjectIdentifiers.DsaWithSha1, "SHA1WITHDSA");
|
||||
oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA");
|
||||
oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA");
|
||||
keyAlgorithms.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA");
|
||||
keyAlgorithms.Add(X9ObjectIdentifiers.IdDsa, "DSA");
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
|
||||
noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
|
||||
noParams.Add(NistObjectIdentifiers.DsaWithSha224);
|
||||
noParams.Add(NistObjectIdentifiers.DsaWithSha256);
|
||||
noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
|
||||
noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
AlgorithmIdentifier hashAlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
|
||||
exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(hashAlgId, 20));
|
||||
AlgorithmIdentifier hashAlgId2 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
|
||||
exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(hashAlgId2, 28));
|
||||
AlgorithmIdentifier hashAlgId3 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
|
||||
exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(hashAlgId3, 32));
|
||||
AlgorithmIdentifier hashAlgId4 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
|
||||
exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(hashAlgId4, 48));
|
||||
AlgorithmIdentifier hashAlgId5 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
|
||||
exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(hashAlgId5, 64));
|
||||
}
|
||||
|
||||
private static RsassaPssParameters CreatePssParams(AlgorithmIdentifier hashAlgId, int saltSize)
|
||||
{
|
||||
return new RsassaPssParameters(hashAlgId, new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), new DerInteger(saltSize), new DerInteger(1));
|
||||
}
|
||||
|
||||
protected Pkcs10CertificationRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequest(byte[] encoded)
|
||||
: base((Asn1Sequence)Asn1Object.FromByteArray(encoded))
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequest(Asn1Sequence seq)
|
||||
: base(seq)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequest(Stream input)
|
||||
: base((Asn1Sequence)Asn1Object.FromStream(input))
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequest(string signatureAlgorithm, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes, AsymmetricKeyParameter signingKey)
|
||||
: this(new Asn1SignatureFactory(signatureAlgorithm, signingKey), subject, publicKey, attributes)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use constructor without 'signingKey' parameter (ignored here)")]
|
||||
public Pkcs10CertificationRequest(ISignatureFactory signatureFactory, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes, AsymmetricKeyParameter signingKey)
|
||||
: this(signatureFactory, subject, publicKey, attributes)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequest(ISignatureFactory signatureFactory, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes)
|
||||
{
|
||||
if (signatureFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException("signatureFactory");
|
||||
}
|
||||
if (subject == null)
|
||||
{
|
||||
throw new ArgumentNullException("subject");
|
||||
}
|
||||
if (publicKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("publicKey");
|
||||
}
|
||||
if (publicKey.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("expected public key", "publicKey");
|
||||
}
|
||||
Init(signatureFactory, subject, publicKey, attributes);
|
||||
}
|
||||
|
||||
private void Init(ISignatureFactory signatureFactory, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes)
|
||||
{
|
||||
sigAlgId = (AlgorithmIdentifier)signatureFactory.AlgorithmDetails;
|
||||
SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
|
||||
reqInfo = new CertificationRequestInfo(subject, pkInfo, attributes);
|
||||
IStreamCalculator streamCalculator = signatureFactory.CreateCalculator();
|
||||
byte[] derEncoded = reqInfo.GetDerEncoded();
|
||||
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
sigBits = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect());
|
||||
}
|
||||
|
||||
public AsymmetricKeyParameter GetPublicKey()
|
||||
{
|
||||
return PublicKeyFactory.CreateKey(reqInfo.SubjectPublicKeyInfo);
|
||||
}
|
||||
|
||||
public bool Verify()
|
||||
{
|
||||
return Verify(GetPublicKey());
|
||||
}
|
||||
|
||||
public bool Verify(AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
return Verify(new Asn1VerifierFactoryProvider(publicKey));
|
||||
}
|
||||
|
||||
public bool Verify(IVerifierFactoryProvider verifierProvider)
|
||||
{
|
||||
return Verify(verifierProvider.CreateVerifierFactory(sigAlgId));
|
||||
}
|
||||
|
||||
public bool Verify(IVerifierFactory verifier)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] derEncoded = reqInfo.GetDerEncoded();
|
||||
IStreamCalculator streamCalculator = verifier.CreateCalculator();
|
||||
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
return ((IVerifier)streamCalculator.GetResult()).IsVerified(sigBits.GetOctets());
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new SignatureException("exception encoding TBS cert request", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetSignatureParameters(ISigner signature, Asn1Encodable asn1Params)
|
||||
{
|
||||
if (asn1Params != null && !(asn1Params is Asn1Null) && Platform.EndsWith(signature.AlgorithmName, "MGF1"))
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("signature algorithm with MGF1");
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetSignatureName(AlgorithmIdentifier sigAlgId)
|
||||
{
|
||||
Asn1Encodable parameters = sigAlgId.Parameters;
|
||||
if (parameters != null && !(parameters is Asn1Null) && sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
|
||||
{
|
||||
RsassaPssParameters instance = RsassaPssParameters.GetInstance(parameters);
|
||||
return GetDigestAlgName(instance.HashAlgorithm.Algorithm) + "withRSAandMGF1";
|
||||
}
|
||||
return sigAlgId.Algorithm.Id;
|
||||
}
|
||||
|
||||
private static string GetDigestAlgName(DerObjectIdentifier digestAlgOID)
|
||||
{
|
||||
if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID))
|
||||
{
|
||||
return "MD5";
|
||||
}
|
||||
if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA1";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA224";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA256";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA384";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA512";
|
||||
}
|
||||
if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD128";
|
||||
}
|
||||
if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD160";
|
||||
}
|
||||
if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD256";
|
||||
}
|
||||
if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID))
|
||||
{
|
||||
return "GOST3411";
|
||||
}
|
||||
return digestAlgOID.Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class Pkcs10CertificationRequestDelaySigned : Pkcs10CertificationRequest
|
||||
{
|
||||
protected Pkcs10CertificationRequestDelaySigned()
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequestDelaySigned(byte[] encoded)
|
||||
: base(encoded)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequestDelaySigned(Asn1Sequence seq)
|
||||
: base(seq)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequestDelaySigned(Stream input)
|
||||
: base(input)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequestDelaySigned(string signatureAlgorithm, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes, AsymmetricKeyParameter signingKey)
|
||||
: base(signatureAlgorithm, subject, publicKey, attributes, signingKey)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs10CertificationRequestDelaySigned(string signatureAlgorithm, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes)
|
||||
{
|
||||
if (signatureAlgorithm == null)
|
||||
{
|
||||
throw new ArgumentNullException("signatureAlgorithm");
|
||||
}
|
||||
if (subject == null)
|
||||
{
|
||||
throw new ArgumentNullException("subject");
|
||||
}
|
||||
if (publicKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("publicKey");
|
||||
}
|
||||
if (publicKey.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("expected public key", "publicKey");
|
||||
}
|
||||
string text = Platform.ToUpperInvariant(signatureAlgorithm);
|
||||
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)Pkcs10CertificationRequest.algorithms[text];
|
||||
if (derObjectIdentifier == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
derObjectIdentifier = new DerObjectIdentifier(text);
|
||||
}
|
||||
catch (Exception innerException)
|
||||
{
|
||||
throw new ArgumentException("Unknown signature type requested", innerException);
|
||||
}
|
||||
}
|
||||
if (Pkcs10CertificationRequest.noParams.Contains(derObjectIdentifier))
|
||||
{
|
||||
sigAlgId = new AlgorithmIdentifier(derObjectIdentifier);
|
||||
}
|
||||
else if (Pkcs10CertificationRequest.exParams.Contains(text))
|
||||
{
|
||||
sigAlgId = new AlgorithmIdentifier(derObjectIdentifier, (Asn1Encodable)Pkcs10CertificationRequest.exParams[text]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sigAlgId = new AlgorithmIdentifier(derObjectIdentifier, DerNull.Instance);
|
||||
}
|
||||
SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
|
||||
reqInfo = new CertificationRequestInfo(subject, pkInfo, attributes);
|
||||
}
|
||||
|
||||
public byte[] GetDataToSign()
|
||||
{
|
||||
return reqInfo.GetDerEncoded();
|
||||
}
|
||||
|
||||
public void SignRequest(byte[] signedData)
|
||||
{
|
||||
sigBits = new DerBitString(signedData);
|
||||
}
|
||||
|
||||
public void SignRequest(DerBitString signedData)
|
||||
{
|
||||
sigBits = signedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public abstract class Pkcs12Entry
|
||||
{
|
||||
private readonly IDictionary attributes;
|
||||
|
||||
public Asn1Encodable this[DerObjectIdentifier oid] => (Asn1Encodable)attributes[oid.Id];
|
||||
|
||||
public Asn1Encodable this[string oid] => (Asn1Encodable)attributes[oid];
|
||||
|
||||
public IEnumerable BagAttributeKeys => new EnumerableProxy(attributes.Keys);
|
||||
|
||||
protected internal Pkcs12Entry(IDictionary attributes)
|
||||
{
|
||||
this.attributes = attributes;
|
||||
foreach (object attribute in attributes)
|
||||
{
|
||||
DictionaryEntry dictionaryEntry = (DictionaryEntry)attribute;
|
||||
if (!(dictionaryEntry.Key is string))
|
||||
{
|
||||
throw new ArgumentException("Attribute keys must be of type: " + typeof(string).FullName, "attributes");
|
||||
}
|
||||
if (!(dictionaryEntry.Value is Asn1Encodable))
|
||||
{
|
||||
throw new ArgumentException("Attribute values must be of type: " + typeof(Asn1Encodable).FullName, "attributes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use 'object[index]' syntax instead")]
|
||||
public Asn1Encodable GetBagAttribute(DerObjectIdentifier oid)
|
||||
{
|
||||
return (Asn1Encodable)attributes[oid.Id];
|
||||
}
|
||||
|
||||
[Obsolete("Use 'object[index]' syntax instead")]
|
||||
public Asn1Encodable GetBagAttribute(string oid)
|
||||
{
|
||||
return (Asn1Encodable)attributes[oid];
|
||||
}
|
||||
|
||||
[Obsolete("Use 'BagAttributeKeys' property")]
|
||||
public IEnumerator GetBagAttributeKeys()
|
||||
{
|
||||
return attributes.Keys.GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,824 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Oiw;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class Pkcs12Store
|
||||
{
|
||||
internal class CertId
|
||||
{
|
||||
private readonly byte[] id;
|
||||
|
||||
internal byte[] Id => id;
|
||||
|
||||
internal CertId(AsymmetricKeyParameter pubKey)
|
||||
{
|
||||
id = CreateSubjectKeyID(pubKey).GetKeyIdentifier();
|
||||
}
|
||||
|
||||
internal CertId(byte[] id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Arrays.GetHashCode(id);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is CertId certId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Arrays.AreEqual(id, certId.id);
|
||||
}
|
||||
}
|
||||
|
||||
private class IgnoresCaseHashtable : IEnumerable
|
||||
{
|
||||
private readonly IDictionary orig = Platform.CreateHashtable();
|
||||
|
||||
private readonly IDictionary keys = Platform.CreateHashtable();
|
||||
|
||||
public ICollection Keys => orig.Keys;
|
||||
|
||||
public object this[string alias]
|
||||
{
|
||||
get
|
||||
{
|
||||
string key = Platform.ToUpperInvariant(alias);
|
||||
string text = (string)keys[key];
|
||||
if (text == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return orig[text];
|
||||
}
|
||||
set
|
||||
{
|
||||
string key = Platform.ToUpperInvariant(alias);
|
||||
string text = (string)keys[key];
|
||||
if (text != null)
|
||||
{
|
||||
orig.Remove(text);
|
||||
}
|
||||
keys[key] = alias;
|
||||
orig[alias] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection Values => orig.Values;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
orig.Clear();
|
||||
keys.Clear();
|
||||
}
|
||||
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return orig.GetEnumerator();
|
||||
}
|
||||
|
||||
public object Remove(string alias)
|
||||
{
|
||||
string key = Platform.ToUpperInvariant(alias);
|
||||
string text = (string)keys[key];
|
||||
if (text == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
keys.Remove(key);
|
||||
object result = orig[text];
|
||||
orig.Remove(text);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private const int MinIterations = 1024;
|
||||
|
||||
private const int SaltSize = 20;
|
||||
|
||||
private readonly IgnoresCaseHashtable keys = new IgnoresCaseHashtable();
|
||||
|
||||
private readonly IDictionary localIds = Platform.CreateHashtable();
|
||||
|
||||
private readonly IgnoresCaseHashtable certs = new IgnoresCaseHashtable();
|
||||
|
||||
private readonly IDictionary chainCerts = Platform.CreateHashtable();
|
||||
|
||||
private readonly IDictionary keyCerts = Platform.CreateHashtable();
|
||||
|
||||
private readonly DerObjectIdentifier keyAlgorithm;
|
||||
|
||||
private readonly DerObjectIdentifier certAlgorithm;
|
||||
|
||||
private readonly bool useDerEncoding;
|
||||
|
||||
private AsymmetricKeyEntry unmarkedKeyEntry = null;
|
||||
|
||||
public IEnumerable Aliases => new EnumerableProxy(GetAliasesTable().Keys);
|
||||
|
||||
public int Count => GetAliasesTable().Count;
|
||||
|
||||
private static SubjectKeyIdentifier CreateSubjectKeyID(AsymmetricKeyParameter pubKey)
|
||||
{
|
||||
return new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey));
|
||||
}
|
||||
|
||||
internal Pkcs12Store(DerObjectIdentifier keyAlgorithm, DerObjectIdentifier certAlgorithm, bool useDerEncoding)
|
||||
{
|
||||
this.keyAlgorithm = keyAlgorithm;
|
||||
this.certAlgorithm = certAlgorithm;
|
||||
this.useDerEncoding = useDerEncoding;
|
||||
}
|
||||
|
||||
public Pkcs12Store()
|
||||
: this(PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc, PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc, useDerEncoding: false)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs12Store(Stream input, char[] password)
|
||||
: this()
|
||||
{
|
||||
Load(input, password);
|
||||
}
|
||||
|
||||
protected virtual void LoadKeyBag(PrivateKeyInfo privKeyInfo, Asn1Set bagAttributes)
|
||||
{
|
||||
AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(privKeyInfo);
|
||||
IDictionary dictionary = Platform.CreateHashtable();
|
||||
AsymmetricKeyEntry value = new AsymmetricKeyEntry(key, dictionary);
|
||||
string text = null;
|
||||
Asn1OctetString asn1OctetString = null;
|
||||
if (bagAttributes != null)
|
||||
{
|
||||
foreach (Asn1Sequence bagAttribute in bagAttributes)
|
||||
{
|
||||
DerObjectIdentifier instance = DerObjectIdentifier.GetInstance(bagAttribute[0]);
|
||||
Asn1Set instance2 = Asn1Set.GetInstance(bagAttribute[1]);
|
||||
Asn1Encodable asn1Encodable = null;
|
||||
if (instance2.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
asn1Encodable = instance2[0];
|
||||
if (dictionary.Contains(instance.Id))
|
||||
{
|
||||
if (!dictionary[instance.Id].Equals(asn1Encodable))
|
||||
{
|
||||
throw new IOException("attempt to add existing attribute with different value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary.Add(instance.Id, asn1Encodable);
|
||||
}
|
||||
if (instance.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
|
||||
{
|
||||
text = ((DerBmpString)asn1Encodable).GetString();
|
||||
keys[text] = value;
|
||||
}
|
||||
else if (instance.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
|
||||
{
|
||||
asn1OctetString = (Asn1OctetString)asn1Encodable;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (asn1OctetString != null)
|
||||
{
|
||||
string text2 = Hex.ToHexString(asn1OctetString.GetOctets());
|
||||
if (text == null)
|
||||
{
|
||||
keys[text2] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
localIds[text] = text2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unmarkedKeyEntry = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo encPrivKeyInfo, Asn1Set bagAttributes, char[] password, bool wrongPkcs12Zero)
|
||||
{
|
||||
if (password != null)
|
||||
{
|
||||
PrivateKeyInfo privKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, wrongPkcs12Zero, encPrivKeyInfo);
|
||||
LoadKeyBag(privKeyInfo, bagAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(Stream input, char[] password)
|
||||
{
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromStream(input);
|
||||
Pfx pfx = new Pfx(seq);
|
||||
ContentInfo authSafe = pfx.AuthSafe;
|
||||
bool wrongPkcs12Zero = false;
|
||||
if (password != null && pfx.MacData != null)
|
||||
{
|
||||
MacData macData = pfx.MacData;
|
||||
DigestInfo mac = macData.Mac;
|
||||
AlgorithmIdentifier algorithmID = mac.AlgorithmID;
|
||||
byte[] salt = macData.GetSalt();
|
||||
int intValue = macData.IterationCount.IntValue;
|
||||
byte[] octets = ((Asn1OctetString)authSafe.Content).GetOctets();
|
||||
byte[] a = CalculatePbeMac(algorithmID.Algorithm, salt, intValue, password, wrongPkcs12Zero: false, octets);
|
||||
byte[] digest = mac.GetDigest();
|
||||
if (!Arrays.ConstantTimeAreEqual(a, digest))
|
||||
{
|
||||
if (password.Length > 0)
|
||||
{
|
||||
throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
|
||||
}
|
||||
a = CalculatePbeMac(algorithmID.Algorithm, salt, intValue, password, wrongPkcs12Zero: true, octets);
|
||||
if (!Arrays.ConstantTimeAreEqual(a, digest))
|
||||
{
|
||||
throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
|
||||
}
|
||||
wrongPkcs12Zero = true;
|
||||
}
|
||||
}
|
||||
keys.Clear();
|
||||
localIds.Clear();
|
||||
unmarkedKeyEntry = null;
|
||||
IList list = Platform.CreateArrayList();
|
||||
if (authSafe.ContentType.Equals(PkcsObjectIdentifiers.Data))
|
||||
{
|
||||
byte[] octets2 = ((Asn1OctetString)authSafe.Content).GetOctets();
|
||||
AuthenticatedSafe authenticatedSafe = new AuthenticatedSafe((Asn1Sequence)Asn1Object.FromByteArray(octets2));
|
||||
ContentInfo[] contentInfo = authenticatedSafe.GetContentInfo();
|
||||
ContentInfo[] array = contentInfo;
|
||||
foreach (ContentInfo contentInfo2 in array)
|
||||
{
|
||||
DerObjectIdentifier contentType = contentInfo2.ContentType;
|
||||
byte[] array2 = null;
|
||||
if (contentType.Equals(PkcsObjectIdentifiers.Data))
|
||||
{
|
||||
array2 = ((Asn1OctetString)contentInfo2.Content).GetOctets();
|
||||
}
|
||||
else if (contentType.Equals(PkcsObjectIdentifiers.EncryptedData) && password != null)
|
||||
{
|
||||
EncryptedData instance = EncryptedData.GetInstance(contentInfo2.Content);
|
||||
array2 = CryptPbeData(forEncryption: false, instance.EncryptionAlgorithm, password, wrongPkcs12Zero, instance.Content.GetOctets());
|
||||
}
|
||||
if (array2 == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(array2);
|
||||
foreach (Asn1Sequence item in asn1Sequence)
|
||||
{
|
||||
SafeBag safeBag = new SafeBag(item);
|
||||
if (safeBag.BagID.Equals(PkcsObjectIdentifiers.CertBag))
|
||||
{
|
||||
list.Add(safeBag);
|
||||
}
|
||||
else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
|
||||
{
|
||||
LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes, password, wrongPkcs12Zero);
|
||||
}
|
||||
else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
|
||||
{
|
||||
LoadKeyBag(PrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
certs.Clear();
|
||||
chainCerts.Clear();
|
||||
keyCerts.Clear();
|
||||
foreach (SafeBag item2 in list)
|
||||
{
|
||||
CertBag certBag = new CertBag((Asn1Sequence)item2.BagValue);
|
||||
byte[] octets3 = ((Asn1OctetString)certBag.CertValue).GetOctets();
|
||||
X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(octets3);
|
||||
IDictionary dictionary = Platform.CreateHashtable();
|
||||
Asn1OctetString asn1OctetString = null;
|
||||
string text = null;
|
||||
if (item2.BagAttributes != null)
|
||||
{
|
||||
foreach (Asn1Sequence bagAttribute in item2.BagAttributes)
|
||||
{
|
||||
DerObjectIdentifier instance2 = DerObjectIdentifier.GetInstance(bagAttribute[0]);
|
||||
Asn1Set instance3 = Asn1Set.GetInstance(bagAttribute[1]);
|
||||
if (instance3.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Asn1Encodable asn1Encodable = instance3[0];
|
||||
if (dictionary.Contains(instance2.Id))
|
||||
{
|
||||
if (!dictionary[instance2.Id].Equals(asn1Encodable))
|
||||
{
|
||||
throw new IOException("attempt to add existing attribute with different value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary.Add(instance2.Id, asn1Encodable);
|
||||
}
|
||||
if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
|
||||
{
|
||||
text = ((DerBmpString)asn1Encodable).GetString();
|
||||
}
|
||||
else if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
|
||||
{
|
||||
asn1OctetString = (Asn1OctetString)asn1Encodable;
|
||||
}
|
||||
}
|
||||
}
|
||||
CertId certId = new CertId(x509Certificate.GetPublicKey());
|
||||
X509CertificateEntry value = new X509CertificateEntry(x509Certificate, dictionary);
|
||||
chainCerts[certId] = value;
|
||||
if (unmarkedKeyEntry != null)
|
||||
{
|
||||
if (keyCerts.Count == 0)
|
||||
{
|
||||
string text2 = Hex.ToHexString(certId.Id);
|
||||
keyCerts[text2] = value;
|
||||
keys[text2] = unmarkedKeyEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
keys["unmarked"] = unmarkedKeyEntry;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (asn1OctetString != null)
|
||||
{
|
||||
string key = Hex.ToHexString(asn1OctetString.GetOctets());
|
||||
keyCerts[key] = value;
|
||||
}
|
||||
if (text != null)
|
||||
{
|
||||
certs[text] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AsymmetricKeyEntry GetKey(string alias)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
return (AsymmetricKeyEntry)keys[alias];
|
||||
}
|
||||
|
||||
public bool IsCertificateEntry(string alias)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
if (certs[alias] != null)
|
||||
{
|
||||
return keys[alias] == null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsKeyEntry(string alias)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
return keys[alias] != null;
|
||||
}
|
||||
|
||||
private IDictionary GetAliasesTable()
|
||||
{
|
||||
IDictionary dictionary = Platform.CreateHashtable();
|
||||
foreach (string key3 in certs.Keys)
|
||||
{
|
||||
dictionary[key3] = "cert";
|
||||
}
|
||||
foreach (string key4 in keys.Keys)
|
||||
{
|
||||
if (dictionary[key4] == null)
|
||||
{
|
||||
dictionary[key4] = "key";
|
||||
}
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public bool ContainsAlias(string alias)
|
||||
{
|
||||
if (certs[alias] == null)
|
||||
{
|
||||
return keys[alias] != null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public X509CertificateEntry GetCertificate(string alias)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)certs[alias];
|
||||
if (x509CertificateEntry == null)
|
||||
{
|
||||
string text = (string)localIds[alias];
|
||||
x509CertificateEntry = ((text == null) ? ((X509CertificateEntry)keyCerts[alias]) : ((X509CertificateEntry)keyCerts[text]));
|
||||
}
|
||||
return x509CertificateEntry;
|
||||
}
|
||||
|
||||
public string GetCertificateAlias(X509Certificate cert)
|
||||
{
|
||||
if (cert == null)
|
||||
{
|
||||
throw new ArgumentNullException("cert");
|
||||
}
|
||||
foreach (object cert2 in certs)
|
||||
{
|
||||
DictionaryEntry dictionaryEntry = (DictionaryEntry)cert2;
|
||||
X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)dictionaryEntry.Value;
|
||||
if (x509CertificateEntry.Certificate.Equals(cert))
|
||||
{
|
||||
return (string)dictionaryEntry.Key;
|
||||
}
|
||||
}
|
||||
foreach (object keyCert in keyCerts)
|
||||
{
|
||||
DictionaryEntry dictionaryEntry2 = (DictionaryEntry)keyCert;
|
||||
X509CertificateEntry x509CertificateEntry2 = (X509CertificateEntry)dictionaryEntry2.Value;
|
||||
if (x509CertificateEntry2.Certificate.Equals(cert))
|
||||
{
|
||||
return (string)dictionaryEntry2.Key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public X509CertificateEntry[] GetCertificateChain(string alias)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
if (!IsKeyEntry(alias))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
X509CertificateEntry x509CertificateEntry = GetCertificate(alias);
|
||||
if (x509CertificateEntry != null)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
while (x509CertificateEntry != null)
|
||||
{
|
||||
X509Certificate certificate = x509CertificateEntry.Certificate;
|
||||
X509CertificateEntry x509CertificateEntry2 = null;
|
||||
Asn1OctetString extensionValue = certificate.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier);
|
||||
if (extensionValue != null)
|
||||
{
|
||||
AuthorityKeyIdentifier instance = AuthorityKeyIdentifier.GetInstance(Asn1Object.FromByteArray(extensionValue.GetOctets()));
|
||||
if (instance.GetKeyIdentifier() != null)
|
||||
{
|
||||
x509CertificateEntry2 = (X509CertificateEntry)chainCerts[new CertId(instance.GetKeyIdentifier())];
|
||||
}
|
||||
}
|
||||
if (x509CertificateEntry2 == null)
|
||||
{
|
||||
X509Name issuerDN = certificate.IssuerDN;
|
||||
X509Name subjectDN = certificate.SubjectDN;
|
||||
if (!issuerDN.Equivalent(subjectDN))
|
||||
{
|
||||
foreach (CertId key in chainCerts.Keys)
|
||||
{
|
||||
X509CertificateEntry x509CertificateEntry3 = (X509CertificateEntry)chainCerts[key];
|
||||
X509Certificate certificate2 = x509CertificateEntry3.Certificate;
|
||||
X509Name subjectDN2 = certificate2.SubjectDN;
|
||||
if (subjectDN2.Equivalent(issuerDN))
|
||||
{
|
||||
try
|
||||
{
|
||||
certificate.Verify(certificate2.GetPublicKey());
|
||||
x509CertificateEntry2 = x509CertificateEntry3;
|
||||
}
|
||||
catch (InvalidKeyException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
list.Add(x509CertificateEntry);
|
||||
x509CertificateEntry = ((x509CertificateEntry2 == x509CertificateEntry) ? null : x509CertificateEntry2);
|
||||
}
|
||||
X509CertificateEntry[] array = new X509CertificateEntry[list.Count];
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
array[i] = (X509CertificateEntry)list[i];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetCertificateEntry(string alias, X509CertificateEntry certEntry)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
if (certEntry == null)
|
||||
{
|
||||
throw new ArgumentNullException("certEntry");
|
||||
}
|
||||
if (keys[alias] != null)
|
||||
{
|
||||
throw new ArgumentException("There is a key entry with the name " + alias + ".");
|
||||
}
|
||||
certs[alias] = certEntry;
|
||||
chainCerts[new CertId(certEntry.Certificate.GetPublicKey())] = certEntry;
|
||||
}
|
||||
|
||||
public void SetKeyEntry(string alias, AsymmetricKeyEntry keyEntry, X509CertificateEntry[] chain)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
if (keyEntry == null)
|
||||
{
|
||||
throw new ArgumentNullException("keyEntry");
|
||||
}
|
||||
if (keyEntry.Key.IsPrivate && chain == null)
|
||||
{
|
||||
throw new ArgumentException("No certificate chain for private key");
|
||||
}
|
||||
if (keys[alias] != null)
|
||||
{
|
||||
DeleteEntry(alias);
|
||||
}
|
||||
keys[alias] = keyEntry;
|
||||
certs[alias] = chain[0];
|
||||
for (int i = 0; i != chain.Length; i++)
|
||||
{
|
||||
chainCerts[new CertId(chain[i].Certificate.GetPublicKey())] = chain[i];
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteEntry(string alias)
|
||||
{
|
||||
if (alias == null)
|
||||
{
|
||||
throw new ArgumentNullException("alias");
|
||||
}
|
||||
AsymmetricKeyEntry asymmetricKeyEntry = (AsymmetricKeyEntry)keys[alias];
|
||||
if (asymmetricKeyEntry != null)
|
||||
{
|
||||
keys.Remove(alias);
|
||||
}
|
||||
X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)certs[alias];
|
||||
if (x509CertificateEntry != null)
|
||||
{
|
||||
certs.Remove(alias);
|
||||
chainCerts.Remove(new CertId(x509CertificateEntry.Certificate.GetPublicKey()));
|
||||
}
|
||||
if (asymmetricKeyEntry != null)
|
||||
{
|
||||
string text = (string)localIds[alias];
|
||||
if (text != null)
|
||||
{
|
||||
localIds.Remove(alias);
|
||||
x509CertificateEntry = (X509CertificateEntry)keyCerts[text];
|
||||
}
|
||||
if (x509CertificateEntry != null)
|
||||
{
|
||||
keyCerts.Remove(text);
|
||||
chainCerts.Remove(new CertId(x509CertificateEntry.Certificate.GetPublicKey()));
|
||||
}
|
||||
}
|
||||
if (x509CertificateEntry == null && asymmetricKeyEntry == null)
|
||||
{
|
||||
throw new ArgumentException("no such entry as " + alias);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEntryOfType(string alias, Type entryType)
|
||||
{
|
||||
if ((object)entryType == typeof(X509CertificateEntry))
|
||||
{
|
||||
return IsCertificateEntry(alias);
|
||||
}
|
||||
if ((object)entryType == typeof(AsymmetricKeyEntry))
|
||||
{
|
||||
if (IsKeyEntry(alias))
|
||||
{
|
||||
return GetCertificate(alias) != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use 'Count' property instead")]
|
||||
public int Size()
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
|
||||
public void Save(Stream stream, char[] password, SecureRandom random)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException("stream");
|
||||
}
|
||||
if (random == null)
|
||||
{
|
||||
throw new ArgumentNullException("random");
|
||||
}
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (string key2 in keys.Keys)
|
||||
{
|
||||
byte[] array = new byte[20];
|
||||
random.NextBytes(array);
|
||||
AsymmetricKeyEntry asymmetricKeyEntry = (AsymmetricKeyEntry)keys[key2];
|
||||
DerObjectIdentifier oid;
|
||||
Asn1Encodable asn1Encodable;
|
||||
if (password == null)
|
||||
{
|
||||
oid = PkcsObjectIdentifiers.KeyBag;
|
||||
asn1Encodable = PrivateKeyInfoFactory.CreatePrivateKeyInfo(asymmetricKeyEntry.Key);
|
||||
}
|
||||
else
|
||||
{
|
||||
oid = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag;
|
||||
asn1Encodable = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(keyAlgorithm, password, array, 1024, asymmetricKeyEntry.Key);
|
||||
}
|
||||
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
||||
foreach (string bagAttributeKey in asymmetricKeyEntry.BagAttributeKeys)
|
||||
{
|
||||
Asn1Encodable obj = asymmetricKeyEntry[bagAttributeKey];
|
||||
if (!bagAttributeKey.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
|
||||
{
|
||||
asn1EncodableVector2.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey), new DerSet(obj)));
|
||||
}
|
||||
}
|
||||
asn1EncodableVector2.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(key2))));
|
||||
if (asymmetricKeyEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
|
||||
{
|
||||
X509CertificateEntry certificate = GetCertificate(key2);
|
||||
AsymmetricKeyParameter publicKey = certificate.Certificate.GetPublicKey();
|
||||
SubjectKeyIdentifier obj2 = CreateSubjectKeyID(publicKey);
|
||||
asn1EncodableVector2.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(obj2)));
|
||||
}
|
||||
asn1EncodableVector.Add(new SafeBag(oid, asn1Encodable.ToAsn1Object(), new DerSet(asn1EncodableVector2)));
|
||||
}
|
||||
byte[] derEncoded = new DerSequence(asn1EncodableVector).GetDerEncoded();
|
||||
ContentInfo contentInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded));
|
||||
byte[] array2 = new byte[20];
|
||||
random.NextBytes(array2);
|
||||
Asn1EncodableVector asn1EncodableVector3 = new Asn1EncodableVector();
|
||||
Pkcs12PbeParams pkcs12PbeParams = new Pkcs12PbeParams(array2, 1024);
|
||||
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(certAlgorithm, pkcs12PbeParams.ToAsn1Object());
|
||||
ISet set = new HashSet();
|
||||
foreach (string key3 in keys.Keys)
|
||||
{
|
||||
X509CertificateEntry certificate2 = GetCertificate(key3);
|
||||
CertBag certBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(certificate2.Certificate.GetEncoded()));
|
||||
Asn1EncodableVector asn1EncodableVector4 = new Asn1EncodableVector();
|
||||
foreach (string bagAttributeKey2 in certificate2.BagAttributeKeys)
|
||||
{
|
||||
Asn1Encodable obj3 = certificate2[bagAttributeKey2];
|
||||
if (!bagAttributeKey2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
|
||||
{
|
||||
asn1EncodableVector4.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey2), new DerSet(obj3)));
|
||||
}
|
||||
}
|
||||
asn1EncodableVector4.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(key3))));
|
||||
if (certificate2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
|
||||
{
|
||||
AsymmetricKeyParameter publicKey2 = certificate2.Certificate.GetPublicKey();
|
||||
SubjectKeyIdentifier obj4 = CreateSubjectKeyID(publicKey2);
|
||||
asn1EncodableVector4.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(obj4)));
|
||||
}
|
||||
asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, certBag.ToAsn1Object(), new DerSet(asn1EncodableVector4)));
|
||||
set.Add(certificate2.Certificate);
|
||||
}
|
||||
foreach (string key4 in certs.Keys)
|
||||
{
|
||||
X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)certs[key4];
|
||||
if (keys[key4] != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
CertBag certBag2 = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry.Certificate.GetEncoded()));
|
||||
Asn1EncodableVector asn1EncodableVector5 = new Asn1EncodableVector();
|
||||
foreach (string bagAttributeKey3 in x509CertificateEntry.BagAttributeKeys)
|
||||
{
|
||||
if (!bagAttributeKey3.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
|
||||
{
|
||||
Asn1Encodable obj5 = x509CertificateEntry[bagAttributeKey3];
|
||||
if (!bagAttributeKey3.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
|
||||
{
|
||||
asn1EncodableVector5.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey3), new DerSet(obj5)));
|
||||
}
|
||||
}
|
||||
}
|
||||
asn1EncodableVector5.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(key4))));
|
||||
asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, certBag2.ToAsn1Object(), new DerSet(asn1EncodableVector5)));
|
||||
set.Add(x509CertificateEntry.Certificate);
|
||||
}
|
||||
foreach (CertId key5 in chainCerts.Keys)
|
||||
{
|
||||
X509CertificateEntry x509CertificateEntry2 = (X509CertificateEntry)chainCerts[key5];
|
||||
if (set.Contains(x509CertificateEntry2.Certificate))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
CertBag certBag3 = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry2.Certificate.GetEncoded()));
|
||||
Asn1EncodableVector asn1EncodableVector6 = new Asn1EncodableVector();
|
||||
foreach (string bagAttributeKey4 in x509CertificateEntry2.BagAttributeKeys)
|
||||
{
|
||||
if (!bagAttributeKey4.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
|
||||
{
|
||||
asn1EncodableVector6.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey4), new DerSet(x509CertificateEntry2[bagAttributeKey4])));
|
||||
}
|
||||
}
|
||||
asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, certBag3.ToAsn1Object(), new DerSet(asn1EncodableVector6)));
|
||||
}
|
||||
byte[] derEncoded2 = new DerSequence(asn1EncodableVector3).GetDerEncoded();
|
||||
ContentInfo contentInfo2;
|
||||
if (password == null)
|
||||
{
|
||||
contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded2));
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] str = CryptPbeData(forEncryption: true, algorithmIdentifier, password, wrongPkcs12Zero: false, derEncoded2);
|
||||
EncryptedData encryptedData = new EncryptedData(PkcsObjectIdentifiers.Data, algorithmIdentifier, new BerOctetString(str));
|
||||
contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, encryptedData.ToAsn1Object());
|
||||
}
|
||||
ContentInfo[] info = new ContentInfo[2] { contentInfo, contentInfo2 };
|
||||
byte[] encoded = new AuthenticatedSafe(info).GetEncoded(useDerEncoding ? "DER" : "BER");
|
||||
ContentInfo contentInfo3 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encoded));
|
||||
MacData macData = null;
|
||||
if (password != null)
|
||||
{
|
||||
byte[] array3 = new byte[20];
|
||||
random.NextBytes(array3);
|
||||
byte[] digest = CalculatePbeMac(OiwObjectIdentifiers.IdSha1, array3, 1024, password, wrongPkcs12Zero: false, encoded);
|
||||
AlgorithmIdentifier algID = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
|
||||
DigestInfo digInfo = new DigestInfo(algID, digest);
|
||||
macData = new MacData(digInfo, array3, 1024);
|
||||
}
|
||||
Pfx obj6 = new Pfx(contentInfo3, macData);
|
||||
DerOutputStream derOutputStream = ((!useDerEncoding) ? new BerOutputStream(stream) : new DerOutputStream(stream));
|
||||
derOutputStream.WriteObject(obj6);
|
||||
}
|
||||
|
||||
internal static byte[] CalculatePbeMac(DerObjectIdentifier oid, byte[] salt, int itCount, char[] password, bool wrongPkcs12Zero, byte[] data)
|
||||
{
|
||||
Asn1Encodable pbeParameters = PbeUtilities.GenerateAlgorithmParameters(oid, salt, itCount);
|
||||
ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(oid, password, wrongPkcs12Zero, pbeParameters);
|
||||
IMac mac = (IMac)PbeUtilities.CreateEngine(oid);
|
||||
mac.Init(parameters);
|
||||
return MacUtilities.DoFinal(mac, data);
|
||||
}
|
||||
|
||||
private static byte[] CryptPbeData(bool forEncryption, AlgorithmIdentifier algId, char[] password, bool wrongPkcs12Zero, byte[] data)
|
||||
{
|
||||
if (!(PbeUtilities.CreateEngine(algId.Algorithm) is IBufferedCipher bufferedCipher))
|
||||
{
|
||||
throw new Exception("Unknown encryption algorithm: " + algId.Algorithm);
|
||||
}
|
||||
Pkcs12PbeParams instance = Pkcs12PbeParams.GetInstance(algId.Parameters);
|
||||
ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(algId.Algorithm, password, wrongPkcs12Zero, instance);
|
||||
bufferedCipher.Init(forEncryption, parameters);
|
||||
return bufferedCipher.DoFinal(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class Pkcs12StoreBuilder
|
||||
{
|
||||
private DerObjectIdentifier keyAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc;
|
||||
|
||||
private DerObjectIdentifier certAlgorithm = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc;
|
||||
|
||||
private bool useDerEncoding = false;
|
||||
|
||||
public Pkcs12Store Build()
|
||||
{
|
||||
return new Pkcs12Store(keyAlgorithm, certAlgorithm, useDerEncoding);
|
||||
}
|
||||
|
||||
public Pkcs12StoreBuilder SetCertAlgorithm(DerObjectIdentifier certAlgorithm)
|
||||
{
|
||||
this.certAlgorithm = certAlgorithm;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Pkcs12StoreBuilder SetKeyAlgorithm(DerObjectIdentifier keyAlgorithm)
|
||||
{
|
||||
this.keyAlgorithm = keyAlgorithm;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Pkcs12StoreBuilder SetUseDerEncoding(bool useDerEncoding)
|
||||
{
|
||||
this.useDerEncoding = useDerEncoding;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class Pkcs12Utilities
|
||||
{
|
||||
public static byte[] ConvertToDefiniteLength(byte[] berPkcs12File)
|
||||
{
|
||||
Pfx pfx = new Pfx(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(berPkcs12File)));
|
||||
return pfx.GetEncoded("DER");
|
||||
}
|
||||
|
||||
public static byte[] ConvertToDefiniteLength(byte[] berPkcs12File, char[] passwd)
|
||||
{
|
||||
Pfx pfx = new Pfx(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(berPkcs12File)));
|
||||
ContentInfo authSafe = pfx.AuthSafe;
|
||||
Asn1OctetString instance = Asn1OctetString.GetInstance(authSafe.Content);
|
||||
Asn1Object asn1Object = Asn1Object.FromByteArray(instance.GetOctets());
|
||||
authSafe = new ContentInfo(authSafe.ContentType, new DerOctetString(asn1Object.GetEncoded("DER")));
|
||||
MacData macData = pfx.MacData;
|
||||
try
|
||||
{
|
||||
int intValue = macData.IterationCount.IntValue;
|
||||
byte[] octets = Asn1OctetString.GetInstance(authSafe.Content).GetOctets();
|
||||
byte[] digest = Pkcs12Store.CalculatePbeMac(macData.Mac.AlgorithmID.Algorithm, macData.GetSalt(), intValue, passwd, wrongPkcs12Zero: false, octets);
|
||||
AlgorithmIdentifier algID = new AlgorithmIdentifier(macData.Mac.AlgorithmID.Algorithm, DerNull.Instance);
|
||||
DigestInfo digInfo = new DigestInfo(algID, digest);
|
||||
macData = new MacData(digInfo, macData.GetSalt(), intValue);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException("error constructing MAC: " + ex.ToString());
|
||||
}
|
||||
pfx = new Pfx(authSafe, macData);
|
||||
return pfx.GetEncoded("DER");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class Pkcs8EncryptedPrivateKeyInfo
|
||||
{
|
||||
private EncryptedPrivateKeyInfo encryptedPrivateKeyInfo;
|
||||
|
||||
private static EncryptedPrivateKeyInfo parseBytes(byte[] pkcs8Encoding)
|
||||
{
|
||||
try
|
||||
{
|
||||
return EncryptedPrivateKeyInfo.GetInstance(pkcs8Encoding);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
throw new PkcsIOException("malformed data: " + ex.Message, ex);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
throw new PkcsIOException("malformed data: " + ex2.Message, ex2);
|
||||
}
|
||||
}
|
||||
|
||||
public Pkcs8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo)
|
||||
{
|
||||
this.encryptedPrivateKeyInfo = encryptedPrivateKeyInfo;
|
||||
}
|
||||
|
||||
public Pkcs8EncryptedPrivateKeyInfo(byte[] encryptedPrivateKeyInfo)
|
||||
: this(parseBytes(encryptedPrivateKeyInfo))
|
||||
{
|
||||
}
|
||||
|
||||
public EncryptedPrivateKeyInfo ToAsn1Structure()
|
||||
{
|
||||
return encryptedPrivateKeyInfo;
|
||||
}
|
||||
|
||||
public byte[] GetEncryptedData()
|
||||
{
|
||||
return encryptedPrivateKeyInfo.GetEncryptedData();
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return encryptedPrivateKeyInfo.GetEncoded();
|
||||
}
|
||||
|
||||
public PrivateKeyInfo DecryptPrivateKeyInfo(IDecryptorBuilderProvider inputDecryptorProvider)
|
||||
{
|
||||
try
|
||||
{
|
||||
ICipherBuilder cipherBuilder = inputDecryptorProvider.CreateDecryptorBuilder(encryptedPrivateKeyInfo.EncryptionAlgorithm);
|
||||
ICipher cipher = cipherBuilder.BuildCipher(new MemoryInputStream(encryptedPrivateKeyInfo.GetEncryptedData()));
|
||||
Stream stream = cipher.Stream;
|
||||
byte[] obj = Streams.ReadAll(cipher.Stream);
|
||||
Platform.Dispose(stream);
|
||||
return PrivateKeyInfo.GetInstance(obj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new PkcsException("unable to read encrypted data: " + ex.Message, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class Pkcs8EncryptedPrivateKeyInfoBuilder
|
||||
{
|
||||
private PrivateKeyInfo privateKeyInfo;
|
||||
|
||||
public Pkcs8EncryptedPrivateKeyInfoBuilder(byte[] privateKeyInfo)
|
||||
: this(PrivateKeyInfo.GetInstance(privateKeyInfo))
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs8EncryptedPrivateKeyInfoBuilder(PrivateKeyInfo privateKeyInfo)
|
||||
{
|
||||
this.privateKeyInfo = privateKeyInfo;
|
||||
}
|
||||
|
||||
public Pkcs8EncryptedPrivateKeyInfo Build(ICipherBuilder encryptor)
|
||||
{
|
||||
try
|
||||
{
|
||||
MemoryStream memoryStream = new MemoryOutputStream();
|
||||
ICipher cipher = encryptor.BuildCipher(memoryStream);
|
||||
byte[] encoded = privateKeyInfo.GetEncoded();
|
||||
Stream stream = cipher.Stream;
|
||||
stream.Write(encoded, 0, encoded.Length);
|
||||
Platform.Dispose(stream);
|
||||
return new Pkcs8EncryptedPrivateKeyInfo(new EncryptedPrivateKeyInfo((AlgorithmIdentifier)encryptor.AlgorithmDetails, memoryStream.ToArray()));
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
throw new InvalidOperationException("cannot encode privateKeyInfo");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class PkcsException : Exception
|
||||
{
|
||||
public PkcsException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PkcsException(string message, Exception underlying)
|
||||
: base(message, underlying)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class PkcsIOException : IOException
|
||||
{
|
||||
public PkcsIOException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PkcsIOException(string message, Exception underlying)
|
||||
: base(message, underlying)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using Org.BouncyCastle.Asn1.EdEC;
|
||||
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.Generators;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public sealed class PrivateKeyInfoFactory
|
||||
{
|
||||
private PrivateKeyInfoFactory()
|
||||
{
|
||||
}
|
||||
|
||||
public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter privateKey)
|
||||
{
|
||||
return CreatePrivateKeyInfo(privateKey, null);
|
||||
}
|
||||
|
||||
public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter privateKey, Asn1Set attributes)
|
||||
{
|
||||
if (privateKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("privateKey");
|
||||
}
|
||||
if (!privateKey.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Public key passed - private key expected", "privateKey");
|
||||
}
|
||||
if (privateKey is ElGamalPrivateKeyParameters)
|
||||
{
|
||||
ElGamalPrivateKeyParameters elGamalPrivateKeyParameters = (ElGamalPrivateKeyParameters)privateKey;
|
||||
ElGamalParameters parameters = elGamalPrivateKeyParameters.Parameters;
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(parameters.P, parameters.G).ToAsn1Object()), new DerInteger(elGamalPrivateKeyParameters.X), attributes);
|
||||
}
|
||||
if (privateKey is DsaPrivateKeyParameters)
|
||||
{
|
||||
DsaPrivateKeyParameters dsaPrivateKeyParameters = (DsaPrivateKeyParameters)privateKey;
|
||||
DsaParameters parameters2 = dsaPrivateKeyParameters.Parameters;
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, new DsaParameter(parameters2.P, parameters2.Q, parameters2.G).ToAsn1Object()), new DerInteger(dsaPrivateKeyParameters.X), attributes);
|
||||
}
|
||||
if (privateKey is DHPrivateKeyParameters)
|
||||
{
|
||||
DHPrivateKeyParameters dHPrivateKeyParameters = (DHPrivateKeyParameters)privateKey;
|
||||
DHParameter dHParameter = new DHParameter(dHPrivateKeyParameters.Parameters.P, dHPrivateKeyParameters.Parameters.G, dHPrivateKeyParameters.Parameters.L);
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(dHPrivateKeyParameters.AlgorithmOid, dHParameter.ToAsn1Object()), new DerInteger(dHPrivateKeyParameters.X), attributes);
|
||||
}
|
||||
if (privateKey is RsaKeyParameters)
|
||||
{
|
||||
AlgorithmIdentifier privateKeyAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance);
|
||||
RsaPrivateKeyStructure rsaPrivateKeyStructure;
|
||||
if (privateKey is RsaPrivateCrtKeyParameters)
|
||||
{
|
||||
RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)privateKey;
|
||||
rsaPrivateKeyStructure = new RsaPrivateKeyStructure(rsaPrivateCrtKeyParameters.Modulus, rsaPrivateCrtKeyParameters.PublicExponent, rsaPrivateCrtKeyParameters.Exponent, rsaPrivateCrtKeyParameters.P, rsaPrivateCrtKeyParameters.Q, rsaPrivateCrtKeyParameters.DP, rsaPrivateCrtKeyParameters.DQ, rsaPrivateCrtKeyParameters.QInv);
|
||||
}
|
||||
else
|
||||
{
|
||||
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)privateKey;
|
||||
rsaPrivateKeyStructure = new RsaPrivateKeyStructure(rsaKeyParameters.Modulus, BigInteger.Zero, rsaKeyParameters.Exponent, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero);
|
||||
}
|
||||
return new PrivateKeyInfo(privateKeyAlgorithm, rsaPrivateKeyStructure.ToAsn1Object(), attributes);
|
||||
}
|
||||
if (privateKey is ECPrivateKeyParameters)
|
||||
{
|
||||
ECPrivateKeyParameters eCPrivateKeyParameters = (ECPrivateKeyParameters)privateKey;
|
||||
DerBitString publicKey = new DerBitString(ECKeyPairGenerator.GetCorrespondingPublicKey(eCPrivateKeyParameters).Q.GetEncoded(compressed: false));
|
||||
ECDomainParameters parameters3 = eCPrivateKeyParameters.Parameters;
|
||||
if (parameters3 is ECGost3410Parameters)
|
||||
{
|
||||
ECGost3410Parameters eCGost3410Parameters = (ECGost3410Parameters)parameters3;
|
||||
Gost3410PublicKeyAlgParameters parameters4 = new Gost3410PublicKeyAlgParameters(eCGost3410Parameters.PublicKeyParamSet, eCGost3410Parameters.DigestParamSet, eCGost3410Parameters.EncryptionParamSet);
|
||||
bool flag = eCPrivateKeyParameters.D.BitLength > 256;
|
||||
DerObjectIdentifier algorithm = (flag ? RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 : RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256);
|
||||
int num = (flag ? 64 : 32);
|
||||
byte[] array = new byte[num];
|
||||
ExtractBytes(array, num, 0, eCPrivateKeyParameters.D);
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(algorithm, parameters4), new DerOctetString(array));
|
||||
}
|
||||
int bitLength = parameters3.N.BitLength;
|
||||
AlgorithmIdentifier privateKeyAlgorithm2;
|
||||
ECPrivateKeyStructure privateKey2;
|
||||
if (eCPrivateKeyParameters.AlgorithmName == "ECGOST3410")
|
||||
{
|
||||
if (eCPrivateKeyParameters.PublicKeyParamSet == null)
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
|
||||
}
|
||||
Gost3410PublicKeyAlgParameters parameters5 = new Gost3410PublicKeyAlgParameters(eCPrivateKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
|
||||
privateKeyAlgorithm2 = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, parameters5);
|
||||
privateKey2 = new ECPrivateKeyStructure(bitLength, eCPrivateKeyParameters.D, publicKey, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
X962Parameters parameters6;
|
||||
if (eCPrivateKeyParameters.PublicKeyParamSet == null)
|
||||
{
|
||||
X9ECParameters ecParameters = new X9ECParameters(parameters3.Curve, parameters3.G, parameters3.N, parameters3.H, parameters3.GetSeed());
|
||||
parameters6 = new X962Parameters(ecParameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters6 = new X962Parameters(eCPrivateKeyParameters.PublicKeyParamSet);
|
||||
}
|
||||
privateKey2 = new ECPrivateKeyStructure(bitLength, eCPrivateKeyParameters.D, publicKey, parameters6);
|
||||
privateKeyAlgorithm2 = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, parameters6);
|
||||
}
|
||||
return new PrivateKeyInfo(privateKeyAlgorithm2, privateKey2, attributes);
|
||||
}
|
||||
if (privateKey is Gost3410PrivateKeyParameters)
|
||||
{
|
||||
Gost3410PrivateKeyParameters gost3410PrivateKeyParameters = (Gost3410PrivateKeyParameters)privateKey;
|
||||
if (gost3410PrivateKeyParameters.PublicKeyParamSet == null)
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
|
||||
}
|
||||
byte[] array2 = gost3410PrivateKeyParameters.X.ToByteArrayUnsigned();
|
||||
byte[] array3 = new byte[array2.Length];
|
||||
for (int i = 0; i != array3.Length; i++)
|
||||
{
|
||||
array3[i] = array2[array2.Length - 1 - i];
|
||||
}
|
||||
Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters = new Gost3410PublicKeyAlgParameters(gost3410PrivateKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null);
|
||||
AlgorithmIdentifier privateKeyAlgorithm3 = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x94, gost3410PublicKeyAlgParameters.ToAsn1Object());
|
||||
return new PrivateKeyInfo(privateKeyAlgorithm3, new DerOctetString(array3), attributes);
|
||||
}
|
||||
if (privateKey is X448PrivateKeyParameters)
|
||||
{
|
||||
X448PrivateKeyParameters x448PrivateKeyParameters = (X448PrivateKeyParameters)privateKey;
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), new DerOctetString(x448PrivateKeyParameters.GetEncoded()), attributes, x448PrivateKeyParameters.GeneratePublicKey().GetEncoded());
|
||||
}
|
||||
if (privateKey is X25519PrivateKeyParameters)
|
||||
{
|
||||
X25519PrivateKeyParameters x25519PrivateKeyParameters = (X25519PrivateKeyParameters)privateKey;
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), new DerOctetString(x25519PrivateKeyParameters.GetEncoded()), attributes, x25519PrivateKeyParameters.GeneratePublicKey().GetEncoded());
|
||||
}
|
||||
if (privateKey is Ed448PrivateKeyParameters)
|
||||
{
|
||||
Ed448PrivateKeyParameters ed448PrivateKeyParameters = (Ed448PrivateKeyParameters)privateKey;
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), new DerOctetString(ed448PrivateKeyParameters.GetEncoded()), attributes, ed448PrivateKeyParameters.GeneratePublicKey().GetEncoded());
|
||||
}
|
||||
if (privateKey is Ed25519PrivateKeyParameters)
|
||||
{
|
||||
Ed25519PrivateKeyParameters ed25519PrivateKeyParameters = (Ed25519PrivateKeyParameters)privateKey;
|
||||
return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), new DerOctetString(ed25519PrivateKeyParameters.GetEncoded()), attributes, ed25519PrivateKeyParameters.GeneratePublicKey().GetEncoded());
|
||||
}
|
||||
throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(privateKey));
|
||||
}
|
||||
|
||||
public static PrivateKeyInfo CreatePrivateKeyInfo(char[] passPhrase, EncryptedPrivateKeyInfo encInfo)
|
||||
{
|
||||
return CreatePrivateKeyInfo(passPhrase, wrongPkcs12Zero: false, encInfo);
|
||||
}
|
||||
|
||||
public static PrivateKeyInfo CreatePrivateKeyInfo(char[] passPhrase, bool wrongPkcs12Zero, EncryptedPrivateKeyInfo encInfo)
|
||||
{
|
||||
AlgorithmIdentifier encryptionAlgorithm = encInfo.EncryptionAlgorithm;
|
||||
if (!(PbeUtilities.CreateEngine(encryptionAlgorithm) is IBufferedCipher bufferedCipher))
|
||||
{
|
||||
throw new Exception("Unknown encryption algorithm: " + encryptionAlgorithm.Algorithm);
|
||||
}
|
||||
ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(encryptionAlgorithm, passPhrase, wrongPkcs12Zero);
|
||||
bufferedCipher.Init(forEncryption: false, parameters);
|
||||
byte[] obj = bufferedCipher.DoFinal(encInfo.GetEncryptedData());
|
||||
return PrivateKeyInfo.GetInstance(obj);
|
||||
}
|
||||
|
||||
private static void ExtractBytes(byte[] encKey, int size, int offSet, BigInteger bI)
|
||||
{
|
||||
byte[] array = bI.ToByteArray();
|
||||
if (array.Length < size)
|
||||
{
|
||||
byte[] array2 = new byte[size];
|
||||
Array.Copy(array, 0, array2, array2.Length - array.Length, array.Length);
|
||||
array = array2;
|
||||
}
|
||||
for (int i = 0; i != size; i++)
|
||||
{
|
||||
encKey[offSet + i] = array[array.Length - 1 - i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkcs;
|
||||
|
||||
public class X509CertificateEntry : Pkcs12Entry
|
||||
{
|
||||
private readonly X509Certificate cert;
|
||||
|
||||
public X509Certificate Certificate => cert;
|
||||
|
||||
public X509CertificateEntry(X509Certificate cert)
|
||||
: base(Platform.CreateHashtable())
|
||||
{
|
||||
this.cert = cert;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public X509CertificateEntry(X509Certificate cert, Hashtable attributes)
|
||||
: base(attributes)
|
||||
{
|
||||
this.cert = cert;
|
||||
}
|
||||
|
||||
public X509CertificateEntry(X509Certificate cert, IDictionary attributes)
|
||||
: base(attributes)
|
||||
{
|
||||
this.cert = cert;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is X509CertificateEntry x509CertificateEntry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return cert.Equals(x509CertificateEntry.cert);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ~cert.GetHashCode();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user