init commit
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class BaseDigestCalculator : IDigestCalculator
|
||||
{
|
||||
private readonly byte[] digest;
|
||||
|
||||
internal BaseDigestCalculator(byte[] digest)
|
||||
{
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public byte[] GetDigest()
|
||||
{
|
||||
return Arrays.Clone(digest);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
[Serializable]
|
||||
public class CmsAttributeTableGenerationException : CmsException
|
||||
{
|
||||
public CmsAttributeTableGenerationException()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAttributeTableGenerationException(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAttributeTableGenerationException(string name, Exception e)
|
||||
: base(name, e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public interface CmsAttributeTableGenerator
|
||||
{
|
||||
AttributeTable GetAttributes(IDictionary parameters);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public enum CmsAttributeTableParameter
|
||||
{
|
||||
ContentType,
|
||||
Digest,
|
||||
Signature,
|
||||
DigestAlgorithmIdentifier
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class CmsAuthEnvelopedData
|
||||
{
|
||||
private class AuthEnvelopedSecureReadable : CmsSecureReadable
|
||||
{
|
||||
private readonly CmsAuthEnvelopedData parent;
|
||||
|
||||
public AlgorithmIdentifier Algorithm => parent.authEncAlg;
|
||||
|
||||
public object CryptoObject => null;
|
||||
|
||||
internal AuthEnvelopedSecureReadable(CmsAuthEnvelopedData parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public CmsReadable GetReadable(KeyParameter key)
|
||||
{
|
||||
throw new CmsException("AuthEnveloped data decryption not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
internal RecipientInformationStore recipientInfoStore;
|
||||
|
||||
internal ContentInfo contentInfo;
|
||||
|
||||
private OriginatorInfo originator;
|
||||
|
||||
private AlgorithmIdentifier authEncAlg;
|
||||
|
||||
private Asn1Set authAttrs;
|
||||
|
||||
private byte[] mac;
|
||||
|
||||
private Asn1Set unauthAttrs;
|
||||
|
||||
public CmsAuthEnvelopedData(byte[] authEnvData)
|
||||
: this(CmsUtilities.ReadContentInfo(authEnvData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthEnvelopedData(Stream authEnvData)
|
||||
: this(CmsUtilities.ReadContentInfo(authEnvData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthEnvelopedData(ContentInfo contentInfo)
|
||||
{
|
||||
this.contentInfo = contentInfo;
|
||||
AuthEnvelopedData instance = AuthEnvelopedData.GetInstance(contentInfo.Content);
|
||||
originator = instance.OriginatorInfo;
|
||||
Asn1Set recipientInfos = instance.RecipientInfos;
|
||||
EncryptedContentInfo authEncryptedContentInfo = instance.AuthEncryptedContentInfo;
|
||||
authEncAlg = authEncryptedContentInfo.ContentEncryptionAlgorithm;
|
||||
CmsSecureReadable secureReadable = new AuthEnvelopedSecureReadable(this);
|
||||
recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore(recipientInfos, secureReadable);
|
||||
authAttrs = instance.AuthAttrs;
|
||||
mac = instance.Mac.GetOctets();
|
||||
unauthAttrs = instance.UnauthAttrs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class CmsAuthEnvelopedGenerator
|
||||
{
|
||||
public static readonly string Aes128Ccm = NistObjectIdentifiers.IdAes128Ccm.Id;
|
||||
|
||||
public static readonly string Aes192Ccm = NistObjectIdentifiers.IdAes192Ccm.Id;
|
||||
|
||||
public static readonly string Aes256Ccm = NistObjectIdentifiers.IdAes256Ccm.Id;
|
||||
|
||||
public static readonly string Aes128Gcm = NistObjectIdentifiers.IdAes128Gcm.Id;
|
||||
|
||||
public static readonly string Aes192Gcm = NistObjectIdentifiers.IdAes192Gcm.Id;
|
||||
|
||||
public static readonly string Aes256Gcm = NistObjectIdentifiers.IdAes256Gcm.Id;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsAuthenticatedData
|
||||
{
|
||||
internal RecipientInformationStore recipientInfoStore;
|
||||
|
||||
internal ContentInfo contentInfo;
|
||||
|
||||
private AlgorithmIdentifier macAlg;
|
||||
|
||||
private Asn1Set authAttrs;
|
||||
|
||||
private Asn1Set unauthAttrs;
|
||||
|
||||
private byte[] mac;
|
||||
|
||||
public AlgorithmIdentifier MacAlgorithmID => macAlg;
|
||||
|
||||
public string MacAlgOid => macAlg.Algorithm.Id;
|
||||
|
||||
public ContentInfo ContentInfo => contentInfo;
|
||||
|
||||
public CmsAuthenticatedData(byte[] authData)
|
||||
: this(CmsUtilities.ReadContentInfo(authData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthenticatedData(Stream authData)
|
||||
: this(CmsUtilities.ReadContentInfo(authData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthenticatedData(ContentInfo contentInfo)
|
||||
{
|
||||
this.contentInfo = contentInfo;
|
||||
AuthenticatedData instance = AuthenticatedData.GetInstance(contentInfo.Content);
|
||||
Asn1Set recipientInfos = instance.RecipientInfos;
|
||||
macAlg = instance.MacAlgorithm;
|
||||
ContentInfo encapsulatedContentInfo = instance.EncapsulatedContentInfo;
|
||||
CmsReadable readable = new CmsProcessableByteArray(Asn1OctetString.GetInstance(encapsulatedContentInfo.Content).GetOctets());
|
||||
CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsAuthenticatedSecureReadable(macAlg, readable);
|
||||
recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore(recipientInfos, secureReadable);
|
||||
authAttrs = instance.AuthAttrs;
|
||||
mac = instance.Mac.GetOctets();
|
||||
unauthAttrs = instance.UnauthAttrs;
|
||||
}
|
||||
|
||||
public byte[] GetMac()
|
||||
{
|
||||
return Arrays.Clone(mac);
|
||||
}
|
||||
|
||||
public RecipientInformationStore GetRecipientInfos()
|
||||
{
|
||||
return recipientInfoStore;
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable GetAuthAttrs()
|
||||
{
|
||||
if (authAttrs == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Org.BouncyCastle.Asn1.Cms.AttributeTable(authAttrs);
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable GetUnauthAttrs()
|
||||
{
|
||||
if (unauthAttrs == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Org.BouncyCastle.Asn1.Cms.AttributeTable(unauthAttrs);
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return contentInfo.GetEncoded();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsAuthenticatedDataGenerator : CmsAuthenticatedGenerator
|
||||
{
|
||||
public CmsAuthenticatedDataGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthenticatedDataGenerator(SecureRandom rand)
|
||||
: base(rand)
|
||||
{
|
||||
}
|
||||
|
||||
private CmsAuthenticatedData Generate(CmsProcessable content, string macOid, CipherKeyGenerator keyGen)
|
||||
{
|
||||
KeyParameter keyParameter;
|
||||
AlgorithmIdentifier algorithmIdentifier;
|
||||
Asn1OctetString content2;
|
||||
Asn1OctetString mac2;
|
||||
try
|
||||
{
|
||||
byte[] array = keyGen.GenerateKey();
|
||||
keyParameter = ParameterUtilities.CreateKeyParameter(macOid, array);
|
||||
Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, array);
|
||||
algorithmIdentifier = GetAlgorithmIdentifier(macOid, keyParameter, asn1Params, out var _);
|
||||
IMac mac = MacUtilities.GetMac(macOid);
|
||||
mac.Init(keyParameter);
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
Stream stream = new TeeOutputStream(memoryStream, new MacSink(mac));
|
||||
content.Write(stream);
|
||||
Platform.Dispose(stream);
|
||||
content2 = new BerOctetString(memoryStream.ToArray());
|
||||
byte[] str = MacUtilities.DoFinal(mac);
|
||||
mac2 = new DerOctetString(str);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (IOException e3)
|
||||
{
|
||||
throw new CmsException("exception decoding algorithm parameters.", e3);
|
||||
}
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (RecipientInfoGenerator recipientInfoGenerator in recipientInfoGenerators)
|
||||
{
|
||||
try
|
||||
{
|
||||
asn1EncodableVector.Add(recipientInfoGenerator.Generate(keyParameter, rand));
|
||||
}
|
||||
catch (InvalidKeyException e4)
|
||||
{
|
||||
throw new CmsException("key inappropriate for algorithm.", e4);
|
||||
}
|
||||
catch (GeneralSecurityException e5)
|
||||
{
|
||||
throw new CmsException("error making encrypted content.", e5);
|
||||
}
|
||||
}
|
||||
ContentInfo encapsulatedContent = new ContentInfo(CmsObjectIdentifiers.Data, content2);
|
||||
ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.AuthenticatedData, new AuthenticatedData(null, new DerSet(asn1EncodableVector), algorithmIdentifier, null, encapsulatedContent, null, mac2, null));
|
||||
return new CmsAuthenticatedData(contentInfo);
|
||||
}
|
||||
|
||||
public CmsAuthenticatedData Generate(CmsProcessable content, string encryptionOid)
|
||||
{
|
||||
try
|
||||
{
|
||||
CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid);
|
||||
keyGenerator.Init(new KeyGenerationParameters(rand, keyGenerator.DefaultStrength));
|
||||
return Generate(content, encryptionOid, keyGenerator);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("can't find key generation algorithm.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsAuthenticatedDataParser : CmsContentInfoParser
|
||||
{
|
||||
internal RecipientInformationStore _recipientInfoStore;
|
||||
|
||||
internal AuthenticatedDataParser authData;
|
||||
|
||||
private AlgorithmIdentifier macAlg;
|
||||
|
||||
private byte[] mac;
|
||||
|
||||
private Org.BouncyCastle.Asn1.Cms.AttributeTable authAttrs;
|
||||
|
||||
private Org.BouncyCastle.Asn1.Cms.AttributeTable unauthAttrs;
|
||||
|
||||
private bool authAttrNotRead;
|
||||
|
||||
private bool unauthAttrNotRead;
|
||||
|
||||
public AlgorithmIdentifier MacAlgorithmID => macAlg;
|
||||
|
||||
public string MacAlgOid => macAlg.Algorithm.Id;
|
||||
|
||||
public Asn1Object MacAlgParams => macAlg.Parameters?.ToAsn1Object();
|
||||
|
||||
public CmsAuthenticatedDataParser(byte[] envelopedData)
|
||||
: this(new MemoryStream(envelopedData, writable: false))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthenticatedDataParser(Stream envelopedData)
|
||||
: base(envelopedData)
|
||||
{
|
||||
authAttrNotRead = true;
|
||||
authData = new AuthenticatedDataParser((Asn1SequenceParser)contentInfo.GetContent(16));
|
||||
Asn1Set instance = Asn1Set.GetInstance(authData.GetRecipientInfos().ToAsn1Object());
|
||||
macAlg = authData.GetMacAlgorithm();
|
||||
ContentInfoParser enapsulatedContentInfo = authData.GetEnapsulatedContentInfo();
|
||||
CmsReadable readable = new CmsProcessableInputStream(((Asn1OctetStringParser)enapsulatedContentInfo.GetContent(4)).GetOctetStream());
|
||||
CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsAuthenticatedSecureReadable(macAlg, readable);
|
||||
_recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore(instance, secureReadable);
|
||||
}
|
||||
|
||||
public RecipientInformationStore GetRecipientInfos()
|
||||
{
|
||||
return _recipientInfoStore;
|
||||
}
|
||||
|
||||
public byte[] GetMac()
|
||||
{
|
||||
if (mac == null)
|
||||
{
|
||||
GetAuthAttrs();
|
||||
mac = authData.GetMac().GetOctets();
|
||||
}
|
||||
return Arrays.Clone(mac);
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable GetAuthAttrs()
|
||||
{
|
||||
if (authAttrs == null && authAttrNotRead)
|
||||
{
|
||||
Asn1SetParser asn1SetParser = authData.GetAuthAttrs();
|
||||
authAttrNotRead = false;
|
||||
if (asn1SetParser != null)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
IAsn1Convertible asn1Convertible;
|
||||
while ((asn1Convertible = asn1SetParser.ReadObject()) != null)
|
||||
{
|
||||
Asn1SequenceParser asn1SequenceParser = (Asn1SequenceParser)asn1Convertible;
|
||||
asn1EncodableVector.Add(asn1SequenceParser.ToAsn1Object());
|
||||
}
|
||||
authAttrs = new Org.BouncyCastle.Asn1.Cms.AttributeTable(new DerSet(asn1EncodableVector));
|
||||
}
|
||||
}
|
||||
return authAttrs;
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable GetUnauthAttrs()
|
||||
{
|
||||
if (unauthAttrs == null && unauthAttrNotRead)
|
||||
{
|
||||
Asn1SetParser asn1SetParser = authData.GetUnauthAttrs();
|
||||
unauthAttrNotRead = false;
|
||||
if (asn1SetParser != null)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
IAsn1Convertible asn1Convertible;
|
||||
while ((asn1Convertible = asn1SetParser.ReadObject()) != null)
|
||||
{
|
||||
Asn1SequenceParser asn1SequenceParser = (Asn1SequenceParser)asn1Convertible;
|
||||
asn1EncodableVector.Add(asn1SequenceParser.ToAsn1Object());
|
||||
}
|
||||
unauthAttrs = new Org.BouncyCastle.Asn1.Cms.AttributeTable(new DerSet(asn1EncodableVector));
|
||||
}
|
||||
}
|
||||
return unauthAttrs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsAuthenticatedDataStreamGenerator : CmsAuthenticatedGenerator
|
||||
{
|
||||
private class CmsAuthenticatedDataOutputStream : BaseOutputStream
|
||||
{
|
||||
private readonly Stream macStream;
|
||||
|
||||
private readonly IMac mac;
|
||||
|
||||
private readonly BerSequenceGenerator cGen;
|
||||
|
||||
private readonly BerSequenceGenerator authGen;
|
||||
|
||||
private readonly BerSequenceGenerator eiGen;
|
||||
|
||||
public CmsAuthenticatedDataOutputStream(Stream macStream, IMac mac, BerSequenceGenerator cGen, BerSequenceGenerator authGen, BerSequenceGenerator eiGen)
|
||||
{
|
||||
this.macStream = macStream;
|
||||
this.mac = mac;
|
||||
this.cGen = cGen;
|
||||
this.authGen = authGen;
|
||||
this.eiGen = eiGen;
|
||||
}
|
||||
|
||||
public override void WriteByte(byte b)
|
||||
{
|
||||
macStream.WriteByte(b);
|
||||
}
|
||||
|
||||
public override void Write(byte[] bytes, int off, int len)
|
||||
{
|
||||
macStream.Write(bytes, off, len);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
Platform.Dispose(macStream);
|
||||
eiGen.Close();
|
||||
byte[] str = MacUtilities.DoFinal(mac);
|
||||
authGen.AddObject(new DerOctetString(str));
|
||||
authGen.Close();
|
||||
cGen.Close();
|
||||
base.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private int _bufferSize;
|
||||
|
||||
private bool _berEncodeRecipientSet;
|
||||
|
||||
public CmsAuthenticatedDataStreamGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthenticatedDataStreamGenerator(SecureRandom rand)
|
||||
: base(rand)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetBufferSize(int bufferSize)
|
||||
{
|
||||
_bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public void SetBerEncodeRecipients(bool berEncodeRecipientSet)
|
||||
{
|
||||
_berEncodeRecipientSet = berEncodeRecipientSet;
|
||||
}
|
||||
|
||||
private Stream Open(Stream outStr, string macOid, CipherKeyGenerator keyGen)
|
||||
{
|
||||
byte[] array = keyGen.GenerateKey();
|
||||
KeyParameter keyParameter = ParameterUtilities.CreateKeyParameter(macOid, array);
|
||||
Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, array);
|
||||
ICipherParameters cipherParameters;
|
||||
AlgorithmIdentifier algorithmIdentifier = GetAlgorithmIdentifier(macOid, keyParameter, asn1Params, out cipherParameters);
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (RecipientInfoGenerator recipientInfoGenerator in recipientInfoGenerators)
|
||||
{
|
||||
try
|
||||
{
|
||||
asn1EncodableVector.Add(recipientInfoGenerator.Generate(keyParameter, rand));
|
||||
}
|
||||
catch (InvalidKeyException e)
|
||||
{
|
||||
throw new CmsException("key inappropriate for algorithm.", e);
|
||||
}
|
||||
catch (GeneralSecurityException e2)
|
||||
{
|
||||
throw new CmsException("error making encrypted content.", e2);
|
||||
}
|
||||
}
|
||||
return Open(outStr, algorithmIdentifier, keyParameter, asn1EncodableVector);
|
||||
}
|
||||
|
||||
protected Stream Open(Stream outStr, AlgorithmIdentifier macAlgId, ICipherParameters cipherParameters, Asn1EncodableVector recipientInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
BerSequenceGenerator berSequenceGenerator = new BerSequenceGenerator(outStr);
|
||||
berSequenceGenerator.AddObject(CmsObjectIdentifiers.AuthenticatedData);
|
||||
BerSequenceGenerator berSequenceGenerator2 = new BerSequenceGenerator(berSequenceGenerator.GetRawOutputStream(), 0, isExplicit: true);
|
||||
berSequenceGenerator2.AddObject(new DerInteger(AuthenticatedData.CalculateVersion(null)));
|
||||
Stream rawOutputStream = berSequenceGenerator2.GetRawOutputStream();
|
||||
Asn1Generator asn1Generator = (_berEncodeRecipientSet ? ((Asn1Generator)new BerSetGenerator(rawOutputStream)) : ((Asn1Generator)new DerSetGenerator(rawOutputStream)));
|
||||
foreach (Asn1Encodable recipientInfo in recipientInfos)
|
||||
{
|
||||
asn1Generator.AddObject(recipientInfo);
|
||||
}
|
||||
asn1Generator.Close();
|
||||
berSequenceGenerator2.AddObject(macAlgId);
|
||||
BerSequenceGenerator berSequenceGenerator3 = new BerSequenceGenerator(rawOutputStream);
|
||||
berSequenceGenerator3.AddObject(CmsObjectIdentifiers.Data);
|
||||
Stream output = CmsUtilities.CreateBerOctetOutputStream(berSequenceGenerator3.GetRawOutputStream(), 0, isExplicit: false, _bufferSize);
|
||||
IMac mac = MacUtilities.GetMac(macAlgId.Algorithm);
|
||||
mac.Init(cipherParameters);
|
||||
Stream macStream = new TeeOutputStream(output, new MacSink(mac));
|
||||
return new CmsAuthenticatedDataOutputStream(macStream, mac, berSequenceGenerator, berSequenceGenerator2, berSequenceGenerator3);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (IOException e3)
|
||||
{
|
||||
throw new CmsException("exception decoding algorithm parameters.", e3);
|
||||
}
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStr, string encryptionOid)
|
||||
{
|
||||
CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid);
|
||||
keyGenerator.Init(new KeyGenerationParameters(rand, keyGenerator.DefaultStrength));
|
||||
return Open(outStr, encryptionOid, keyGenerator);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStr, string encryptionOid, int keySize)
|
||||
{
|
||||
CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid);
|
||||
keyGenerator.Init(new KeyGenerationParameters(rand, keySize));
|
||||
return Open(outStr, encryptionOid, keyGenerator);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsAuthenticatedGenerator : CmsEnvelopedGenerator
|
||||
{
|
||||
public CmsAuthenticatedGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsAuthenticatedGenerator(SecureRandom rand)
|
||||
: base(rand)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Zlib;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsCompressedData
|
||||
{
|
||||
internal ContentInfo contentInfo;
|
||||
|
||||
public ContentInfo ContentInfo => contentInfo;
|
||||
|
||||
public CmsCompressedData(byte[] compressedData)
|
||||
: this(CmsUtilities.ReadContentInfo(compressedData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsCompressedData(Stream compressedDataStream)
|
||||
: this(CmsUtilities.ReadContentInfo(compressedDataStream))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsCompressedData(ContentInfo contentInfo)
|
||||
{
|
||||
this.contentInfo = contentInfo;
|
||||
}
|
||||
|
||||
public byte[] GetContent()
|
||||
{
|
||||
CompressedData instance = CompressedData.GetInstance(contentInfo.Content);
|
||||
ContentInfo encapContentInfo = instance.EncapContentInfo;
|
||||
Asn1OctetString asn1OctetString = (Asn1OctetString)encapContentInfo.Content;
|
||||
ZInputStream zInputStream = new ZInputStream(asn1OctetString.GetOctetStream());
|
||||
try
|
||||
{
|
||||
return CmsUtilities.StreamToByteArray(zInputStream);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("exception reading compressed stream.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Platform.Dispose(zInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetContent(int limit)
|
||||
{
|
||||
CompressedData instance = CompressedData.GetInstance(contentInfo.Content);
|
||||
ContentInfo encapContentInfo = instance.EncapContentInfo;
|
||||
Asn1OctetString asn1OctetString = (Asn1OctetString)encapContentInfo.Content;
|
||||
ZInputStream inStream = new ZInputStream(new MemoryStream(asn1OctetString.GetOctets(), writable: false));
|
||||
try
|
||||
{
|
||||
return CmsUtilities.StreamToByteArray(inStream, limit);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("exception reading compressed stream.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return contentInfo.GetEncoded();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Zlib;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsCompressedDataGenerator
|
||||
{
|
||||
public const string ZLib = "1.2.840.113549.1.9.16.3.8";
|
||||
|
||||
public CmsCompressedData Generate(CmsProcessable content, string compressionOid)
|
||||
{
|
||||
AlgorithmIdentifier compressionAlgorithm;
|
||||
Asn1OctetString content2;
|
||||
try
|
||||
{
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
ZOutputStream zOutputStream = new ZOutputStream(memoryStream, -1);
|
||||
content.Write(zOutputStream);
|
||||
Platform.Dispose(zOutputStream);
|
||||
compressionAlgorithm = new AlgorithmIdentifier(new DerObjectIdentifier(compressionOid));
|
||||
content2 = new BerOctetString(memoryStream.ToArray());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("exception encoding data.", e);
|
||||
}
|
||||
ContentInfo encapContentInfo = new ContentInfo(CmsObjectIdentifiers.Data, content2);
|
||||
ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.CompressedData, new CompressedData(compressionAlgorithm, encapContentInfo));
|
||||
return new CmsCompressedData(contentInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Utilities.Zlib;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsCompressedDataParser : CmsContentInfoParser
|
||||
{
|
||||
public CmsCompressedDataParser(byte[] compressedData)
|
||||
: this(new MemoryStream(compressedData, writable: false))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsCompressedDataParser(Stream compressedData)
|
||||
: base(compressedData)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsTypedStream GetContent()
|
||||
{
|
||||
try
|
||||
{
|
||||
CompressedDataParser compressedDataParser = new CompressedDataParser((Asn1SequenceParser)contentInfo.GetContent(16));
|
||||
ContentInfoParser encapContentInfo = compressedDataParser.GetEncapContentInfo();
|
||||
Asn1OctetStringParser asn1OctetStringParser = (Asn1OctetStringParser)encapContentInfo.GetContent(4);
|
||||
return new CmsTypedStream(encapContentInfo.ContentType.ToString(), new ZInputStream(asn1OctetStringParser.GetOctetStream()));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("IOException reading compressed content.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
using Org.BouncyCastle.Utilities.Zlib;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsCompressedDataStreamGenerator
|
||||
{
|
||||
private class CmsCompressedOutputStream : BaseOutputStream
|
||||
{
|
||||
private ZOutputStream _out;
|
||||
|
||||
private BerSequenceGenerator _sGen;
|
||||
|
||||
private BerSequenceGenerator _cGen;
|
||||
|
||||
private BerSequenceGenerator _eiGen;
|
||||
|
||||
internal CmsCompressedOutputStream(ZOutputStream outStream, BerSequenceGenerator sGen, BerSequenceGenerator cGen, BerSequenceGenerator eiGen)
|
||||
{
|
||||
_out = outStream;
|
||||
_sGen = sGen;
|
||||
_cGen = cGen;
|
||||
_eiGen = eiGen;
|
||||
}
|
||||
|
||||
public override void WriteByte(byte b)
|
||||
{
|
||||
_out.WriteByte(b);
|
||||
}
|
||||
|
||||
public override void Write(byte[] bytes, int off, int len)
|
||||
{
|
||||
_out.Write(bytes, off, len);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
Platform.Dispose(_out);
|
||||
_eiGen.Close();
|
||||
_cGen.Close();
|
||||
_sGen.Close();
|
||||
base.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public const string ZLib = "1.2.840.113549.1.9.16.3.8";
|
||||
|
||||
private int _bufferSize;
|
||||
|
||||
public void SetBufferSize(int bufferSize)
|
||||
{
|
||||
_bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, string compressionOID)
|
||||
{
|
||||
return Open(outStream, CmsObjectIdentifiers.Data.Id, compressionOID);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, string contentOID, string compressionOID)
|
||||
{
|
||||
BerSequenceGenerator berSequenceGenerator = new BerSequenceGenerator(outStream);
|
||||
berSequenceGenerator.AddObject(CmsObjectIdentifiers.CompressedData);
|
||||
BerSequenceGenerator berSequenceGenerator2 = new BerSequenceGenerator(berSequenceGenerator.GetRawOutputStream(), 0, isExplicit: true);
|
||||
berSequenceGenerator2.AddObject(new DerInteger(0));
|
||||
berSequenceGenerator2.AddObject(new AlgorithmIdentifier(new DerObjectIdentifier("1.2.840.113549.1.9.16.3.8")));
|
||||
BerSequenceGenerator berSequenceGenerator3 = new BerSequenceGenerator(berSequenceGenerator2.GetRawOutputStream());
|
||||
berSequenceGenerator3.AddObject(new DerObjectIdentifier(contentOID));
|
||||
Stream output = CmsUtilities.CreateBerOctetOutputStream(berSequenceGenerator3.GetRawOutputStream(), 0, isExplicit: true, _bufferSize);
|
||||
return new CmsCompressedOutputStream(new ZOutputStream(output, -1), berSequenceGenerator, berSequenceGenerator2, berSequenceGenerator3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsContentInfoParser
|
||||
{
|
||||
protected ContentInfoParser contentInfo;
|
||||
|
||||
protected Stream data;
|
||||
|
||||
protected CmsContentInfoParser(Stream data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw new ArgumentNullException("data");
|
||||
}
|
||||
this.data = data;
|
||||
try
|
||||
{
|
||||
Asn1StreamParser asn1StreamParser = new Asn1StreamParser(data);
|
||||
contentInfo = new ContentInfoParser((Asn1SequenceParser)asn1StreamParser.ReadObject());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("IOException reading content.", e);
|
||||
}
|
||||
catch (InvalidCastException e2)
|
||||
{
|
||||
throw new CmsException("Unexpected object reading content.", e2);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Platform.Dispose(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsEnvelopedData
|
||||
{
|
||||
internal RecipientInformationStore recipientInfoStore;
|
||||
|
||||
internal ContentInfo contentInfo;
|
||||
|
||||
private AlgorithmIdentifier encAlg;
|
||||
|
||||
private Asn1Set unprotectedAttributes;
|
||||
|
||||
public AlgorithmIdentifier EncryptionAlgorithmID => encAlg;
|
||||
|
||||
public string EncryptionAlgOid => encAlg.Algorithm.Id;
|
||||
|
||||
public ContentInfo ContentInfo => contentInfo;
|
||||
|
||||
public CmsEnvelopedData(byte[] envelopedData)
|
||||
: this(CmsUtilities.ReadContentInfo(envelopedData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsEnvelopedData(Stream envelopedData)
|
||||
: this(CmsUtilities.ReadContentInfo(envelopedData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsEnvelopedData(ContentInfo contentInfo)
|
||||
{
|
||||
this.contentInfo = contentInfo;
|
||||
EnvelopedData instance = EnvelopedData.GetInstance(contentInfo.Content);
|
||||
Asn1Set recipientInfos = instance.RecipientInfos;
|
||||
EncryptedContentInfo encryptedContentInfo = instance.EncryptedContentInfo;
|
||||
encAlg = encryptedContentInfo.ContentEncryptionAlgorithm;
|
||||
CmsReadable readable = new CmsProcessableByteArray(encryptedContentInfo.EncryptedContent.GetOctets());
|
||||
CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsEnvelopedSecureReadable(encAlg, readable);
|
||||
recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore(recipientInfos, secureReadable);
|
||||
unprotectedAttributes = instance.UnprotectedAttrs;
|
||||
}
|
||||
|
||||
public RecipientInformationStore GetRecipientInfos()
|
||||
{
|
||||
return recipientInfoStore;
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable GetUnprotectedAttributes()
|
||||
{
|
||||
if (unprotectedAttributes == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Org.BouncyCastle.Asn1.Cms.AttributeTable(unprotectedAttributes);
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return contentInfo.GetEncoded();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsEnvelopedDataGenerator : CmsEnvelopedGenerator
|
||||
{
|
||||
public CmsEnvelopedDataGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsEnvelopedDataGenerator(SecureRandom rand)
|
||||
: base(rand)
|
||||
{
|
||||
}
|
||||
|
||||
private CmsEnvelopedData Generate(CmsProcessable content, string encryptionOid, CipherKeyGenerator keyGen)
|
||||
{
|
||||
AlgorithmIdentifier algorithmIdentifier = null;
|
||||
KeyParameter keyParameter;
|
||||
Asn1OctetString encryptedContent;
|
||||
try
|
||||
{
|
||||
byte[] array = keyGen.GenerateKey();
|
||||
keyParameter = ParameterUtilities.CreateKeyParameter(encryptionOid, array);
|
||||
Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, array);
|
||||
algorithmIdentifier = GetAlgorithmIdentifier(encryptionOid, keyParameter, asn1Params, out var cipherParameters);
|
||||
IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid);
|
||||
cipher.Init(forEncryption: true, new ParametersWithRandom(cipherParameters, rand));
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
CipherStream cipherStream = new CipherStream(memoryStream, null, cipher);
|
||||
content.Write(cipherStream);
|
||||
Platform.Dispose(cipherStream);
|
||||
encryptedContent = new BerOctetString(memoryStream.ToArray());
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (IOException e3)
|
||||
{
|
||||
throw new CmsException("exception decoding algorithm parameters.", e3);
|
||||
}
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (RecipientInfoGenerator recipientInfoGenerator in recipientInfoGenerators)
|
||||
{
|
||||
try
|
||||
{
|
||||
asn1EncodableVector.Add(recipientInfoGenerator.Generate(keyParameter, rand));
|
||||
}
|
||||
catch (InvalidKeyException e4)
|
||||
{
|
||||
throw new CmsException("key inappropriate for algorithm.", e4);
|
||||
}
|
||||
catch (GeneralSecurityException e5)
|
||||
{
|
||||
throw new CmsException("error making encrypted content.", e5);
|
||||
}
|
||||
}
|
||||
EncryptedContentInfo encryptedContentInfo = new EncryptedContentInfo(CmsObjectIdentifiers.Data, algorithmIdentifier, encryptedContent);
|
||||
Asn1Set unprotectedAttrs = null;
|
||||
if (unprotectedAttributeGenerator != null)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable attributes = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());
|
||||
unprotectedAttrs = new BerSet(attributes.ToAsn1EncodableVector());
|
||||
}
|
||||
ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.EnvelopedData, new EnvelopedData(null, new DerSet(asn1EncodableVector), encryptedContentInfo, unprotectedAttrs));
|
||||
return new CmsEnvelopedData(contentInfo);
|
||||
}
|
||||
|
||||
public CmsEnvelopedData Generate(CmsProcessable content, string encryptionOid)
|
||||
{
|
||||
try
|
||||
{
|
||||
CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid);
|
||||
keyGenerator.Init(new KeyGenerationParameters(rand, keyGenerator.DefaultStrength));
|
||||
return Generate(content, encryptionOid, keyGenerator);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("can't find key generation algorithm.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public CmsEnvelopedData Generate(CmsProcessable content, ICipherBuilderWithKey cipherBuilder)
|
||||
{
|
||||
KeyParameter contentEncryptionKey;
|
||||
Asn1OctetString encryptedContent;
|
||||
try
|
||||
{
|
||||
contentEncryptionKey = (KeyParameter)cipherBuilder.Key;
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
Stream stream = cipherBuilder.BuildCipher(memoryStream).Stream;
|
||||
content.Write(stream);
|
||||
Platform.Dispose(stream);
|
||||
encryptedContent = new BerOctetString(memoryStream.ToArray());
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (IOException e3)
|
||||
{
|
||||
throw new CmsException("exception decoding algorithm parameters.", e3);
|
||||
}
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (RecipientInfoGenerator recipientInfoGenerator in recipientInfoGenerators)
|
||||
{
|
||||
try
|
||||
{
|
||||
asn1EncodableVector.Add(recipientInfoGenerator.Generate(contentEncryptionKey, rand));
|
||||
}
|
||||
catch (InvalidKeyException e4)
|
||||
{
|
||||
throw new CmsException("key inappropriate for algorithm.", e4);
|
||||
}
|
||||
catch (GeneralSecurityException e5)
|
||||
{
|
||||
throw new CmsException("error making encrypted content.", e5);
|
||||
}
|
||||
}
|
||||
EncryptedContentInfo encryptedContentInfo = new EncryptedContentInfo(CmsObjectIdentifiers.Data, (AlgorithmIdentifier)cipherBuilder.AlgorithmDetails, encryptedContent);
|
||||
Asn1Set unprotectedAttrs = null;
|
||||
if (unprotectedAttributeGenerator != null)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable attributes = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());
|
||||
unprotectedAttrs = new BerSet(attributes.ToAsn1EncodableVector());
|
||||
}
|
||||
ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.EnvelopedData, new EnvelopedData(null, new DerSet(asn1EncodableVector), encryptedContentInfo, unprotectedAttrs));
|
||||
return new CmsEnvelopedData(contentInfo);
|
||||
}
|
||||
|
||||
public CmsEnvelopedData Generate(CmsProcessable content, string encryptionOid, int keySize)
|
||||
{
|
||||
try
|
||||
{
|
||||
CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid);
|
||||
keyGenerator.Init(new KeyGenerationParameters(rand, keySize));
|
||||
return Generate(content, encryptionOid, keyGenerator);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("can't find key generation algorithm.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsEnvelopedDataParser : CmsContentInfoParser
|
||||
{
|
||||
internal RecipientInformationStore recipientInfoStore;
|
||||
|
||||
internal EnvelopedDataParser envelopedData;
|
||||
|
||||
private AlgorithmIdentifier _encAlg;
|
||||
|
||||
private Org.BouncyCastle.Asn1.Cms.AttributeTable _unprotectedAttributes;
|
||||
|
||||
private bool _attrNotRead;
|
||||
|
||||
public AlgorithmIdentifier EncryptionAlgorithmID => _encAlg;
|
||||
|
||||
public string EncryptionAlgOid => _encAlg.Algorithm.Id;
|
||||
|
||||
public Asn1Object EncryptionAlgParams => _encAlg.Parameters?.ToAsn1Object();
|
||||
|
||||
public CmsEnvelopedDataParser(byte[] envelopedData)
|
||||
: this(new MemoryStream(envelopedData, writable: false))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsEnvelopedDataParser(Stream envelopedData)
|
||||
: base(envelopedData)
|
||||
{
|
||||
_attrNotRead = true;
|
||||
this.envelopedData = new EnvelopedDataParser((Asn1SequenceParser)contentInfo.GetContent(16));
|
||||
Asn1Set instance = Asn1Set.GetInstance(this.envelopedData.GetRecipientInfos().ToAsn1Object());
|
||||
EncryptedContentInfoParser encryptedContentInfo = this.envelopedData.GetEncryptedContentInfo();
|
||||
_encAlg = encryptedContentInfo.ContentEncryptionAlgorithm;
|
||||
CmsReadable readable = new CmsProcessableInputStream(((Asn1OctetStringParser)encryptedContentInfo.GetEncryptedContent(4)).GetOctetStream());
|
||||
CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsEnvelopedSecureReadable(_encAlg, readable);
|
||||
recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore(instance, secureReadable);
|
||||
}
|
||||
|
||||
public RecipientInformationStore GetRecipientInfos()
|
||||
{
|
||||
return recipientInfoStore;
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable GetUnprotectedAttributes()
|
||||
{
|
||||
if (_unprotectedAttributes == null && _attrNotRead)
|
||||
{
|
||||
Asn1SetParser unprotectedAttrs = envelopedData.GetUnprotectedAttrs();
|
||||
_attrNotRead = false;
|
||||
if (unprotectedAttrs != null)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
IAsn1Convertible asn1Convertible;
|
||||
while ((asn1Convertible = unprotectedAttrs.ReadObject()) != null)
|
||||
{
|
||||
Asn1SequenceParser asn1SequenceParser = (Asn1SequenceParser)asn1Convertible;
|
||||
asn1EncodableVector.Add(asn1SequenceParser.ToAsn1Object());
|
||||
}
|
||||
_unprotectedAttributes = new Org.BouncyCastle.Asn1.Cms.AttributeTable(new DerSet(asn1EncodableVector));
|
||||
}
|
||||
}
|
||||
return _unprotectedAttributes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsEnvelopedDataStreamGenerator : CmsEnvelopedGenerator
|
||||
{
|
||||
private class CmsEnvelopedDataOutputStream : BaseOutputStream
|
||||
{
|
||||
private readonly CmsEnvelopedGenerator _outer;
|
||||
|
||||
private readonly CipherStream _out;
|
||||
|
||||
private readonly BerSequenceGenerator _cGen;
|
||||
|
||||
private readonly BerSequenceGenerator _envGen;
|
||||
|
||||
private readonly BerSequenceGenerator _eiGen;
|
||||
|
||||
public CmsEnvelopedDataOutputStream(CmsEnvelopedGenerator outer, CipherStream outStream, BerSequenceGenerator cGen, BerSequenceGenerator envGen, BerSequenceGenerator eiGen)
|
||||
{
|
||||
_outer = outer;
|
||||
_out = outStream;
|
||||
_cGen = cGen;
|
||||
_envGen = envGen;
|
||||
_eiGen = eiGen;
|
||||
}
|
||||
|
||||
public override void WriteByte(byte b)
|
||||
{
|
||||
_out.WriteByte(b);
|
||||
}
|
||||
|
||||
public override void Write(byte[] bytes, int off, int len)
|
||||
{
|
||||
_out.Write(bytes, off, len);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
Platform.Dispose(_out);
|
||||
_eiGen.Close();
|
||||
if (_outer.unprotectedAttributeGenerator != null)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable attributes = _outer.unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());
|
||||
Asn1Set obj = new BerSet(attributes.ToAsn1EncodableVector());
|
||||
_envGen.AddObject(new DerTaggedObject(explicitly: false, 1, obj));
|
||||
}
|
||||
_envGen.Close();
|
||||
_cGen.Close();
|
||||
base.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private object _originatorInfo = null;
|
||||
|
||||
private object _unprotectedAttributes = null;
|
||||
|
||||
private int _bufferSize;
|
||||
|
||||
private bool _berEncodeRecipientSet;
|
||||
|
||||
private DerInteger Version
|
||||
{
|
||||
get
|
||||
{
|
||||
int value = ((_originatorInfo != null || _unprotectedAttributes != null) ? 2 : 0);
|
||||
return new DerInteger(value);
|
||||
}
|
||||
}
|
||||
|
||||
public CmsEnvelopedDataStreamGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsEnvelopedDataStreamGenerator(SecureRandom rand)
|
||||
: base(rand)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetBufferSize(int bufferSize)
|
||||
{
|
||||
_bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public void SetBerEncodeRecipients(bool berEncodeRecipientSet)
|
||||
{
|
||||
_berEncodeRecipientSet = berEncodeRecipientSet;
|
||||
}
|
||||
|
||||
private Stream Open(Stream outStream, string encryptionOid, CipherKeyGenerator keyGen)
|
||||
{
|
||||
byte[] array = keyGen.GenerateKey();
|
||||
KeyParameter keyParameter = ParameterUtilities.CreateKeyParameter(encryptionOid, array);
|
||||
Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, array);
|
||||
ICipherParameters cipherParameters;
|
||||
AlgorithmIdentifier algorithmIdentifier = GetAlgorithmIdentifier(encryptionOid, keyParameter, asn1Params, out cipherParameters);
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (RecipientInfoGenerator recipientInfoGenerator in recipientInfoGenerators)
|
||||
{
|
||||
try
|
||||
{
|
||||
asn1EncodableVector.Add(recipientInfoGenerator.Generate(keyParameter, rand));
|
||||
}
|
||||
catch (InvalidKeyException e)
|
||||
{
|
||||
throw new CmsException("key inappropriate for algorithm.", e);
|
||||
}
|
||||
catch (GeneralSecurityException e2)
|
||||
{
|
||||
throw new CmsException("error making encrypted content.", e2);
|
||||
}
|
||||
}
|
||||
return Open(outStream, algorithmIdentifier, cipherParameters, asn1EncodableVector);
|
||||
}
|
||||
|
||||
private Stream Open(Stream outStream, AlgorithmIdentifier encAlgID, ICipherParameters cipherParameters, Asn1EncodableVector recipientInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
BerSequenceGenerator berSequenceGenerator = new BerSequenceGenerator(outStream);
|
||||
berSequenceGenerator.AddObject(CmsObjectIdentifiers.EnvelopedData);
|
||||
BerSequenceGenerator berSequenceGenerator2 = new BerSequenceGenerator(berSequenceGenerator.GetRawOutputStream(), 0, isExplicit: true);
|
||||
berSequenceGenerator2.AddObject(Version);
|
||||
Stream rawOutputStream = berSequenceGenerator2.GetRawOutputStream();
|
||||
Asn1Generator asn1Generator = (_berEncodeRecipientSet ? ((Asn1Generator)new BerSetGenerator(rawOutputStream)) : ((Asn1Generator)new DerSetGenerator(rawOutputStream)));
|
||||
foreach (Asn1Encodable recipientInfo in recipientInfos)
|
||||
{
|
||||
asn1Generator.AddObject(recipientInfo);
|
||||
}
|
||||
asn1Generator.Close();
|
||||
BerSequenceGenerator berSequenceGenerator3 = new BerSequenceGenerator(rawOutputStream);
|
||||
berSequenceGenerator3.AddObject(CmsObjectIdentifiers.Data);
|
||||
berSequenceGenerator3.AddObject(encAlgID);
|
||||
Stream stream = CmsUtilities.CreateBerOctetOutputStream(berSequenceGenerator3.GetRawOutputStream(), 0, isExplicit: false, _bufferSize);
|
||||
IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.Algorithm);
|
||||
cipher.Init(forEncryption: true, new ParametersWithRandom(cipherParameters, rand));
|
||||
CipherStream outStream2 = new CipherStream(stream, null, cipher);
|
||||
return new CmsEnvelopedDataOutputStream(this, outStream2, berSequenceGenerator, berSequenceGenerator2, berSequenceGenerator3);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (IOException e3)
|
||||
{
|
||||
throw new CmsException("exception decoding algorithm parameters.", e3);
|
||||
}
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, string encryptionOid)
|
||||
{
|
||||
CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid);
|
||||
keyGenerator.Init(new KeyGenerationParameters(rand, keyGenerator.DefaultStrength));
|
||||
return Open(outStream, encryptionOid, keyGenerator);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, string encryptionOid, int keySize)
|
||||
{
|
||||
CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid);
|
||||
keyGenerator.Init(new KeyGenerationParameters(rand, keySize));
|
||||
return Open(outStream, encryptionOid, keyGenerator);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Kisa;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Asn1.Ntt;
|
||||
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.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsEnvelopedGenerator
|
||||
{
|
||||
public const string IdeaCbc = "1.3.6.1.4.1.188.7.1.1.2";
|
||||
|
||||
public const string Cast5Cbc = "1.2.840.113533.7.66.10";
|
||||
|
||||
internal static readonly short[] rc2Table = new short[256]
|
||||
{
|
||||
189, 86, 234, 242, 162, 241, 172, 42, 176, 147,
|
||||
209, 156, 27, 51, 253, 208, 48, 4, 182, 220,
|
||||
125, 223, 50, 75, 247, 203, 69, 155, 49, 187,
|
||||
33, 90, 65, 159, 225, 217, 74, 77, 158, 218,
|
||||
160, 104, 44, 195, 39, 95, 128, 54, 62, 238,
|
||||
251, 149, 26, 254, 206, 168, 52, 169, 19, 240,
|
||||
166, 63, 216, 12, 120, 36, 175, 35, 82, 193,
|
||||
103, 23, 245, 102, 144, 231, 232, 7, 184, 96,
|
||||
72, 230, 30, 83, 243, 146, 164, 114, 140, 8,
|
||||
21, 110, 134, 0, 132, 250, 244, 127, 138, 66,
|
||||
25, 246, 219, 205, 20, 141, 80, 18, 186, 60,
|
||||
6, 78, 236, 179, 53, 17, 161, 136, 142, 43,
|
||||
148, 153, 183, 113, 116, 211, 228, 191, 58, 222,
|
||||
150, 14, 188, 10, 237, 119, 252, 55, 107, 3,
|
||||
121, 137, 98, 198, 215, 192, 210, 124, 106, 139,
|
||||
34, 163, 91, 5, 93, 2, 117, 213, 97, 227,
|
||||
24, 143, 85, 81, 173, 31, 11, 94, 133, 229,
|
||||
194, 87, 99, 202, 61, 108, 180, 197, 204, 112,
|
||||
178, 145, 89, 13, 71, 32, 200, 79, 88, 224,
|
||||
1, 226, 22, 56, 196, 111, 59, 15, 101, 70,
|
||||
190, 126, 45, 123, 130, 249, 64, 181, 29, 115,
|
||||
248, 235, 38, 199, 135, 151, 37, 84, 177, 40,
|
||||
170, 152, 157, 165, 100, 109, 122, 212, 16, 129,
|
||||
68, 239, 73, 214, 174, 46, 221, 118, 92, 47,
|
||||
167, 28, 201, 9, 105, 154, 131, 207, 41, 57,
|
||||
185, 233, 76, 255, 67, 171
|
||||
};
|
||||
|
||||
public static readonly string DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc.Id;
|
||||
|
||||
public static readonly string RC2Cbc = PkcsObjectIdentifiers.RC2Cbc.Id;
|
||||
|
||||
public static readonly string Aes128Cbc = NistObjectIdentifiers.IdAes128Cbc.Id;
|
||||
|
||||
public static readonly string Aes192Cbc = NistObjectIdentifiers.IdAes192Cbc.Id;
|
||||
|
||||
public static readonly string Aes256Cbc = NistObjectIdentifiers.IdAes256Cbc.Id;
|
||||
|
||||
public static readonly string Camellia128Cbc = NttObjectIdentifiers.IdCamellia128Cbc.Id;
|
||||
|
||||
public static readonly string Camellia192Cbc = NttObjectIdentifiers.IdCamellia192Cbc.Id;
|
||||
|
||||
public static readonly string Camellia256Cbc = NttObjectIdentifiers.IdCamellia256Cbc.Id;
|
||||
|
||||
public static readonly string SeedCbc = KisaObjectIdentifiers.IdSeedCbc.Id;
|
||||
|
||||
public static readonly string DesEde3Wrap = PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id;
|
||||
|
||||
public static readonly string Aes128Wrap = NistObjectIdentifiers.IdAes128Wrap.Id;
|
||||
|
||||
public static readonly string Aes192Wrap = NistObjectIdentifiers.IdAes192Wrap.Id;
|
||||
|
||||
public static readonly string Aes256Wrap = NistObjectIdentifiers.IdAes256Wrap.Id;
|
||||
|
||||
public static readonly string Camellia128Wrap = NttObjectIdentifiers.IdCamellia128Wrap.Id;
|
||||
|
||||
public static readonly string Camellia192Wrap = NttObjectIdentifiers.IdCamellia192Wrap.Id;
|
||||
|
||||
public static readonly string Camellia256Wrap = NttObjectIdentifiers.IdCamellia256Wrap.Id;
|
||||
|
||||
public static readonly string SeedWrap = KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id;
|
||||
|
||||
public static readonly string ECDHSha1Kdf = X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id;
|
||||
|
||||
public static readonly string ECMqvSha1Kdf = X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id;
|
||||
|
||||
internal readonly IList recipientInfoGenerators = Platform.CreateArrayList();
|
||||
|
||||
internal readonly SecureRandom rand;
|
||||
|
||||
internal CmsAttributeTableGenerator unprotectedAttributeGenerator = null;
|
||||
|
||||
public CmsAttributeTableGenerator UnprotectedAttributeGenerator
|
||||
{
|
||||
get
|
||||
{
|
||||
return unprotectedAttributeGenerator;
|
||||
}
|
||||
set
|
||||
{
|
||||
unprotectedAttributeGenerator = value;
|
||||
}
|
||||
}
|
||||
|
||||
public CmsEnvelopedGenerator()
|
||||
: this(new SecureRandom())
|
||||
{
|
||||
}
|
||||
|
||||
public CmsEnvelopedGenerator(SecureRandom rand)
|
||||
{
|
||||
this.rand = rand;
|
||||
}
|
||||
|
||||
public void AddKeyTransRecipient(X509Certificate cert)
|
||||
{
|
||||
KeyTransRecipientInfoGenerator keyTransRecipientInfoGenerator = new KeyTransRecipientInfoGenerator();
|
||||
keyTransRecipientInfoGenerator.RecipientCert = cert;
|
||||
recipientInfoGenerators.Add(keyTransRecipientInfoGenerator);
|
||||
}
|
||||
|
||||
public void AddKeyTransRecipient(AsymmetricKeyParameter pubKey, byte[] subKeyId)
|
||||
{
|
||||
KeyTransRecipientInfoGenerator keyTransRecipientInfoGenerator = new KeyTransRecipientInfoGenerator();
|
||||
keyTransRecipientInfoGenerator.RecipientPublicKey = pubKey;
|
||||
keyTransRecipientInfoGenerator.SubjectKeyIdentifier = new DerOctetString(subKeyId);
|
||||
recipientInfoGenerators.Add(keyTransRecipientInfoGenerator);
|
||||
}
|
||||
|
||||
public void AddKekRecipient(string keyAlgorithm, KeyParameter key, byte[] keyIdentifier)
|
||||
{
|
||||
AddKekRecipient(keyAlgorithm, key, new KekIdentifier(keyIdentifier, null, null));
|
||||
}
|
||||
|
||||
public void AddKekRecipient(string keyAlgorithm, KeyParameter key, KekIdentifier kekIdentifier)
|
||||
{
|
||||
KekRecipientInfoGenerator kekRecipientInfoGenerator = new KekRecipientInfoGenerator();
|
||||
kekRecipientInfoGenerator.KekIdentifier = kekIdentifier;
|
||||
kekRecipientInfoGenerator.KeyEncryptionKeyOID = keyAlgorithm;
|
||||
kekRecipientInfoGenerator.KeyEncryptionKey = key;
|
||||
recipientInfoGenerators.Add(kekRecipientInfoGenerator);
|
||||
}
|
||||
|
||||
public void AddPasswordRecipient(CmsPbeKey pbeKey, string kekAlgorithmOid)
|
||||
{
|
||||
Pbkdf2Params parameters = new Pbkdf2Params(pbeKey.Salt, pbeKey.IterationCount);
|
||||
PasswordRecipientInfoGenerator passwordRecipientInfoGenerator = new PasswordRecipientInfoGenerator();
|
||||
passwordRecipientInfoGenerator.KeyDerivationAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPbkdf2, parameters);
|
||||
passwordRecipientInfoGenerator.KeyEncryptionKeyOID = kekAlgorithmOid;
|
||||
passwordRecipientInfoGenerator.KeyEncryptionKey = pbeKey.GetEncoded(kekAlgorithmOid);
|
||||
recipientInfoGenerators.Add(passwordRecipientInfoGenerator);
|
||||
}
|
||||
|
||||
public void AddKeyAgreementRecipient(string agreementAlgorithm, AsymmetricKeyParameter senderPrivateKey, AsymmetricKeyParameter senderPublicKey, X509Certificate recipientCert, string cekWrapAlgorithm)
|
||||
{
|
||||
IList list = Platform.CreateArrayList(1);
|
||||
list.Add(recipientCert);
|
||||
AddKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey, list, cekWrapAlgorithm);
|
||||
}
|
||||
|
||||
public void AddKeyAgreementRecipients(string agreementAlgorithm, AsymmetricKeyParameter senderPrivateKey, AsymmetricKeyParameter senderPublicKey, ICollection recipientCerts, string cekWrapAlgorithm)
|
||||
{
|
||||
if (!senderPrivateKey.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected private key", "senderPrivateKey");
|
||||
}
|
||||
if (senderPublicKey.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected public key", "senderPublicKey");
|
||||
}
|
||||
KeyAgreeRecipientInfoGenerator keyAgreeRecipientInfoGenerator = new KeyAgreeRecipientInfoGenerator();
|
||||
keyAgreeRecipientInfoGenerator.KeyAgreementOID = new DerObjectIdentifier(agreementAlgorithm);
|
||||
keyAgreeRecipientInfoGenerator.KeyEncryptionOID = new DerObjectIdentifier(cekWrapAlgorithm);
|
||||
keyAgreeRecipientInfoGenerator.RecipientCerts = recipientCerts;
|
||||
keyAgreeRecipientInfoGenerator.SenderKeyPair = new AsymmetricCipherKeyPair(senderPublicKey, senderPrivateKey);
|
||||
recipientInfoGenerators.Add(keyAgreeRecipientInfoGenerator);
|
||||
}
|
||||
|
||||
public void AddRecipientInfoGenerator(RecipientInfoGenerator recipientInfoGenerator)
|
||||
{
|
||||
recipientInfoGenerators.Add(recipientInfoGenerator);
|
||||
}
|
||||
|
||||
protected internal virtual AlgorithmIdentifier GetAlgorithmIdentifier(string encryptionOid, KeyParameter encKey, Asn1Encodable asn1Params, out ICipherParameters cipherParameters)
|
||||
{
|
||||
Asn1Object asn1Object;
|
||||
if (asn1Params != null)
|
||||
{
|
||||
asn1Object = asn1Params.ToAsn1Object();
|
||||
cipherParameters = ParameterUtilities.GetCipherParameters(encryptionOid, encKey, asn1Object);
|
||||
}
|
||||
else
|
||||
{
|
||||
asn1Object = DerNull.Instance;
|
||||
cipherParameters = encKey;
|
||||
}
|
||||
return new AlgorithmIdentifier(new DerObjectIdentifier(encryptionOid), asn1Object);
|
||||
}
|
||||
|
||||
protected internal virtual Asn1Encodable GenerateAsn1Parameters(string encryptionOid, byte[] encKeyBytes)
|
||||
{
|
||||
Asn1Encodable result = null;
|
||||
try
|
||||
{
|
||||
if (encryptionOid.Equals(RC2Cbc))
|
||||
{
|
||||
byte[] array = new byte[8];
|
||||
rand.NextBytes(array);
|
||||
int num = encKeyBytes.Length * 8;
|
||||
int parameterVersion = ((num >= 256) ? num : rc2Table[num]);
|
||||
result = new RC2CbcParameter(parameterVersion, array);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ParameterUtilities.GenerateParameters(encryptionOid, rand);
|
||||
}
|
||||
}
|
||||
catch (SecurityUtilityException)
|
||||
{
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class CmsEnvelopedHelper
|
||||
{
|
||||
internal class CmsAuthenticatedSecureReadable : CmsSecureReadable
|
||||
{
|
||||
private AlgorithmIdentifier algorithm;
|
||||
|
||||
private IMac mac;
|
||||
|
||||
private CmsReadable readable;
|
||||
|
||||
public AlgorithmIdentifier Algorithm => algorithm;
|
||||
|
||||
public object CryptoObject => mac;
|
||||
|
||||
internal CmsAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, CmsReadable readable)
|
||||
{
|
||||
this.algorithm = algorithm;
|
||||
this.readable = readable;
|
||||
}
|
||||
|
||||
public CmsReadable GetReadable(KeyParameter sKey)
|
||||
{
|
||||
string id = algorithm.Algorithm.Id;
|
||||
try
|
||||
{
|
||||
mac = MacUtilities.GetMac(id);
|
||||
mac.Init(sKey);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (IOException e3)
|
||||
{
|
||||
throw new CmsException("error decoding algorithm parameters.", e3);
|
||||
}
|
||||
try
|
||||
{
|
||||
return new CmsProcessableInputStream(new TeeInputStream(readable.GetInputStream(), new MacSink(mac)));
|
||||
}
|
||||
catch (IOException e4)
|
||||
{
|
||||
throw new CmsException("error reading content.", e4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class CmsEnvelopedSecureReadable : CmsSecureReadable
|
||||
{
|
||||
private AlgorithmIdentifier algorithm;
|
||||
|
||||
private IBufferedCipher cipher;
|
||||
|
||||
private CmsReadable readable;
|
||||
|
||||
public AlgorithmIdentifier Algorithm => algorithm;
|
||||
|
||||
public object CryptoObject => cipher;
|
||||
|
||||
internal CmsEnvelopedSecureReadable(AlgorithmIdentifier algorithm, CmsReadable readable)
|
||||
{
|
||||
this.algorithm = algorithm;
|
||||
this.readable = readable;
|
||||
}
|
||||
|
||||
public CmsReadable GetReadable(KeyParameter sKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
cipher = CipherUtilities.GetCipher(algorithm.Algorithm);
|
||||
Asn1Object asn1Object = algorithm.Parameters?.ToAsn1Object();
|
||||
ICipherParameters cipherParameters = sKey;
|
||||
if (asn1Object != null && !(asn1Object is Asn1Null))
|
||||
{
|
||||
cipherParameters = ParameterUtilities.GetCipherParameters(algorithm.Algorithm, cipherParameters, asn1Object);
|
||||
}
|
||||
else
|
||||
{
|
||||
string id = algorithm.Algorithm.Id;
|
||||
if (id.Equals(CmsEnvelopedGenerator.DesEde3Cbc) || id.Equals("1.3.6.1.4.1.188.7.1.1.2") || id.Equals("1.2.840.113533.7.66.10"))
|
||||
{
|
||||
cipherParameters = new ParametersWithIV(cipherParameters, new byte[8]);
|
||||
}
|
||||
}
|
||||
cipher.Init(forEncryption: false, cipherParameters);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (IOException e3)
|
||||
{
|
||||
throw new CmsException("error decoding algorithm parameters.", e3);
|
||||
}
|
||||
try
|
||||
{
|
||||
return new CmsProcessableInputStream(new CipherStream(readable.GetInputStream(), cipher, null));
|
||||
}
|
||||
catch (IOException e4)
|
||||
{
|
||||
throw new CmsException("error reading content.", e4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static readonly CmsEnvelopedHelper Instance;
|
||||
|
||||
private static readonly IDictionary KeySizes;
|
||||
|
||||
private static readonly IDictionary BaseCipherNames;
|
||||
|
||||
static CmsEnvelopedHelper()
|
||||
{
|
||||
Instance = new CmsEnvelopedHelper();
|
||||
KeySizes = Platform.CreateHashtable();
|
||||
BaseCipherNames = Platform.CreateHashtable();
|
||||
KeySizes.Add(CmsEnvelopedGenerator.DesEde3Cbc, 192);
|
||||
KeySizes.Add(CmsEnvelopedGenerator.Aes128Cbc, 128);
|
||||
KeySizes.Add(CmsEnvelopedGenerator.Aes192Cbc, 192);
|
||||
KeySizes.Add(CmsEnvelopedGenerator.Aes256Cbc, 256);
|
||||
BaseCipherNames.Add(CmsEnvelopedGenerator.DesEde3Cbc, "DESEDE");
|
||||
BaseCipherNames.Add(CmsEnvelopedGenerator.Aes128Cbc, "AES");
|
||||
BaseCipherNames.Add(CmsEnvelopedGenerator.Aes192Cbc, "AES");
|
||||
BaseCipherNames.Add(CmsEnvelopedGenerator.Aes256Cbc, "AES");
|
||||
}
|
||||
|
||||
private string GetAsymmetricEncryptionAlgName(string encryptionAlgOid)
|
||||
{
|
||||
if (PkcsObjectIdentifiers.RsaEncryption.Id.Equals(encryptionAlgOid))
|
||||
{
|
||||
return "RSA/ECB/PKCS1Padding";
|
||||
}
|
||||
return encryptionAlgOid;
|
||||
}
|
||||
|
||||
internal IBufferedCipher CreateAsymmetricCipher(string encryptionOid)
|
||||
{
|
||||
string asymmetricEncryptionAlgName = GetAsymmetricEncryptionAlgName(encryptionOid);
|
||||
if (!asymmetricEncryptionAlgName.Equals(encryptionOid))
|
||||
{
|
||||
try
|
||||
{
|
||||
return CipherUtilities.GetCipher(asymmetricEncryptionAlgName);
|
||||
}
|
||||
catch (SecurityUtilityException)
|
||||
{
|
||||
}
|
||||
}
|
||||
return CipherUtilities.GetCipher(encryptionOid);
|
||||
}
|
||||
|
||||
internal IWrapper CreateWrapper(string encryptionOid)
|
||||
{
|
||||
try
|
||||
{
|
||||
return WrapperUtilities.GetWrapper(encryptionOid);
|
||||
}
|
||||
catch (SecurityUtilityException)
|
||||
{
|
||||
return WrapperUtilities.GetWrapper(GetAsymmetricEncryptionAlgName(encryptionOid));
|
||||
}
|
||||
}
|
||||
|
||||
internal string GetRfc3211WrapperName(string oid)
|
||||
{
|
||||
if (oid == null)
|
||||
{
|
||||
throw new ArgumentNullException("oid");
|
||||
}
|
||||
string text = (string)BaseCipherNames[oid];
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentException("no name for " + oid, "oid");
|
||||
}
|
||||
return text + "RFC3211Wrap";
|
||||
}
|
||||
|
||||
internal int GetKeySize(string oid)
|
||||
{
|
||||
if (!KeySizes.Contains(oid))
|
||||
{
|
||||
throw new ArgumentException("no keysize for " + oid, "oid");
|
||||
}
|
||||
return (int)KeySizes[oid];
|
||||
}
|
||||
|
||||
internal static RecipientInformationStore BuildRecipientInformationStore(Asn1Set recipientInfos, CmsSecureReadable secureReadable)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
for (int i = 0; i != recipientInfos.Count; i++)
|
||||
{
|
||||
RecipientInfo instance = RecipientInfo.GetInstance(recipientInfos[i]);
|
||||
ReadRecipientInfo(list, instance, secureReadable);
|
||||
}
|
||||
return new RecipientInformationStore(list);
|
||||
}
|
||||
|
||||
private static void ReadRecipientInfo(IList infos, RecipientInfo info, CmsSecureReadable secureReadable)
|
||||
{
|
||||
Asn1Encodable info2 = info.Info;
|
||||
if (info2 is KeyTransRecipientInfo)
|
||||
{
|
||||
infos.Add(new KeyTransRecipientInformation((KeyTransRecipientInfo)info2, secureReadable));
|
||||
}
|
||||
else if (info2 is KekRecipientInfo)
|
||||
{
|
||||
infos.Add(new KekRecipientInformation((KekRecipientInfo)info2, secureReadable));
|
||||
}
|
||||
else if (info2 is KeyAgreeRecipientInfo)
|
||||
{
|
||||
KeyAgreeRecipientInformation.ReadRecipientInfo(infos, (KeyAgreeRecipientInfo)info2, secureReadable);
|
||||
}
|
||||
else if (info2 is PasswordRecipientInfo)
|
||||
{
|
||||
infos.Add(new PasswordRecipientInformation((PasswordRecipientInfo)info2, secureReadable));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
[Serializable]
|
||||
public class CmsException : Exception
|
||||
{
|
||||
public CmsException()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsException(string msg)
|
||||
: base(msg)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsException(string msg, Exception e)
|
||||
: base(msg, e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public abstract class CmsPbeKey : ICipherParameters
|
||||
{
|
||||
internal readonly char[] password;
|
||||
|
||||
internal readonly byte[] salt;
|
||||
|
||||
internal readonly int iterationCount;
|
||||
|
||||
[Obsolete("Will be removed")]
|
||||
public string Password => new string(password);
|
||||
|
||||
public byte[] Salt => Arrays.Clone(salt);
|
||||
|
||||
public int IterationCount => iterationCount;
|
||||
|
||||
public string Algorithm => "PKCS5S2";
|
||||
|
||||
public string Format => "RAW";
|
||||
|
||||
[Obsolete("Use version taking 'char[]' instead")]
|
||||
public CmsPbeKey(string password, byte[] salt, int iterationCount)
|
||||
: this(password.ToCharArray(), salt, iterationCount)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use version taking 'char[]' instead")]
|
||||
public CmsPbeKey(string password, AlgorithmIdentifier keyDerivationAlgorithm)
|
||||
: this(password.ToCharArray(), keyDerivationAlgorithm)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsPbeKey(char[] password, byte[] salt, int iterationCount)
|
||||
{
|
||||
this.password = (char[])password.Clone();
|
||||
this.salt = Arrays.Clone(salt);
|
||||
this.iterationCount = iterationCount;
|
||||
}
|
||||
|
||||
public CmsPbeKey(char[] password, AlgorithmIdentifier keyDerivationAlgorithm)
|
||||
{
|
||||
if (!keyDerivationAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdPbkdf2))
|
||||
{
|
||||
throw new ArgumentException("Unsupported key derivation algorithm: " + keyDerivationAlgorithm.Algorithm);
|
||||
}
|
||||
Pbkdf2Params instance = Pbkdf2Params.GetInstance(keyDerivationAlgorithm.Parameters.ToAsn1Object());
|
||||
this.password = (char[])password.Clone();
|
||||
salt = instance.GetSalt();
|
||||
iterationCount = instance.IterationCount.IntValue;
|
||||
}
|
||||
|
||||
~CmsPbeKey()
|
||||
{
|
||||
Array.Clear(password, 0, password.Length);
|
||||
}
|
||||
|
||||
[Obsolete("Use 'Salt' property instead")]
|
||||
public byte[] GetSalt()
|
||||
{
|
||||
return Salt;
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
internal abstract KeyParameter GetEncoded(string algorithmOid);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public interface CmsProcessable
|
||||
{
|
||||
void Write(Stream outStream);
|
||||
|
||||
[Obsolete]
|
||||
object GetContent();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsProcessableByteArray : CmsProcessable, CmsReadable
|
||||
{
|
||||
private readonly DerObjectIdentifier type;
|
||||
|
||||
private readonly byte[] bytes;
|
||||
|
||||
public DerObjectIdentifier Type => type;
|
||||
|
||||
public CmsProcessableByteArray(byte[] bytes)
|
||||
{
|
||||
type = CmsObjectIdentifiers.Data;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public CmsProcessableByteArray(DerObjectIdentifier type, byte[] bytes)
|
||||
{
|
||||
this.bytes = bytes;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public virtual Stream GetInputStream()
|
||||
{
|
||||
return new MemoryStream(bytes, writable: false);
|
||||
}
|
||||
|
||||
public virtual void Write(Stream zOut)
|
||||
{
|
||||
zOut.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public virtual object GetContent()
|
||||
{
|
||||
return bytes.Clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsProcessableFile : CmsProcessable, CmsReadable
|
||||
{
|
||||
private const int DefaultBufSize = 32768;
|
||||
|
||||
private readonly FileInfo _file;
|
||||
|
||||
private readonly int _bufSize;
|
||||
|
||||
public CmsProcessableFile(FileInfo file)
|
||||
: this(file, 32768)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsProcessableFile(FileInfo file, int bufSize)
|
||||
{
|
||||
_file = file;
|
||||
_bufSize = bufSize;
|
||||
}
|
||||
|
||||
public virtual Stream GetInputStream()
|
||||
{
|
||||
return new FileStream(_file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, _bufSize);
|
||||
}
|
||||
|
||||
public virtual void Write(Stream zOut)
|
||||
{
|
||||
Stream inputStream = GetInputStream();
|
||||
Streams.PipeAll(inputStream, zOut);
|
||||
Platform.Dispose(inputStream);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public virtual object GetContent()
|
||||
{
|
||||
return _file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsProcessableInputStream : CmsProcessable, CmsReadable
|
||||
{
|
||||
private readonly Stream input;
|
||||
|
||||
private bool used = false;
|
||||
|
||||
public CmsProcessableInputStream(Stream input)
|
||||
{
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public virtual Stream GetInputStream()
|
||||
{
|
||||
CheckSingleUsage();
|
||||
return input;
|
||||
}
|
||||
|
||||
public virtual void Write(Stream output)
|
||||
{
|
||||
CheckSingleUsage();
|
||||
Streams.PipeAll(input, output);
|
||||
Platform.Dispose(input);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public virtual object GetContent()
|
||||
{
|
||||
return GetInputStream();
|
||||
}
|
||||
|
||||
protected virtual void CheckSingleUsage()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (used)
|
||||
{
|
||||
throw new InvalidOperationException("CmsProcessableInputStream can only be used once");
|
||||
}
|
||||
used = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public interface CmsReadable
|
||||
{
|
||||
Stream GetInputStream();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal interface CmsSecureReadable
|
||||
{
|
||||
AlgorithmIdentifier Algorithm { get; }
|
||||
|
||||
object CryptoObject { get; }
|
||||
|
||||
CmsReadable GetReadable(KeyParameter key);
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsSignedData
|
||||
{
|
||||
private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
|
||||
|
||||
private readonly CmsProcessable signedContent;
|
||||
|
||||
private SignedData signedData;
|
||||
|
||||
private ContentInfo contentInfo;
|
||||
|
||||
private SignerInformationStore signerInfoStore;
|
||||
|
||||
private IX509Store attrCertStore;
|
||||
|
||||
private IX509Store certificateStore;
|
||||
|
||||
private IX509Store crlStore;
|
||||
|
||||
private IDictionary hashes;
|
||||
|
||||
public int Version => signedData.Version.Value.IntValue;
|
||||
|
||||
[Obsolete("Use 'SignedContentType' property instead.")]
|
||||
public string SignedContentTypeOid => signedData.EncapContentInfo.ContentType.Id;
|
||||
|
||||
public DerObjectIdentifier SignedContentType => signedData.EncapContentInfo.ContentType;
|
||||
|
||||
public CmsProcessable SignedContent => signedContent;
|
||||
|
||||
public ContentInfo ContentInfo => contentInfo;
|
||||
|
||||
private CmsSignedData(CmsSignedData c)
|
||||
{
|
||||
signedData = c.signedData;
|
||||
contentInfo = c.contentInfo;
|
||||
signedContent = c.signedContent;
|
||||
signerInfoStore = c.signerInfoStore;
|
||||
}
|
||||
|
||||
public CmsSignedData(byte[] sigBlock)
|
||||
: this(CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, writable: false)))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedData(CmsProcessable signedContent, byte[] sigBlock)
|
||||
: this(signedContent, CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, writable: false)))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedData(IDictionary hashes, byte[] sigBlock)
|
||||
: this(hashes, CmsUtilities.ReadContentInfo(sigBlock))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedData(CmsProcessable signedContent, Stream sigData)
|
||||
: this(signedContent, CmsUtilities.ReadContentInfo(sigData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedData(Stream sigData)
|
||||
: this(CmsUtilities.ReadContentInfo(sigData))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedData(CmsProcessable signedContent, ContentInfo sigData)
|
||||
{
|
||||
this.signedContent = signedContent;
|
||||
contentInfo = sigData;
|
||||
signedData = SignedData.GetInstance(contentInfo.Content);
|
||||
}
|
||||
|
||||
public CmsSignedData(IDictionary hashes, ContentInfo sigData)
|
||||
{
|
||||
this.hashes = hashes;
|
||||
contentInfo = sigData;
|
||||
signedData = SignedData.GetInstance(contentInfo.Content);
|
||||
}
|
||||
|
||||
public CmsSignedData(ContentInfo sigData)
|
||||
{
|
||||
contentInfo = sigData;
|
||||
signedData = SignedData.GetInstance(contentInfo.Content);
|
||||
if (signedData.EncapContentInfo.Content != null)
|
||||
{
|
||||
signedContent = new CmsProcessableByteArray(((Asn1OctetString)signedData.EncapContentInfo.Content).GetOctets());
|
||||
}
|
||||
}
|
||||
|
||||
public SignerInformationStore GetSignerInfos()
|
||||
{
|
||||
if (signerInfoStore == null)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
Asn1Set signerInfos = signedData.SignerInfos;
|
||||
foreach (object item in signerInfos)
|
||||
{
|
||||
SignerInfo instance = SignerInfo.GetInstance(item);
|
||||
DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType;
|
||||
if (hashes == null)
|
||||
{
|
||||
list.Add(new SignerInformation(instance, contentType, signedContent, null));
|
||||
continue;
|
||||
}
|
||||
byte[] digest = (byte[])hashes[instance.DigestAlgorithm.Algorithm.Id];
|
||||
list.Add(new SignerInformation(instance, contentType, null, new BaseDigestCalculator(digest)));
|
||||
}
|
||||
signerInfoStore = new SignerInformationStore(list);
|
||||
}
|
||||
return signerInfoStore;
|
||||
}
|
||||
|
||||
public IX509Store GetAttributeCertificates(string type)
|
||||
{
|
||||
if (attrCertStore == null)
|
||||
{
|
||||
attrCertStore = Helper.CreateAttributeStore(type, signedData.Certificates);
|
||||
}
|
||||
return attrCertStore;
|
||||
}
|
||||
|
||||
public IX509Store GetCertificates(string type)
|
||||
{
|
||||
if (certificateStore == null)
|
||||
{
|
||||
certificateStore = Helper.CreateCertificateStore(type, signedData.Certificates);
|
||||
}
|
||||
return certificateStore;
|
||||
}
|
||||
|
||||
public IX509Store GetCrls(string type)
|
||||
{
|
||||
if (crlStore == null)
|
||||
{
|
||||
crlStore = Helper.CreateCrlStore(type, signedData.CRLs);
|
||||
}
|
||||
return crlStore;
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return contentInfo.GetEncoded();
|
||||
}
|
||||
|
||||
public static CmsSignedData ReplaceSigners(CmsSignedData signedData, SignerInformationStore signerInformationStore)
|
||||
{
|
||||
CmsSignedData cmsSignedData = new CmsSignedData(signedData);
|
||||
cmsSignedData.signerInfoStore = signerInformationStore;
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
||||
foreach (SignerInformation signer in signerInformationStore.GetSigners())
|
||||
{
|
||||
asn1EncodableVector.Add(Helper.FixAlgID(signer.DigestAlgorithmID));
|
||||
asn1EncodableVector2.Add(signer.ToSignerInfo());
|
||||
}
|
||||
Asn1Set asn1Set = new DerSet(asn1EncodableVector);
|
||||
Asn1Set asn1Set2 = new DerSet(asn1EncodableVector2);
|
||||
Asn1Sequence asn1Sequence = (Asn1Sequence)signedData.signedData.ToAsn1Object();
|
||||
asn1EncodableVector2 = new Asn1EncodableVector(asn1Sequence[0], asn1Set);
|
||||
for (int i = 2; i != asn1Sequence.Count - 1; i++)
|
||||
{
|
||||
asn1EncodableVector2.Add(asn1Sequence[i]);
|
||||
}
|
||||
asn1EncodableVector2.Add(asn1Set2);
|
||||
cmsSignedData.signedData = SignedData.GetInstance(new BerSequence(asn1EncodableVector2));
|
||||
cmsSignedData.contentInfo = new ContentInfo(cmsSignedData.contentInfo.ContentType, cmsSignedData.signedData);
|
||||
return cmsSignedData;
|
||||
}
|
||||
|
||||
public static CmsSignedData ReplaceCertificatesAndCrls(CmsSignedData signedData, IX509Store x509Certs, IX509Store x509Crls, IX509Store x509AttrCerts)
|
||||
{
|
||||
if (x509AttrCerts != null)
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("Currently can't replace attribute certificates");
|
||||
}
|
||||
CmsSignedData cmsSignedData = new CmsSignedData(signedData);
|
||||
Asn1Set certificates = null;
|
||||
try
|
||||
{
|
||||
Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList(CmsUtilities.GetCertificatesFromStore(x509Certs));
|
||||
if (asn1Set.Count != 0)
|
||||
{
|
||||
certificates = asn1Set;
|
||||
}
|
||||
}
|
||||
catch (X509StoreException e)
|
||||
{
|
||||
throw new CmsException("error getting certificates from store", e);
|
||||
}
|
||||
Asn1Set crls = null;
|
||||
try
|
||||
{
|
||||
Asn1Set asn1Set2 = CmsUtilities.CreateBerSetFromList(CmsUtilities.GetCrlsFromStore(x509Crls));
|
||||
if (asn1Set2.Count != 0)
|
||||
{
|
||||
crls = asn1Set2;
|
||||
}
|
||||
}
|
||||
catch (X509StoreException e2)
|
||||
{
|
||||
throw new CmsException("error getting CRLs from store", e2);
|
||||
}
|
||||
SignedData signedData2 = signedData.signedData;
|
||||
cmsSignedData.signedData = new SignedData(signedData2.DigestAlgorithms, signedData2.EncapContentInfo, certificates, crls, signedData2.SignerInfos);
|
||||
cmsSignedData.contentInfo = new ContentInfo(cmsSignedData.contentInfo.ContentType, cmsSignedData.signedData);
|
||||
return cmsSignedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Operators;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsSignedDataGenerator : CmsSignedGenerator
|
||||
{
|
||||
private class SignerInf
|
||||
{
|
||||
private readonly CmsSignedGenerator outer;
|
||||
|
||||
private readonly ISignatureFactory sigCalc;
|
||||
|
||||
private readonly SignerIdentifier signerIdentifier;
|
||||
|
||||
private readonly string digestOID;
|
||||
|
||||
private readonly string encOID;
|
||||
|
||||
private readonly CmsAttributeTableGenerator sAttr;
|
||||
|
||||
private readonly CmsAttributeTableGenerator unsAttr;
|
||||
|
||||
private readonly Org.BouncyCastle.Asn1.Cms.AttributeTable baseSignedTable;
|
||||
|
||||
internal AlgorithmIdentifier DigestAlgorithmID => new AlgorithmIdentifier(new DerObjectIdentifier(digestOID), DerNull.Instance);
|
||||
|
||||
internal CmsAttributeTableGenerator SignedAttributes => sAttr;
|
||||
|
||||
internal CmsAttributeTableGenerator UnsignedAttributes => unsAttr;
|
||||
|
||||
internal SignerInf(CmsSignedGenerator outer, AsymmetricKeyParameter key, SignerIdentifier signerIdentifier, string digestOID, string encOID, CmsAttributeTableGenerator sAttr, CmsAttributeTableGenerator unsAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable baseSignedTable)
|
||||
{
|
||||
string digestAlgName = Helper.GetDigestAlgName(digestOID);
|
||||
string algorithm = digestAlgName + "with" + Helper.GetEncryptionAlgName(encOID);
|
||||
this.outer = outer;
|
||||
sigCalc = new Asn1SignatureFactory(algorithm, key);
|
||||
this.signerIdentifier = signerIdentifier;
|
||||
this.digestOID = digestOID;
|
||||
this.encOID = encOID;
|
||||
this.sAttr = sAttr;
|
||||
this.unsAttr = unsAttr;
|
||||
this.baseSignedTable = baseSignedTable;
|
||||
}
|
||||
|
||||
internal SignerInf(CmsSignedGenerator outer, ISignatureFactory sigCalc, SignerIdentifier signerIdentifier, CmsAttributeTableGenerator sAttr, CmsAttributeTableGenerator unsAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable baseSignedTable)
|
||||
{
|
||||
this.outer = outer;
|
||||
this.sigCalc = sigCalc;
|
||||
this.signerIdentifier = signerIdentifier;
|
||||
digestOID = new DefaultDigestAlgorithmIdentifierFinder().find((AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id;
|
||||
encOID = ((AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id;
|
||||
this.sAttr = sAttr;
|
||||
this.unsAttr = unsAttr;
|
||||
this.baseSignedTable = baseSignedTable;
|
||||
}
|
||||
|
||||
internal SignerInfo ToSignerInfo(DerObjectIdentifier contentType, CmsProcessable content, SecureRandom random)
|
||||
{
|
||||
AlgorithmIdentifier digestAlgorithmID = DigestAlgorithmID;
|
||||
string digestAlgName = Helper.GetDigestAlgName(digestOID);
|
||||
string algorithm = digestAlgName + "with" + Helper.GetEncryptionAlgName(encOID);
|
||||
byte[] array;
|
||||
if (outer._digests.Contains(digestOID))
|
||||
{
|
||||
array = (byte[])outer._digests[digestOID];
|
||||
}
|
||||
else
|
||||
{
|
||||
IDigest digestInstance = Helper.GetDigestInstance(digestAlgName);
|
||||
content?.Write(new DigestSink(digestInstance));
|
||||
array = DigestUtilities.DoFinal(digestInstance);
|
||||
outer._digests.Add(digestOID, array.Clone());
|
||||
}
|
||||
IStreamCalculator streamCalculator = sigCalc.CreateCalculator();
|
||||
Stream stream = new BufferedStream(streamCalculator.Stream);
|
||||
Asn1Set asn1Set = null;
|
||||
if (sAttr != null)
|
||||
{
|
||||
IDictionary baseParameters = outer.GetBaseParameters(contentType, digestAlgorithmID, array);
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable attributeTable = sAttr.GetAttributes(baseParameters);
|
||||
if (contentType == null && attributeTable != null && attributeTable[CmsAttributes.ContentType] != null)
|
||||
{
|
||||
IDictionary dictionary = attributeTable.ToDictionary();
|
||||
dictionary.Remove(CmsAttributes.ContentType);
|
||||
attributeTable = new Org.BouncyCastle.Asn1.Cms.AttributeTable(dictionary);
|
||||
}
|
||||
asn1Set = outer.GetAttributeSet(attributeTable);
|
||||
new DerOutputStream(stream).WriteObject(asn1Set);
|
||||
}
|
||||
else
|
||||
{
|
||||
content?.Write(stream);
|
||||
}
|
||||
Platform.Dispose(stream);
|
||||
byte[] array2 = ((IBlockResult)streamCalculator.GetResult()).Collect();
|
||||
Asn1Set unauthenticatedAttributes = null;
|
||||
if (unsAttr != null)
|
||||
{
|
||||
IDictionary baseParameters2 = outer.GetBaseParameters(contentType, digestAlgorithmID, array);
|
||||
baseParameters2[CmsAttributeTableParameter.Signature] = array2.Clone();
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable attributes = unsAttr.GetAttributes(baseParameters2);
|
||||
unauthenticatedAttributes = outer.GetAttributeSet(attributes);
|
||||
}
|
||||
Asn1Encodable defaultX509Parameters = SignerUtilities.GetDefaultX509Parameters(algorithm);
|
||||
AlgorithmIdentifier encAlgorithmIdentifier = Helper.GetEncAlgorithmIdentifier(new DerObjectIdentifier(encOID), defaultX509Parameters);
|
||||
return new SignerInfo(signerIdentifier, digestAlgorithmID, asn1Set, encAlgorithmIdentifier, new DerOctetString(array2), unauthenticatedAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
|
||||
|
||||
private readonly IList signerInfs = Platform.CreateArrayList();
|
||||
|
||||
public CmsSignedDataGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataGenerator(SecureRandom rand)
|
||||
: base(rand)
|
||||
{
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOID)
|
||||
{
|
||||
AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOID), digestOID);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string encryptionOID, string digestOID)
|
||||
{
|
||||
doAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(cert), encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(), null, null);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string digestOID)
|
||||
{
|
||||
AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOID), digestOID);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string encryptionOID, string digestOID)
|
||||
{
|
||||
doAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(), null, null);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOID, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOID), digestOID, signedAttr, unsignedAttr);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string encryptionOID, string digestOID, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
doAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(cert), encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr), signedAttr);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string digestOID, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOID), digestOID, signedAttr, unsignedAttr);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string encryptionOID, string digestOID, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
doAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr), signedAttr);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOID, CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen)
|
||||
{
|
||||
AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOID), digestOID, signedAttrGen, unsignedAttrGen);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string encryptionOID, string digestOID, CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen)
|
||||
{
|
||||
doAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(cert), encryptionOID, digestOID, signedAttrGen, unsignedAttrGen, null);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string digestOID, CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen)
|
||||
{
|
||||
AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOID), digestOID, signedAttrGen, unsignedAttrGen);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string encryptionOID, string digestOID, CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen)
|
||||
{
|
||||
doAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, signedAttrGen, unsignedAttrGen, null);
|
||||
}
|
||||
|
||||
public void AddSignerInfoGenerator(SignerInfoGenerator signerInfoGenerator)
|
||||
{
|
||||
signerInfs.Add(new SignerInf(this, signerInfoGenerator.contentSigner, signerInfoGenerator.sigId, signerInfoGenerator.signedGen, signerInfoGenerator.unsignedGen, null));
|
||||
}
|
||||
|
||||
private void doAddSigner(AsymmetricKeyParameter privateKey, SignerIdentifier signerIdentifier, string encryptionOID, string digestOID, CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen, Org.BouncyCastle.Asn1.Cms.AttributeTable baseSignedTable)
|
||||
{
|
||||
signerInfs.Add(new SignerInf(this, privateKey, signerIdentifier, digestOID, encryptionOID, signedAttrGen, unsignedAttrGen, baseSignedTable));
|
||||
}
|
||||
|
||||
public CmsSignedData Generate(CmsProcessable content)
|
||||
{
|
||||
return Generate(content, encapsulate: false);
|
||||
}
|
||||
|
||||
public CmsSignedData Generate(string signedContentType, CmsProcessable content, bool encapsulate)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
||||
_digests.Clear();
|
||||
foreach (SignerInformation signer in _signers)
|
||||
{
|
||||
asn1EncodableVector.Add(Helper.FixAlgID(signer.DigestAlgorithmID));
|
||||
asn1EncodableVector2.Add(signer.ToSignerInfo());
|
||||
}
|
||||
DerObjectIdentifier contentType = ((signedContentType == null) ? null : new DerObjectIdentifier(signedContentType));
|
||||
foreach (SignerInf signerInf in signerInfs)
|
||||
{
|
||||
try
|
||||
{
|
||||
asn1EncodableVector.Add(signerInf.DigestAlgorithmID);
|
||||
asn1EncodableVector2.Add(signerInf.ToSignerInfo(contentType, content, rand));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("encoding error.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key inappropriate for signature.", e2);
|
||||
}
|
||||
catch (SignatureException e3)
|
||||
{
|
||||
throw new CmsException("error creating signature.", e3);
|
||||
}
|
||||
catch (CertificateEncodingException e4)
|
||||
{
|
||||
throw new CmsException("error creating sid.", e4);
|
||||
}
|
||||
}
|
||||
Asn1Set certificates = null;
|
||||
if (_certs.Count != 0)
|
||||
{
|
||||
certificates = (base.UseDerForCerts ? CmsUtilities.CreateDerSetFromList(_certs) : CmsUtilities.CreateBerSetFromList(_certs));
|
||||
}
|
||||
Asn1Set crls = null;
|
||||
if (_crls.Count != 0)
|
||||
{
|
||||
crls = (base.UseDerForCrls ? CmsUtilities.CreateDerSetFromList(_crls) : CmsUtilities.CreateBerSetFromList(_crls));
|
||||
}
|
||||
Asn1OctetString content2 = null;
|
||||
if (encapsulate)
|
||||
{
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
if (content != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
content.Write(memoryStream);
|
||||
}
|
||||
catch (IOException e5)
|
||||
{
|
||||
throw new CmsException("encapsulation error.", e5);
|
||||
}
|
||||
}
|
||||
content2 = new BerOctetString(memoryStream.ToArray());
|
||||
}
|
||||
ContentInfo contentInfo = new ContentInfo(contentType, content2);
|
||||
SignedData content3 = new SignedData(new DerSet(asn1EncodableVector), contentInfo, certificates, crls, new DerSet(asn1EncodableVector2));
|
||||
ContentInfo sigData = new ContentInfo(CmsObjectIdentifiers.SignedData, content3);
|
||||
return new CmsSignedData(content, sigData);
|
||||
}
|
||||
|
||||
public CmsSignedData Generate(CmsProcessable content, bool encapsulate)
|
||||
{
|
||||
return Generate(CmsSignedGenerator.Data, content, encapsulate);
|
||||
}
|
||||
|
||||
public SignerInformationStore GenerateCounterSigners(SignerInformation signer)
|
||||
{
|
||||
return Generate(null, new CmsProcessableByteArray(signer.GetSignature()), encapsulate: false).GetSignerInfos();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsSignedDataParser : CmsContentInfoParser
|
||||
{
|
||||
private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
|
||||
|
||||
private SignedDataParser _signedData;
|
||||
|
||||
private DerObjectIdentifier _signedContentType;
|
||||
|
||||
private CmsTypedStream _signedContent;
|
||||
|
||||
private IDictionary _digests;
|
||||
|
||||
private ISet _digestOids;
|
||||
|
||||
private SignerInformationStore _signerInfoStore;
|
||||
|
||||
private Asn1Set _certSet;
|
||||
|
||||
private Asn1Set _crlSet;
|
||||
|
||||
private bool _isCertCrlParsed;
|
||||
|
||||
private IX509Store _attributeStore;
|
||||
|
||||
private IX509Store _certificateStore;
|
||||
|
||||
private IX509Store _crlStore;
|
||||
|
||||
public int Version => _signedData.Version.Value.IntValue;
|
||||
|
||||
public ISet DigestOids => new HashSet(_digestOids);
|
||||
|
||||
public DerObjectIdentifier SignedContentType => _signedContentType;
|
||||
|
||||
public CmsSignedDataParser(byte[] sigBlock)
|
||||
: this(new MemoryStream(sigBlock, writable: false))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataParser(CmsTypedStream signedContent, byte[] sigBlock)
|
||||
: this(signedContent, new MemoryStream(sigBlock, writable: false))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataParser(Stream sigData)
|
||||
: this(null, sigData)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataParser(CmsTypedStream signedContent, Stream sigData)
|
||||
: base(sigData)
|
||||
{
|
||||
try
|
||||
{
|
||||
_signedContent = signedContent;
|
||||
_signedData = SignedDataParser.GetInstance(contentInfo.GetContent(16));
|
||||
_digests = Platform.CreateHashtable();
|
||||
_digestOids = new HashSet();
|
||||
Asn1SetParser digestAlgorithms = _signedData.GetDigestAlgorithms();
|
||||
IAsn1Convertible asn1Convertible;
|
||||
while ((asn1Convertible = digestAlgorithms.ReadObject()) != null)
|
||||
{
|
||||
AlgorithmIdentifier instance = AlgorithmIdentifier.GetInstance(asn1Convertible.ToAsn1Object());
|
||||
try
|
||||
{
|
||||
string id = instance.Algorithm.Id;
|
||||
string digestAlgName = Helper.GetDigestAlgName(id);
|
||||
if (!_digests.Contains(digestAlgName))
|
||||
{
|
||||
_digests[digestAlgName] = Helper.GetDigestInstance(digestAlgName);
|
||||
_digestOids.Add(id);
|
||||
}
|
||||
}
|
||||
catch (SecurityUtilityException)
|
||||
{
|
||||
}
|
||||
}
|
||||
ContentInfoParser encapContentInfo = _signedData.GetEncapContentInfo();
|
||||
Asn1OctetStringParser asn1OctetStringParser = (Asn1OctetStringParser)encapContentInfo.GetContent(4);
|
||||
if (asn1OctetStringParser != null)
|
||||
{
|
||||
CmsTypedStream cmsTypedStream = new CmsTypedStream(encapContentInfo.ContentType.Id, asn1OctetStringParser.GetOctetStream());
|
||||
if (_signedContent == null)
|
||||
{
|
||||
_signedContent = cmsTypedStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmsTypedStream.Drain();
|
||||
}
|
||||
}
|
||||
_signedContentType = ((_signedContent == null) ? encapContentInfo.ContentType : new DerObjectIdentifier(_signedContent.ContentType));
|
||||
}
|
||||
catch (IOException ex2)
|
||||
{
|
||||
throw new CmsException("io exception: " + ex2.Message, ex2);
|
||||
}
|
||||
}
|
||||
|
||||
public SignerInformationStore GetSignerInfos()
|
||||
{
|
||||
if (_signerInfoStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
IList list = Platform.CreateArrayList();
|
||||
IDictionary dictionary = Platform.CreateHashtable();
|
||||
foreach (object key in _digests.Keys)
|
||||
{
|
||||
dictionary[key] = DigestUtilities.DoFinal((IDigest)_digests[key]);
|
||||
}
|
||||
try
|
||||
{
|
||||
Asn1SetParser signerInfos = _signedData.GetSignerInfos();
|
||||
IAsn1Convertible asn1Convertible;
|
||||
while ((asn1Convertible = signerInfos.ReadObject()) != null)
|
||||
{
|
||||
SignerInfo instance = SignerInfo.GetInstance(asn1Convertible.ToAsn1Object());
|
||||
string digestAlgName = Helper.GetDigestAlgName(instance.DigestAlgorithm.Algorithm.Id);
|
||||
byte[] digest = (byte[])dictionary[digestAlgName];
|
||||
list.Add(new SignerInformation(instance, _signedContentType, null, new BaseDigestCalculator(digest)));
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new CmsException("io exception: " + ex.Message, ex);
|
||||
}
|
||||
_signerInfoStore = new SignerInformationStore(list);
|
||||
}
|
||||
return _signerInfoStore;
|
||||
}
|
||||
|
||||
public IX509Store GetAttributeCertificates(string type)
|
||||
{
|
||||
if (_attributeStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
_attributeStore = Helper.CreateAttributeStore(type, _certSet);
|
||||
}
|
||||
return _attributeStore;
|
||||
}
|
||||
|
||||
public IX509Store GetCertificates(string type)
|
||||
{
|
||||
if (_certificateStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
_certificateStore = Helper.CreateCertificateStore(type, _certSet);
|
||||
}
|
||||
return _certificateStore;
|
||||
}
|
||||
|
||||
public IX509Store GetCrls(string type)
|
||||
{
|
||||
if (_crlStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
_crlStore = Helper.CreateCrlStore(type, _crlSet);
|
||||
}
|
||||
return _crlStore;
|
||||
}
|
||||
|
||||
private void PopulateCertCrlSets()
|
||||
{
|
||||
if (_isCertCrlParsed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_isCertCrlParsed = true;
|
||||
try
|
||||
{
|
||||
_certSet = GetAsn1Set(_signedData.GetCertificates());
|
||||
_crlSet = GetAsn1Set(_signedData.GetCrls());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("problem parsing cert/crl sets", e);
|
||||
}
|
||||
}
|
||||
|
||||
public CmsTypedStream GetSignedContent()
|
||||
{
|
||||
if (_signedContent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Stream stream = _signedContent.ContentStream;
|
||||
foreach (IDigest value in _digests.Values)
|
||||
{
|
||||
stream = new DigestStream(stream, value, null);
|
||||
}
|
||||
return new CmsTypedStream(_signedContent.ContentType, stream);
|
||||
}
|
||||
|
||||
public static Stream ReplaceSigners(Stream original, SignerInformationStore signerInformationStore, Stream outStr)
|
||||
{
|
||||
CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = new CmsSignedDataStreamGenerator();
|
||||
CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(original);
|
||||
cmsSignedDataStreamGenerator.AddSigners(signerInformationStore);
|
||||
CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent();
|
||||
bool flag = signedContent != null;
|
||||
Stream stream = cmsSignedDataStreamGenerator.Open(outStr, cmsSignedDataParser.SignedContentType.Id, flag);
|
||||
if (flag)
|
||||
{
|
||||
Streams.PipeAll(signedContent.ContentStream, stream);
|
||||
}
|
||||
cmsSignedDataStreamGenerator.AddAttributeCertificates(cmsSignedDataParser.GetAttributeCertificates("Collection"));
|
||||
cmsSignedDataStreamGenerator.AddCertificates(cmsSignedDataParser.GetCertificates("Collection"));
|
||||
cmsSignedDataStreamGenerator.AddCrls(cmsSignedDataParser.GetCrls("Collection"));
|
||||
Platform.Dispose(stream);
|
||||
return outStr;
|
||||
}
|
||||
|
||||
public static Stream ReplaceCertificatesAndCrls(Stream original, IX509Store x509Certs, IX509Store x509Crls, IX509Store x509AttrCerts, Stream outStr)
|
||||
{
|
||||
CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = new CmsSignedDataStreamGenerator();
|
||||
CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(original);
|
||||
cmsSignedDataStreamGenerator.AddDigests(cmsSignedDataParser.DigestOids);
|
||||
CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent();
|
||||
bool flag = signedContent != null;
|
||||
Stream stream = cmsSignedDataStreamGenerator.Open(outStr, cmsSignedDataParser.SignedContentType.Id, flag);
|
||||
if (flag)
|
||||
{
|
||||
Streams.PipeAll(signedContent.ContentStream, stream);
|
||||
}
|
||||
if (x509AttrCerts != null)
|
||||
{
|
||||
cmsSignedDataStreamGenerator.AddAttributeCertificates(x509AttrCerts);
|
||||
}
|
||||
if (x509Certs != null)
|
||||
{
|
||||
cmsSignedDataStreamGenerator.AddCertificates(x509Certs);
|
||||
}
|
||||
if (x509Crls != null)
|
||||
{
|
||||
cmsSignedDataStreamGenerator.AddCrls(x509Crls);
|
||||
}
|
||||
cmsSignedDataStreamGenerator.AddSigners(cmsSignedDataParser.GetSignerInfos());
|
||||
Platform.Dispose(stream);
|
||||
return outStr;
|
||||
}
|
||||
|
||||
private static Asn1Set GetAsn1Set(Asn1SetParser asn1SetParser)
|
||||
{
|
||||
if (asn1SetParser != null)
|
||||
{
|
||||
return Asn1Set.GetInstance(asn1SetParser.ToAsn1Object());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,522 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsSignedDataStreamGenerator : CmsSignedGenerator
|
||||
{
|
||||
private class DigestAndSignerInfoGeneratorHolder
|
||||
{
|
||||
internal readonly ISignerInfoGenerator signerInf;
|
||||
|
||||
internal readonly string digestOID;
|
||||
|
||||
internal AlgorithmIdentifier DigestAlgorithm => new AlgorithmIdentifier(new DerObjectIdentifier(digestOID), DerNull.Instance);
|
||||
|
||||
internal DigestAndSignerInfoGeneratorHolder(ISignerInfoGenerator signerInf, string digestOID)
|
||||
{
|
||||
this.signerInf = signerInf;
|
||||
this.digestOID = digestOID;
|
||||
}
|
||||
}
|
||||
|
||||
private class SignerInfoGeneratorImpl : ISignerInfoGenerator
|
||||
{
|
||||
private readonly CmsSignedDataStreamGenerator outer;
|
||||
|
||||
private readonly SignerIdentifier _signerIdentifier;
|
||||
|
||||
private readonly string _digestOID;
|
||||
|
||||
private readonly string _encOID;
|
||||
|
||||
private readonly CmsAttributeTableGenerator _sAttr;
|
||||
|
||||
private readonly CmsAttributeTableGenerator _unsAttr;
|
||||
|
||||
private readonly string _encName;
|
||||
|
||||
private readonly ISigner _sig;
|
||||
|
||||
internal SignerInfoGeneratorImpl(CmsSignedDataStreamGenerator outer, AsymmetricKeyParameter key, SignerIdentifier signerIdentifier, string digestOID, string encOID, CmsAttributeTableGenerator sAttr, CmsAttributeTableGenerator unsAttr)
|
||||
{
|
||||
this.outer = outer;
|
||||
_signerIdentifier = signerIdentifier;
|
||||
_digestOID = digestOID;
|
||||
_encOID = encOID;
|
||||
_sAttr = sAttr;
|
||||
_unsAttr = unsAttr;
|
||||
_encName = Helper.GetEncryptionAlgName(_encOID);
|
||||
string digestAlgName = Helper.GetDigestAlgName(_digestOID);
|
||||
string algorithm = digestAlgName + "with" + _encName;
|
||||
if (_sAttr != null)
|
||||
{
|
||||
_sig = Helper.GetSignatureInstance(algorithm);
|
||||
}
|
||||
else if (_encName.Equals("RSA"))
|
||||
{
|
||||
_sig = Helper.GetSignatureInstance("RSA");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_encName.Equals("DSA"))
|
||||
{
|
||||
throw new SignatureException("algorithm: " + _encName + " not supported in base signatures.");
|
||||
}
|
||||
_sig = Helper.GetSignatureInstance("NONEwithDSA");
|
||||
}
|
||||
_sig.Init(forSigning: true, new ParametersWithRandom(key, outer.rand));
|
||||
}
|
||||
|
||||
public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, byte[] calculatedDigest)
|
||||
{
|
||||
try
|
||||
{
|
||||
string digestAlgName = Helper.GetDigestAlgName(_digestOID);
|
||||
string algorithm = digestAlgName + "with" + _encName;
|
||||
byte[] array = calculatedDigest;
|
||||
Asn1Set asn1Set = null;
|
||||
if (_sAttr != null)
|
||||
{
|
||||
IDictionary baseParameters = outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest);
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable attributeTable = _sAttr.GetAttributes(baseParameters);
|
||||
if (contentType == null && attributeTable != null && attributeTable[CmsAttributes.ContentType] != null)
|
||||
{
|
||||
IDictionary dictionary = attributeTable.ToDictionary();
|
||||
dictionary.Remove(CmsAttributes.ContentType);
|
||||
attributeTable = new Org.BouncyCastle.Asn1.Cms.AttributeTable(dictionary);
|
||||
}
|
||||
asn1Set = outer.GetAttributeSet(attributeTable);
|
||||
array = asn1Set.GetEncoded("DER");
|
||||
}
|
||||
else if (_encName.Equals("RSA"))
|
||||
{
|
||||
DigestInfo digestInfo = new DigestInfo(digestAlgorithm, calculatedDigest);
|
||||
array = digestInfo.GetEncoded("DER");
|
||||
}
|
||||
_sig.BlockUpdate(array, 0, array.Length);
|
||||
byte[] array2 = _sig.GenerateSignature();
|
||||
Asn1Set unauthenticatedAttributes = null;
|
||||
if (_unsAttr != null)
|
||||
{
|
||||
IDictionary baseParameters2 = outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest);
|
||||
baseParameters2[CmsAttributeTableParameter.Signature] = array2.Clone();
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable attributes = _unsAttr.GetAttributes(baseParameters2);
|
||||
unauthenticatedAttributes = outer.GetAttributeSet(attributes);
|
||||
}
|
||||
Asn1Encodable defaultX509Parameters = SignerUtilities.GetDefaultX509Parameters(algorithm);
|
||||
AlgorithmIdentifier encAlgorithmIdentifier = Helper.GetEncAlgorithmIdentifier(new DerObjectIdentifier(_encOID), defaultX509Parameters);
|
||||
return new SignerInfo(_signerIdentifier, digestAlgorithm, asn1Set, encAlgorithmIdentifier, new DerOctetString(array2), unauthenticatedAttributes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsStreamException("encoding error.", e);
|
||||
}
|
||||
catch (SignatureException e2)
|
||||
{
|
||||
throw new CmsStreamException("error creating signature.", e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CmsSignedDataOutputStream : BaseOutputStream
|
||||
{
|
||||
private readonly CmsSignedDataStreamGenerator outer;
|
||||
|
||||
private Stream _out;
|
||||
|
||||
private DerObjectIdentifier _contentOID;
|
||||
|
||||
private BerSequenceGenerator _sGen;
|
||||
|
||||
private BerSequenceGenerator _sigGen;
|
||||
|
||||
private BerSequenceGenerator _eiGen;
|
||||
|
||||
public CmsSignedDataOutputStream(CmsSignedDataStreamGenerator outer, Stream outStream, string contentOID, BerSequenceGenerator sGen, BerSequenceGenerator sigGen, BerSequenceGenerator eiGen)
|
||||
{
|
||||
this.outer = outer;
|
||||
_out = outStream;
|
||||
_contentOID = new DerObjectIdentifier(contentOID);
|
||||
_sGen = sGen;
|
||||
_sigGen = sigGen;
|
||||
_eiGen = eiGen;
|
||||
}
|
||||
|
||||
public override void WriteByte(byte b)
|
||||
{
|
||||
_out.WriteByte(b);
|
||||
}
|
||||
|
||||
public override void Write(byte[] bytes, int off, int len)
|
||||
{
|
||||
_out.Write(bytes, off, len);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
DoClose();
|
||||
base.Close();
|
||||
}
|
||||
|
||||
private void DoClose()
|
||||
{
|
||||
Platform.Dispose(_out);
|
||||
_eiGen.Close();
|
||||
outer._digests.Clear();
|
||||
if (outer._certs.Count > 0)
|
||||
{
|
||||
Asn1Set obj = (outer.UseDerForCerts ? CmsUtilities.CreateDerSetFromList(outer._certs) : CmsUtilities.CreateBerSetFromList(outer._certs));
|
||||
WriteToGenerator(_sigGen, new BerTaggedObject(explicitly: false, 0, obj));
|
||||
}
|
||||
if (outer._crls.Count > 0)
|
||||
{
|
||||
Asn1Set obj2 = (outer.UseDerForCrls ? CmsUtilities.CreateDerSetFromList(outer._crls) : CmsUtilities.CreateBerSetFromList(outer._crls));
|
||||
WriteToGenerator(_sigGen, new BerTaggedObject(explicitly: false, 1, obj2));
|
||||
}
|
||||
foreach (object messageDigest in outer._messageDigests)
|
||||
{
|
||||
DictionaryEntry dictionaryEntry = (DictionaryEntry)messageDigest;
|
||||
outer._messageHashes.Add(dictionaryEntry.Key, DigestUtilities.DoFinal((IDigest)dictionaryEntry.Value));
|
||||
}
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (DigestAndSignerInfoGeneratorHolder signerInf in outer._signerInfs)
|
||||
{
|
||||
AlgorithmIdentifier digestAlgorithm = signerInf.DigestAlgorithm;
|
||||
byte[] array = (byte[])outer._messageHashes[Helper.GetDigestAlgName(signerInf.digestOID)];
|
||||
outer._digests[signerInf.digestOID] = array.Clone();
|
||||
asn1EncodableVector.Add(signerInf.signerInf.Generate(_contentOID, digestAlgorithm, array));
|
||||
}
|
||||
foreach (SignerInformation signer in outer._signers)
|
||||
{
|
||||
asn1EncodableVector.Add(signer.ToSignerInfo());
|
||||
}
|
||||
WriteToGenerator(_sigGen, new DerSet(asn1EncodableVector));
|
||||
_sigGen.Close();
|
||||
_sGen.Close();
|
||||
}
|
||||
|
||||
private static void WriteToGenerator(Asn1Generator ag, Asn1Encodable ae)
|
||||
{
|
||||
byte[] encoded = ae.GetEncoded();
|
||||
ag.GetRawOutputStream().Write(encoded, 0, encoded.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
|
||||
|
||||
private readonly IList _signerInfs = Platform.CreateArrayList();
|
||||
|
||||
private readonly ISet _messageDigestOids = new HashSet();
|
||||
|
||||
private readonly IDictionary _messageDigests = Platform.CreateHashtable();
|
||||
|
||||
private readonly IDictionary _messageHashes = Platform.CreateHashtable();
|
||||
|
||||
private bool _messageDigestsLocked;
|
||||
|
||||
private int _bufferSize;
|
||||
|
||||
public CmsSignedDataStreamGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataStreamGenerator(SecureRandom rand)
|
||||
: base(rand)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetBufferSize(int bufferSize)
|
||||
{
|
||||
_bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public void AddDigests(params string[] digestOids)
|
||||
{
|
||||
AddDigests((IEnumerable)digestOids);
|
||||
}
|
||||
|
||||
public void AddDigests(IEnumerable digestOids)
|
||||
{
|
||||
foreach (string digestOid in digestOids)
|
||||
{
|
||||
ConfigureDigest(digestOid);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOid)
|
||||
{
|
||||
AddSigner(privateKey, cert, digestOid, new DefaultSignedAttributeTableGenerator(), null);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string encryptionOid, string digestOid)
|
||||
{
|
||||
AddSigner(privateKey, cert, encryptionOid, digestOid, new DefaultSignedAttributeTableGenerator(), null);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOid, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
AddSigner(privateKey, cert, digestOid, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr));
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string encryptionOid, string digestOid, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
AddSigner(privateKey, cert, encryptionOid, digestOid, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr));
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOid, CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator)
|
||||
{
|
||||
AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOid), digestOid, signedAttrGenerator, unsignedAttrGenerator);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string encryptionOid, string digestOid, CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator)
|
||||
{
|
||||
DoAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(cert), encryptionOid, digestOid, signedAttrGenerator, unsignedAttrGenerator);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string digestOid)
|
||||
{
|
||||
AddSigner(privateKey, subjectKeyID, digestOid, new DefaultSignedAttributeTableGenerator(), null);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string encryptionOid, string digestOid)
|
||||
{
|
||||
AddSigner(privateKey, subjectKeyID, encryptionOid, digestOid, new DefaultSignedAttributeTableGenerator(), null);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string digestOid, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
AddSigner(privateKey, subjectKeyID, digestOid, new DefaultSignedAttributeTableGenerator(signedAttr), new SimpleAttributeTableGenerator(unsignedAttr));
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string digestOid, CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator)
|
||||
{
|
||||
AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOid), digestOid, signedAttrGenerator, unsignedAttrGenerator);
|
||||
}
|
||||
|
||||
public void AddSigner(AsymmetricKeyParameter privateKey, byte[] subjectKeyID, string encryptionOid, string digestOid, CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator)
|
||||
{
|
||||
DoAddSigner(privateKey, CmsSignedGenerator.GetSignerIdentifier(subjectKeyID), encryptionOid, digestOid, signedAttrGenerator, unsignedAttrGenerator);
|
||||
}
|
||||
|
||||
private void DoAddSigner(AsymmetricKeyParameter privateKey, SignerIdentifier signerIdentifier, string encryptionOid, string digestOid, CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator)
|
||||
{
|
||||
ConfigureDigest(digestOid);
|
||||
SignerInfoGeneratorImpl signerInf = new SignerInfoGeneratorImpl(this, privateKey, signerIdentifier, digestOid, encryptionOid, signedAttrGenerator, unsignedAttrGenerator);
|
||||
_signerInfs.Add(new DigestAndSignerInfoGeneratorHolder(signerInf, digestOid));
|
||||
}
|
||||
|
||||
internal override void AddSignerCallback(SignerInformation si)
|
||||
{
|
||||
RegisterDigestOid(si.DigestAlgorithmID.Algorithm.Id);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream)
|
||||
{
|
||||
return Open(outStream, encapsulate: false);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, bool encapsulate)
|
||||
{
|
||||
return Open(outStream, CmsSignedGenerator.Data, encapsulate);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, bool encapsulate, Stream dataOutputStream)
|
||||
{
|
||||
return Open(outStream, CmsSignedGenerator.Data, encapsulate, dataOutputStream);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, string signedContentType, bool encapsulate)
|
||||
{
|
||||
return Open(outStream, signedContentType, encapsulate, null);
|
||||
}
|
||||
|
||||
public Stream Open(Stream outStream, string signedContentType, bool encapsulate, Stream dataOutputStream)
|
||||
{
|
||||
if (outStream == null)
|
||||
{
|
||||
throw new ArgumentNullException("outStream");
|
||||
}
|
||||
if (!outStream.CanWrite)
|
||||
{
|
||||
throw new ArgumentException("Expected writeable stream", "outStream");
|
||||
}
|
||||
if (dataOutputStream != null && !dataOutputStream.CanWrite)
|
||||
{
|
||||
throw new ArgumentException("Expected writeable stream", "dataOutputStream");
|
||||
}
|
||||
_messageDigestsLocked = true;
|
||||
BerSequenceGenerator berSequenceGenerator = new BerSequenceGenerator(outStream);
|
||||
berSequenceGenerator.AddObject(CmsObjectIdentifiers.SignedData);
|
||||
BerSequenceGenerator berSequenceGenerator2 = new BerSequenceGenerator(berSequenceGenerator.GetRawOutputStream(), 0, isExplicit: true);
|
||||
DerObjectIdentifier derObjectIdentifier = ((signedContentType == null) ? null : new DerObjectIdentifier(signedContentType));
|
||||
berSequenceGenerator2.AddObject(CalculateVersion(derObjectIdentifier));
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (string messageDigestOid in _messageDigestOids)
|
||||
{
|
||||
asn1EncodableVector.Add(new AlgorithmIdentifier(new DerObjectIdentifier(messageDigestOid), DerNull.Instance));
|
||||
}
|
||||
byte[] encoded = new DerSet(asn1EncodableVector).GetEncoded();
|
||||
berSequenceGenerator2.GetRawOutputStream().Write(encoded, 0, encoded.Length);
|
||||
BerSequenceGenerator berSequenceGenerator3 = new BerSequenceGenerator(berSequenceGenerator2.GetRawOutputStream());
|
||||
berSequenceGenerator3.AddObject(derObjectIdentifier);
|
||||
Stream s = (encapsulate ? CmsUtilities.CreateBerOctetOutputStream(berSequenceGenerator3.GetRawOutputStream(), 0, isExplicit: true, _bufferSize) : null);
|
||||
Stream safeTeeOutputStream = GetSafeTeeOutputStream(dataOutputStream, s);
|
||||
Stream outStream2 = AttachDigestsToOutputStream(_messageDigests.Values, safeTeeOutputStream);
|
||||
return new CmsSignedDataOutputStream(this, outStream2, signedContentType, berSequenceGenerator, berSequenceGenerator2, berSequenceGenerator3);
|
||||
}
|
||||
|
||||
private void RegisterDigestOid(string digestOid)
|
||||
{
|
||||
if (_messageDigestsLocked)
|
||||
{
|
||||
if (!_messageDigestOids.Contains(digestOid))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot register new digest OIDs after the data stream is opened");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_messageDigestOids.Add(digestOid);
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureDigest(string digestOid)
|
||||
{
|
||||
RegisterDigestOid(digestOid);
|
||||
string digestAlgName = Helper.GetDigestAlgName(digestOid);
|
||||
IDigest digest = (IDigest)_messageDigests[digestAlgName];
|
||||
if (digest == null)
|
||||
{
|
||||
if (_messageDigestsLocked)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot configure new digests after the data stream is opened");
|
||||
}
|
||||
digest = Helper.GetDigestInstance(digestAlgName);
|
||||
_messageDigests[digestAlgName] = digest;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Generate(Stream outStream, string eContentType, bool encapsulate, Stream dataOutputStream, CmsProcessable content)
|
||||
{
|
||||
Stream stream = Open(outStream, eContentType, encapsulate, dataOutputStream);
|
||||
content?.Write(stream);
|
||||
Platform.Dispose(stream);
|
||||
}
|
||||
|
||||
private DerInteger CalculateVersion(DerObjectIdentifier contentOid)
|
||||
{
|
||||
bool flag = false;
|
||||
bool flag2 = false;
|
||||
bool flag3 = false;
|
||||
bool flag4 = false;
|
||||
if (_certs != null)
|
||||
{
|
||||
foreach (object cert in _certs)
|
||||
{
|
||||
if (cert is Asn1TaggedObject)
|
||||
{
|
||||
Asn1TaggedObject asn1TaggedObject = (Asn1TaggedObject)cert;
|
||||
if (asn1TaggedObject.TagNo == 1)
|
||||
{
|
||||
flag3 = true;
|
||||
}
|
||||
else if (asn1TaggedObject.TagNo == 2)
|
||||
{
|
||||
flag4 = true;
|
||||
}
|
||||
else if (asn1TaggedObject.TagNo == 3)
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
return new DerInteger(5);
|
||||
}
|
||||
if (_crls != null)
|
||||
{
|
||||
foreach (object crl in _crls)
|
||||
{
|
||||
if (crl is Asn1TaggedObject)
|
||||
{
|
||||
flag2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag2)
|
||||
{
|
||||
return new DerInteger(5);
|
||||
}
|
||||
if (flag4)
|
||||
{
|
||||
return new DerInteger(4);
|
||||
}
|
||||
if (flag3 || !CmsObjectIdentifiers.Data.Equals(contentOid) || CheckForVersion3(_signers))
|
||||
{
|
||||
return new DerInteger(3);
|
||||
}
|
||||
return new DerInteger(1);
|
||||
}
|
||||
|
||||
private bool CheckForVersion3(IList signerInfos)
|
||||
{
|
||||
foreach (SignerInformation signerInfo in signerInfos)
|
||||
{
|
||||
SignerInfo instance = SignerInfo.GetInstance(signerInfo.ToSignerInfo());
|
||||
if (instance.Version.Value.IntValue == 3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Stream AttachDigestsToOutputStream(ICollection digests, Stream s)
|
||||
{
|
||||
Stream stream = s;
|
||||
foreach (IDigest digest in digests)
|
||||
{
|
||||
stream = GetSafeTeeOutputStream(stream, new DigestSink(digest));
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
private static Stream GetSafeOutputStream(Stream s)
|
||||
{
|
||||
if (s == null)
|
||||
{
|
||||
return new NullOutputStream();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private static Stream GetSafeTeeOutputStream(Stream s1, Stream s2)
|
||||
{
|
||||
if (s1 == null)
|
||||
{
|
||||
return GetSafeOutputStream(s2);
|
||||
}
|
||||
if (s2 == null)
|
||||
{
|
||||
return GetSafeOutputStream(s1);
|
||||
}
|
||||
return new TeeOutputStream(s1, s2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
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.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsSignedGenerator
|
||||
{
|
||||
public static readonly string Data = CmsObjectIdentifiers.Data.Id;
|
||||
|
||||
public static readonly string DigestSha1 = OiwObjectIdentifiers.IdSha1.Id;
|
||||
|
||||
public static readonly string DigestSha224 = NistObjectIdentifiers.IdSha224.Id;
|
||||
|
||||
public static readonly string DigestSha256 = NistObjectIdentifiers.IdSha256.Id;
|
||||
|
||||
public static readonly string DigestSha384 = NistObjectIdentifiers.IdSha384.Id;
|
||||
|
||||
public static readonly string DigestSha512 = NistObjectIdentifiers.IdSha512.Id;
|
||||
|
||||
public static readonly string DigestMD5 = PkcsObjectIdentifiers.MD5.Id;
|
||||
|
||||
public static readonly string DigestGost3411 = CryptoProObjectIdentifiers.GostR3411.Id;
|
||||
|
||||
public static readonly string DigestRipeMD128 = TeleTrusTObjectIdentifiers.RipeMD128.Id;
|
||||
|
||||
public static readonly string DigestRipeMD160 = TeleTrusTObjectIdentifiers.RipeMD160.Id;
|
||||
|
||||
public static readonly string DigestRipeMD256 = TeleTrusTObjectIdentifiers.RipeMD256.Id;
|
||||
|
||||
public static readonly string EncryptionRsa = PkcsObjectIdentifiers.RsaEncryption.Id;
|
||||
|
||||
public static readonly string EncryptionDsa = X9ObjectIdentifiers.IdDsaWithSha1.Id;
|
||||
|
||||
public static readonly string EncryptionECDsa = X9ObjectIdentifiers.ECDsaWithSha1.Id;
|
||||
|
||||
public static readonly string EncryptionRsaPss = PkcsObjectIdentifiers.IdRsassaPss.Id;
|
||||
|
||||
public static readonly string EncryptionGost3410 = CryptoProObjectIdentifiers.GostR3410x94.Id;
|
||||
|
||||
public static readonly string EncryptionECGost3410 = CryptoProObjectIdentifiers.GostR3410x2001.Id;
|
||||
|
||||
internal IList _certs = Platform.CreateArrayList();
|
||||
|
||||
internal IList _crls = Platform.CreateArrayList();
|
||||
|
||||
internal IList _signers = Platform.CreateArrayList();
|
||||
|
||||
internal IDictionary _digests = Platform.CreateHashtable();
|
||||
|
||||
internal bool _useDerForCerts = false;
|
||||
|
||||
internal bool _useDerForCrls = false;
|
||||
|
||||
protected readonly SecureRandom rand;
|
||||
|
||||
public bool UseDerForCerts
|
||||
{
|
||||
get
|
||||
{
|
||||
return _useDerForCerts;
|
||||
}
|
||||
set
|
||||
{
|
||||
_useDerForCerts = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool UseDerForCrls
|
||||
{
|
||||
get
|
||||
{
|
||||
return _useDerForCrls;
|
||||
}
|
||||
set
|
||||
{
|
||||
_useDerForCrls = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected CmsSignedGenerator()
|
||||
: this(new SecureRandom())
|
||||
{
|
||||
}
|
||||
|
||||
protected CmsSignedGenerator(SecureRandom rand)
|
||||
{
|
||||
this.rand = rand;
|
||||
}
|
||||
|
||||
protected internal virtual IDictionary GetBaseParameters(DerObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
|
||||
{
|
||||
IDictionary dictionary = Platform.CreateHashtable();
|
||||
if (contentType != null)
|
||||
{
|
||||
dictionary[CmsAttributeTableParameter.ContentType] = contentType;
|
||||
}
|
||||
dictionary[CmsAttributeTableParameter.DigestAlgorithmIdentifier] = digAlgId;
|
||||
dictionary[CmsAttributeTableParameter.Digest] = hash.Clone();
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
protected internal virtual Asn1Set GetAttributeSet(Org.BouncyCastle.Asn1.Cms.AttributeTable attr)
|
||||
{
|
||||
if (attr != null)
|
||||
{
|
||||
return new DerSet(attr.ToAsn1EncodableVector());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void AddCertificates(IX509Store certStore)
|
||||
{
|
||||
CollectionUtilities.AddRange(_certs, CmsUtilities.GetCertificatesFromStore(certStore));
|
||||
}
|
||||
|
||||
public void AddCrls(IX509Store crlStore)
|
||||
{
|
||||
CollectionUtilities.AddRange(_crls, CmsUtilities.GetCrlsFromStore(crlStore));
|
||||
}
|
||||
|
||||
public void AddAttributeCertificates(IX509Store store)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (IX509AttributeCertificate match in store.GetMatches(null))
|
||||
{
|
||||
_certs.Add(new DerTaggedObject(explicitly: false, 2, AttributeCertificate.GetInstance(Asn1Object.FromByteArray(match.GetEncoded()))));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CmsException("error processing attribute certs", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSigners(SignerInformationStore signerStore)
|
||||
{
|
||||
foreach (SignerInformation signer in signerStore.GetSigners())
|
||||
{
|
||||
_signers.Add(signer);
|
||||
AddSignerCallback(signer);
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary GetGeneratedDigests()
|
||||
{
|
||||
return Platform.CreateHashtable(_digests);
|
||||
}
|
||||
|
||||
internal virtual void AddSignerCallback(SignerInformation si)
|
||||
{
|
||||
}
|
||||
|
||||
internal static SignerIdentifier GetSignerIdentifier(X509Certificate cert)
|
||||
{
|
||||
return new SignerIdentifier(CmsUtilities.GetIssuerAndSerialNumber(cert));
|
||||
}
|
||||
|
||||
internal static SignerIdentifier GetSignerIdentifier(byte[] subjectKeyIdentifier)
|
||||
{
|
||||
return new SignerIdentifier(new DerOctetString(subjectKeyIdentifier));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using Org.BouncyCastle.Asn1.Eac;
|
||||
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.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class CmsSignedHelper
|
||||
{
|
||||
internal static readonly CmsSignedHelper Instance;
|
||||
|
||||
private static readonly string EncryptionECDsaWithSha1;
|
||||
|
||||
private static readonly string EncryptionECDsaWithSha224;
|
||||
|
||||
private static readonly string EncryptionECDsaWithSha256;
|
||||
|
||||
private static readonly string EncryptionECDsaWithSha384;
|
||||
|
||||
private static readonly string EncryptionECDsaWithSha512;
|
||||
|
||||
private static readonly IDictionary encryptionAlgs;
|
||||
|
||||
private static readonly IDictionary digestAlgs;
|
||||
|
||||
private static readonly IDictionary digestAliases;
|
||||
|
||||
private static readonly ISet noParams;
|
||||
|
||||
private static readonly IDictionary ecAlgorithms;
|
||||
|
||||
private static void AddEntries(DerObjectIdentifier oid, string digest, string encryption)
|
||||
{
|
||||
string id = oid.Id;
|
||||
digestAlgs.Add(id, digest);
|
||||
encryptionAlgs.Add(id, encryption);
|
||||
}
|
||||
|
||||
static CmsSignedHelper()
|
||||
{
|
||||
Instance = new CmsSignedHelper();
|
||||
EncryptionECDsaWithSha1 = X9ObjectIdentifiers.ECDsaWithSha1.Id;
|
||||
EncryptionECDsaWithSha224 = X9ObjectIdentifiers.ECDsaWithSha224.Id;
|
||||
EncryptionECDsaWithSha256 = X9ObjectIdentifiers.ECDsaWithSha256.Id;
|
||||
EncryptionECDsaWithSha384 = X9ObjectIdentifiers.ECDsaWithSha384.Id;
|
||||
EncryptionECDsaWithSha512 = X9ObjectIdentifiers.ECDsaWithSha512.Id;
|
||||
encryptionAlgs = Platform.CreateHashtable();
|
||||
digestAlgs = Platform.CreateHashtable();
|
||||
digestAliases = Platform.CreateHashtable();
|
||||
noParams = new HashSet();
|
||||
ecAlgorithms = Platform.CreateHashtable();
|
||||
AddEntries(NistObjectIdentifiers.DsaWithSha224, "SHA224", "DSA");
|
||||
AddEntries(NistObjectIdentifiers.DsaWithSha256, "SHA256", "DSA");
|
||||
AddEntries(NistObjectIdentifiers.DsaWithSha384, "SHA384", "DSA");
|
||||
AddEntries(NistObjectIdentifiers.DsaWithSha512, "SHA512", "DSA");
|
||||
AddEntries(OiwObjectIdentifiers.DsaWithSha1, "SHA1", "DSA");
|
||||
AddEntries(OiwObjectIdentifiers.MD4WithRsa, "MD4", "RSA");
|
||||
AddEntries(OiwObjectIdentifiers.MD4WithRsaEncryption, "MD4", "RSA");
|
||||
AddEntries(OiwObjectIdentifiers.MD5WithRsa, "MD5", "RSA");
|
||||
AddEntries(OiwObjectIdentifiers.Sha1WithRsa, "SHA1", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.MD2WithRsaEncryption, "MD2", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.MD4WithRsaEncryption, "MD4", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.MD5WithRsaEncryption, "MD5", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384", "RSA");
|
||||
AddEntries(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512", "RSA");
|
||||
AddEntries(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1", "ECDSA");
|
||||
AddEntries(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224", "ECDSA");
|
||||
AddEntries(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256", "ECDSA");
|
||||
AddEntries(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384", "ECDSA");
|
||||
AddEntries(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512", "ECDSA");
|
||||
AddEntries(X9ObjectIdentifiers.IdDsaWithSha1, "SHA1", "DSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1");
|
||||
AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1");
|
||||
encryptionAlgs.Add(X9ObjectIdentifiers.IdDsa.Id, "DSA");
|
||||
encryptionAlgs.Add(PkcsObjectIdentifiers.RsaEncryption.Id, "RSA");
|
||||
encryptionAlgs.Add(TeleTrusTObjectIdentifiers.TeleTrusTRsaSignatureAlgorithm, "RSA");
|
||||
encryptionAlgs.Add(X509ObjectIdentifiers.IdEARsa.Id, "RSA");
|
||||
encryptionAlgs.Add(CmsSignedGenerator.EncryptionRsaPss, "RSAandMGF1");
|
||||
encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x94.Id, "GOST3410");
|
||||
encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x2001.Id, "ECGOST3410");
|
||||
encryptionAlgs.Add("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410");
|
||||
encryptionAlgs.Add("1.3.6.1.4.1.5849.1.1.5", "GOST3410");
|
||||
digestAlgs.Add(PkcsObjectIdentifiers.MD2.Id, "MD2");
|
||||
digestAlgs.Add(PkcsObjectIdentifiers.MD4.Id, "MD4");
|
||||
digestAlgs.Add(PkcsObjectIdentifiers.MD5.Id, "MD5");
|
||||
digestAlgs.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1");
|
||||
digestAlgs.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224");
|
||||
digestAlgs.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256");
|
||||
digestAlgs.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384");
|
||||
digestAlgs.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512");
|
||||
digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128");
|
||||
digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160");
|
||||
digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256");
|
||||
digestAlgs.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411");
|
||||
digestAlgs.Add("1.3.6.1.4.1.5849.1.2.1", "GOST3411");
|
||||
digestAliases.Add("SHA1", new string[1] { "SHA-1" });
|
||||
digestAliases.Add("SHA224", new string[1] { "SHA-224" });
|
||||
digestAliases.Add("SHA256", new string[1] { "SHA-256" });
|
||||
digestAliases.Add("SHA384", new string[1] { "SHA-384" });
|
||||
digestAliases.Add("SHA512", new string[1] { "SHA-512" });
|
||||
noParams.Add(CmsSignedGenerator.EncryptionDsa);
|
||||
noParams.Add(EncryptionECDsaWithSha1);
|
||||
noParams.Add(EncryptionECDsaWithSha224);
|
||||
noParams.Add(EncryptionECDsaWithSha256);
|
||||
noParams.Add(EncryptionECDsaWithSha384);
|
||||
noParams.Add(EncryptionECDsaWithSha512);
|
||||
ecAlgorithms.Add(CmsSignedGenerator.DigestSha1, EncryptionECDsaWithSha1);
|
||||
ecAlgorithms.Add(CmsSignedGenerator.DigestSha224, EncryptionECDsaWithSha224);
|
||||
ecAlgorithms.Add(CmsSignedGenerator.DigestSha256, EncryptionECDsaWithSha256);
|
||||
ecAlgorithms.Add(CmsSignedGenerator.DigestSha384, EncryptionECDsaWithSha384);
|
||||
ecAlgorithms.Add(CmsSignedGenerator.DigestSha512, EncryptionECDsaWithSha512);
|
||||
}
|
||||
|
||||
internal string GetDigestAlgName(string digestAlgOid)
|
||||
{
|
||||
string text = (string)digestAlgs[digestAlgOid];
|
||||
if (text != null)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
return digestAlgOid;
|
||||
}
|
||||
|
||||
internal AlgorithmIdentifier GetEncAlgorithmIdentifier(DerObjectIdentifier encOid, Asn1Encodable sigX509Parameters)
|
||||
{
|
||||
if (noParams.Contains(encOid.Id))
|
||||
{
|
||||
return new AlgorithmIdentifier(encOid);
|
||||
}
|
||||
return new AlgorithmIdentifier(encOid, sigX509Parameters);
|
||||
}
|
||||
|
||||
internal string[] GetDigestAliases(string algName)
|
||||
{
|
||||
string[] array = (string[])digestAliases[algName];
|
||||
if (array != null)
|
||||
{
|
||||
return (string[])array.Clone();
|
||||
}
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
internal string GetEncryptionAlgName(string encryptionAlgOid)
|
||||
{
|
||||
string text = (string)encryptionAlgs[encryptionAlgOid];
|
||||
if (text != null)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
return encryptionAlgOid;
|
||||
}
|
||||
|
||||
internal IDigest GetDigestInstance(string algorithm)
|
||||
{
|
||||
try
|
||||
{
|
||||
return DigestUtilities.GetDigest(algorithm);
|
||||
}
|
||||
catch (SecurityUtilityException ex)
|
||||
{
|
||||
string[] array = GetDigestAliases(algorithm);
|
||||
foreach (string algorithm2 in array)
|
||||
{
|
||||
try
|
||||
{
|
||||
return DigestUtilities.GetDigest(algorithm2);
|
||||
}
|
||||
catch (SecurityUtilityException)
|
||||
{
|
||||
}
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
internal ISigner GetSignatureInstance(string algorithm)
|
||||
{
|
||||
return SignerUtilities.GetSigner(algorithm);
|
||||
}
|
||||
|
||||
internal IX509Store CreateAttributeStore(string type, Asn1Set certSet)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
if (certSet != null)
|
||||
{
|
||||
foreach (Asn1Encodable item in certSet)
|
||||
{
|
||||
try
|
||||
{
|
||||
Asn1Object asn1Object = item.ToAsn1Object();
|
||||
if (asn1Object is Asn1TaggedObject)
|
||||
{
|
||||
Asn1TaggedObject asn1TaggedObject = (Asn1TaggedObject)asn1Object;
|
||||
if (asn1TaggedObject.TagNo == 2)
|
||||
{
|
||||
list.Add(new X509V2AttributeCertificate(Asn1Sequence.GetInstance(asn1TaggedObject, explicitly: false).GetEncoded()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CmsException("can't re-encode attribute certificate!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
return X509StoreFactory.Create("AttributeCertificate/" + type, new X509CollectionStoreParameters(list));
|
||||
}
|
||||
catch (ArgumentException e2)
|
||||
{
|
||||
throw new CmsException("can't setup the X509Store", e2);
|
||||
}
|
||||
}
|
||||
|
||||
internal IX509Store CreateCertificateStore(string type, Asn1Set certSet)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
if (certSet != null)
|
||||
{
|
||||
AddCertsFromSet(list, certSet);
|
||||
}
|
||||
try
|
||||
{
|
||||
return X509StoreFactory.Create("Certificate/" + type, new X509CollectionStoreParameters(list));
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new CmsException("can't setup the X509Store", e);
|
||||
}
|
||||
}
|
||||
|
||||
internal IX509Store CreateCrlStore(string type, Asn1Set crlSet)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
if (crlSet != null)
|
||||
{
|
||||
AddCrlsFromSet(list, crlSet);
|
||||
}
|
||||
try
|
||||
{
|
||||
return X509StoreFactory.Create("CRL/" + type, new X509CollectionStoreParameters(list));
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new CmsException("can't setup the X509Store", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddCertsFromSet(IList certs, Asn1Set certSet)
|
||||
{
|
||||
X509CertificateParser x509CertificateParser = new X509CertificateParser();
|
||||
foreach (Asn1Encodable item in certSet)
|
||||
{
|
||||
try
|
||||
{
|
||||
Asn1Object asn1Object = item.ToAsn1Object();
|
||||
if (asn1Object is Asn1Sequence)
|
||||
{
|
||||
certs.Add(x509CertificateParser.ReadCertificate(asn1Object.GetEncoded()));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CmsException("can't re-encode certificate!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddCrlsFromSet(IList crls, Asn1Set crlSet)
|
||||
{
|
||||
X509CrlParser x509CrlParser = new X509CrlParser();
|
||||
foreach (Asn1Encodable item in crlSet)
|
||||
{
|
||||
try
|
||||
{
|
||||
crls.Add(x509CrlParser.ReadCrl(item.GetEncoded()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CmsException("can't re-encode CRL!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal AlgorithmIdentifier FixAlgID(AlgorithmIdentifier algId)
|
||||
{
|
||||
if (algId.Parameters == null)
|
||||
{
|
||||
return new AlgorithmIdentifier(algId.Algorithm, DerNull.Instance);
|
||||
}
|
||||
return algId;
|
||||
}
|
||||
|
||||
internal string GetEncOid(AsymmetricKeyParameter key, string digestOID)
|
||||
{
|
||||
string text = null;
|
||||
if (key is RsaKeyParameters)
|
||||
{
|
||||
if (!((RsaKeyParameters)key).IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected RSA private key");
|
||||
}
|
||||
text = CmsSignedGenerator.EncryptionRsa;
|
||||
}
|
||||
else if (key is DsaPrivateKeyParameters)
|
||||
{
|
||||
if (digestOID.Equals(CmsSignedGenerator.DigestSha1))
|
||||
{
|
||||
text = CmsSignedGenerator.EncryptionDsa;
|
||||
}
|
||||
else if (digestOID.Equals(CmsSignedGenerator.DigestSha224))
|
||||
{
|
||||
text = NistObjectIdentifiers.DsaWithSha224.Id;
|
||||
}
|
||||
else if (digestOID.Equals(CmsSignedGenerator.DigestSha256))
|
||||
{
|
||||
text = NistObjectIdentifiers.DsaWithSha256.Id;
|
||||
}
|
||||
else if (digestOID.Equals(CmsSignedGenerator.DigestSha384))
|
||||
{
|
||||
text = NistObjectIdentifiers.DsaWithSha384.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!digestOID.Equals(CmsSignedGenerator.DigestSha512))
|
||||
{
|
||||
throw new ArgumentException("can't mix DSA with anything but SHA1/SHA2");
|
||||
}
|
||||
text = NistObjectIdentifiers.DsaWithSha512.Id;
|
||||
}
|
||||
}
|
||||
else if (key is ECPrivateKeyParameters)
|
||||
{
|
||||
ECPrivateKeyParameters eCPrivateKeyParameters = (ECPrivateKeyParameters)key;
|
||||
string algorithmName = eCPrivateKeyParameters.AlgorithmName;
|
||||
if (algorithmName == "ECGOST3410")
|
||||
{
|
||||
text = CmsSignedGenerator.EncryptionECGost3410;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = (string)ecAlgorithms[digestOID];
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentException("can't mix ECDSA with anything but SHA family digests");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(key is Gost3410PrivateKeyParameters))
|
||||
{
|
||||
throw new ArgumentException("Unknown algorithm in CmsSignedGenerator.GetEncOid");
|
||||
}
|
||||
text = CmsSignedGenerator.EncryptionGost3410;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
[Serializable]
|
||||
public class CmsStreamException : IOException
|
||||
{
|
||||
public CmsStreamException()
|
||||
{
|
||||
}
|
||||
|
||||
public CmsStreamException(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsStreamException(string name, Exception e)
|
||||
: base(name, e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsTypedStream
|
||||
{
|
||||
private class FullReaderStream : FilterStream
|
||||
{
|
||||
internal FullReaderStream(Stream input)
|
||||
: base(input)
|
||||
{
|
||||
}
|
||||
|
||||
public override int Read(byte[] buf, int off, int len)
|
||||
{
|
||||
return Streams.ReadFully(s, buf, off, len);
|
||||
}
|
||||
}
|
||||
|
||||
private const int BufferSize = 32768;
|
||||
|
||||
private readonly string _oid;
|
||||
|
||||
private readonly Stream _in;
|
||||
|
||||
public string ContentType => _oid;
|
||||
|
||||
public Stream ContentStream => _in;
|
||||
|
||||
public CmsTypedStream(Stream inStream)
|
||||
: this(PkcsObjectIdentifiers.Data.Id, inStream, 32768)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsTypedStream(string oid, Stream inStream)
|
||||
: this(oid, inStream, 32768)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsTypedStream(string oid, Stream inStream, int bufSize)
|
||||
{
|
||||
_oid = oid;
|
||||
_in = new FullReaderStream(new BufferedStream(inStream, bufSize));
|
||||
}
|
||||
|
||||
public void Drain()
|
||||
{
|
||||
Streams.Drain(_in);
|
||||
Platform.Dispose(_in);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class CmsUtilities
|
||||
{
|
||||
internal static int MaximumMemory
|
||||
{
|
||||
get
|
||||
{
|
||||
long num = 2147483647L;
|
||||
if (num > int.MaxValue)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
return (int)num;
|
||||
}
|
||||
}
|
||||
|
||||
internal static ContentInfo ReadContentInfo(byte[] input)
|
||||
{
|
||||
return ReadContentInfo(new Asn1InputStream(input));
|
||||
}
|
||||
|
||||
internal static ContentInfo ReadContentInfo(Stream input)
|
||||
{
|
||||
return ReadContentInfo(new Asn1InputStream(input, MaximumMemory));
|
||||
}
|
||||
|
||||
private static ContentInfo ReadContentInfo(Asn1InputStream aIn)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ContentInfo.GetInstance(aIn.ReadObject());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("IOException reading content.", e);
|
||||
}
|
||||
catch (InvalidCastException e2)
|
||||
{
|
||||
throw new CmsException("Malformed content.", e2);
|
||||
}
|
||||
catch (ArgumentException e3)
|
||||
{
|
||||
throw new CmsException("Malformed content.", e3);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] StreamToByteArray(Stream inStream)
|
||||
{
|
||||
return Streams.ReadAll(inStream);
|
||||
}
|
||||
|
||||
public static byte[] StreamToByteArray(Stream inStream, int limit)
|
||||
{
|
||||
return Streams.ReadAllLimited(inStream, limit);
|
||||
}
|
||||
|
||||
public static IList GetCertificatesFromStore(IX509Store certStore)
|
||||
{
|
||||
try
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
if (certStore != null)
|
||||
{
|
||||
foreach (X509Certificate match in certStore.GetMatches(null))
|
||||
{
|
||||
list.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(match.GetEncoded())));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
catch (CertificateEncodingException e)
|
||||
{
|
||||
throw new CmsException("error encoding certs", e);
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
throw new CmsException("error processing certs", e2);
|
||||
}
|
||||
}
|
||||
|
||||
public static IList GetCrlsFromStore(IX509Store crlStore)
|
||||
{
|
||||
try
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
if (crlStore != null)
|
||||
{
|
||||
foreach (X509Crl match in crlStore.GetMatches(null))
|
||||
{
|
||||
list.Add(CertificateList.GetInstance(Asn1Object.FromByteArray(match.GetEncoded())));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
catch (CrlException e)
|
||||
{
|
||||
throw new CmsException("error encoding crls", e);
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
throw new CmsException("error processing crls", e2);
|
||||
}
|
||||
}
|
||||
|
||||
public static Asn1Set CreateBerSetFromList(IList berObjects)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (Asn1Encodable berObject in berObjects)
|
||||
{
|
||||
asn1EncodableVector.Add(berObject);
|
||||
}
|
||||
return new BerSet(asn1EncodableVector);
|
||||
}
|
||||
|
||||
public static Asn1Set CreateDerSetFromList(IList derObjects)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (Asn1Encodable derObject in derObjects)
|
||||
{
|
||||
asn1EncodableVector.Add(derObject);
|
||||
}
|
||||
return new DerSet(asn1EncodableVector);
|
||||
}
|
||||
|
||||
internal static Stream CreateBerOctetOutputStream(Stream s, int tagNo, bool isExplicit, int bufferSize)
|
||||
{
|
||||
BerOctetStringGenerator berOctetStringGenerator = new BerOctetStringGenerator(s, tagNo, isExplicit);
|
||||
return berOctetStringGenerator.GetOctetOutputStream(bufferSize);
|
||||
}
|
||||
|
||||
internal static TbsCertificateStructure GetTbsCertificateStructure(X509Certificate cert)
|
||||
{
|
||||
return TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetTbsCertificate()));
|
||||
}
|
||||
|
||||
internal static IssuerAndSerialNumber GetIssuerAndSerialNumber(X509Certificate cert)
|
||||
{
|
||||
TbsCertificateStructure tbsCertificateStructure = GetTbsCertificateStructure(cert);
|
||||
return new IssuerAndSerialNumber(tbsCertificateStructure.Issuer, tbsCertificateStructure.SerialNumber.Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class CounterSignatureDigestCalculator : IDigestCalculator
|
||||
{
|
||||
private readonly string alg;
|
||||
|
||||
private readonly byte[] data;
|
||||
|
||||
internal CounterSignatureDigestCalculator(string alg, byte[] data)
|
||||
{
|
||||
this.alg = alg;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public byte[] GetDigest()
|
||||
{
|
||||
IDigest digestInstance = CmsSignedHelper.Instance.GetDigestInstance(alg);
|
||||
return DigestUtilities.DoFinal(digestInstance, data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class DefaultAuthenticatedAttributeTableGenerator : CmsAttributeTableGenerator
|
||||
{
|
||||
private readonly IDictionary table;
|
||||
|
||||
public DefaultAuthenticatedAttributeTableGenerator()
|
||||
{
|
||||
table = Platform.CreateHashtable();
|
||||
}
|
||||
|
||||
public DefaultAuthenticatedAttributeTableGenerator(AttributeTable attributeTable)
|
||||
{
|
||||
if (attributeTable != null)
|
||||
{
|
||||
table = attributeTable.ToDictionary();
|
||||
}
|
||||
else
|
||||
{
|
||||
table = Platform.CreateHashtable();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IDictionary CreateStandardAttributeTable(IDictionary parameters)
|
||||
{
|
||||
IDictionary dictionary = Platform.CreateHashtable(table);
|
||||
if (!dictionary.Contains(CmsAttributes.ContentType))
|
||||
{
|
||||
DerObjectIdentifier obj = (DerObjectIdentifier)parameters[CmsAttributeTableParameter.ContentType];
|
||||
Attribute attribute = new Attribute(CmsAttributes.ContentType, new DerSet(obj));
|
||||
dictionary[attribute.AttrType] = attribute;
|
||||
}
|
||||
if (!dictionary.Contains(CmsAttributes.MessageDigest))
|
||||
{
|
||||
byte[] str = (byte[])parameters[CmsAttributeTableParameter.Digest];
|
||||
Attribute attribute2 = new Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(str)));
|
||||
dictionary[attribute2.AttrType] = attribute2;
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public virtual AttributeTable GetAttributes(IDictionary parameters)
|
||||
{
|
||||
IDictionary attrs = CreateStandardAttributeTable(parameters);
|
||||
return new AttributeTable(attrs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Collections;
|
||||
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.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class DefaultDigestAlgorithmIdentifierFinder
|
||||
{
|
||||
private static readonly IDictionary digestOids;
|
||||
|
||||
private static readonly IDictionary digestNameToOids;
|
||||
|
||||
static DefaultDigestAlgorithmIdentifierFinder()
|
||||
{
|
||||
digestOids = Platform.CreateHashtable();
|
||||
digestNameToOids = Platform.CreateHashtable();
|
||||
digestOids.Add(OiwObjectIdentifiers.MD4WithRsaEncryption, PkcsObjectIdentifiers.MD4);
|
||||
digestOids.Add(OiwObjectIdentifiers.MD4WithRsa, PkcsObjectIdentifiers.MD4);
|
||||
digestOids.Add(OiwObjectIdentifiers.MD5WithRsa, PkcsObjectIdentifiers.MD5);
|
||||
digestOids.Add(OiwObjectIdentifiers.Sha1WithRsa, OiwObjectIdentifiers.IdSha1);
|
||||
digestOids.Add(OiwObjectIdentifiers.DsaWithSha1, OiwObjectIdentifiers.IdSha1);
|
||||
digestOids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, NistObjectIdentifiers.IdSha224);
|
||||
digestOids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, NistObjectIdentifiers.IdSha256);
|
||||
digestOids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, NistObjectIdentifiers.IdSha384);
|
||||
digestOids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, NistObjectIdentifiers.IdSha512);
|
||||
digestOids.Add(PkcsObjectIdentifiers.MD2WithRsaEncryption, PkcsObjectIdentifiers.MD2);
|
||||
digestOids.Add(PkcsObjectIdentifiers.MD4WithRsaEncryption, PkcsObjectIdentifiers.MD4);
|
||||
digestOids.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption, PkcsObjectIdentifiers.MD5);
|
||||
digestOids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, OiwObjectIdentifiers.IdSha1);
|
||||
digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha1, OiwObjectIdentifiers.IdSha1);
|
||||
digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha224, NistObjectIdentifiers.IdSha224);
|
||||
digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha256, NistObjectIdentifiers.IdSha256);
|
||||
digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha384, NistObjectIdentifiers.IdSha384);
|
||||
digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha512, NistObjectIdentifiers.IdSha512);
|
||||
digestOids.Add(X9ObjectIdentifiers.IdDsaWithSha1, OiwObjectIdentifiers.IdSha1);
|
||||
digestOids.Add(NistObjectIdentifiers.DsaWithSha224, NistObjectIdentifiers.IdSha224);
|
||||
digestOids.Add(NistObjectIdentifiers.DsaWithSha256, NistObjectIdentifiers.IdSha256);
|
||||
digestOids.Add(NistObjectIdentifiers.DsaWithSha384, NistObjectIdentifiers.IdSha384);
|
||||
digestOids.Add(NistObjectIdentifiers.DsaWithSha512, NistObjectIdentifiers.IdSha512);
|
||||
digestOids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128, TeleTrusTObjectIdentifiers.RipeMD128);
|
||||
digestOids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160, TeleTrusTObjectIdentifiers.RipeMD160);
|
||||
digestOids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256, TeleTrusTObjectIdentifiers.RipeMD256);
|
||||
digestOids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, CryptoProObjectIdentifiers.GostR3411);
|
||||
digestOids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001, CryptoProObjectIdentifiers.GostR3411);
|
||||
digestNameToOids.Add("SHA-1", OiwObjectIdentifiers.IdSha1);
|
||||
digestNameToOids.Add("SHA-224", NistObjectIdentifiers.IdSha224);
|
||||
digestNameToOids.Add("SHA-256", NistObjectIdentifiers.IdSha256);
|
||||
digestNameToOids.Add("SHA-384", NistObjectIdentifiers.IdSha384);
|
||||
digestNameToOids.Add("SHA-512", NistObjectIdentifiers.IdSha512);
|
||||
digestNameToOids.Add("SHA1", OiwObjectIdentifiers.IdSha1);
|
||||
digestNameToOids.Add("SHA224", NistObjectIdentifiers.IdSha224);
|
||||
digestNameToOids.Add("SHA256", NistObjectIdentifiers.IdSha256);
|
||||
digestNameToOids.Add("SHA384", NistObjectIdentifiers.IdSha384);
|
||||
digestNameToOids.Add("SHA512", NistObjectIdentifiers.IdSha512);
|
||||
digestNameToOids.Add("SHA3-224", NistObjectIdentifiers.IdSha3_224);
|
||||
digestNameToOids.Add("SHA3-256", NistObjectIdentifiers.IdSha3_256);
|
||||
digestNameToOids.Add("SHA3-384", NistObjectIdentifiers.IdSha3_384);
|
||||
digestNameToOids.Add("SHA3-512", NistObjectIdentifiers.IdSha3_512);
|
||||
digestNameToOids.Add("SHAKE-128", NistObjectIdentifiers.IdShake128);
|
||||
digestNameToOids.Add("SHAKE-256", NistObjectIdentifiers.IdShake256);
|
||||
digestNameToOids.Add("GOST3411", CryptoProObjectIdentifiers.GostR3411);
|
||||
digestNameToOids.Add("MD2", PkcsObjectIdentifiers.MD2);
|
||||
digestNameToOids.Add("MD4", PkcsObjectIdentifiers.MD4);
|
||||
digestNameToOids.Add("MD5", PkcsObjectIdentifiers.MD5);
|
||||
digestNameToOids.Add("RIPEMD128", TeleTrusTObjectIdentifiers.RipeMD128);
|
||||
digestNameToOids.Add("RIPEMD160", TeleTrusTObjectIdentifiers.RipeMD160);
|
||||
digestNameToOids.Add("RIPEMD256", TeleTrusTObjectIdentifiers.RipeMD256);
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId)
|
||||
{
|
||||
if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
|
||||
{
|
||||
return RsassaPssParameters.GetInstance(sigAlgId.Parameters).HashAlgorithm;
|
||||
}
|
||||
return new AlgorithmIdentifier((DerObjectIdentifier)digestOids[sigAlgId.Algorithm], DerNull.Instance);
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier find(string digAlgName)
|
||||
{
|
||||
return new AlgorithmIdentifier((DerObjectIdentifier)digestNameToOids[digAlgName], DerNull.Instance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.BC;
|
||||
using Org.BouncyCastle.Asn1.Bsi;
|
||||
using Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using Org.BouncyCastle.Asn1.Eac;
|
||||
using Org.BouncyCastle.Asn1.GM;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Asn1.Oiw;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.Rosstandart;
|
||||
using Org.BouncyCastle.Asn1.TeleTrust;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class DefaultSignatureAlgorithmIdentifierFinder
|
||||
{
|
||||
private static readonly IDictionary algorithms;
|
||||
|
||||
private static readonly ISet noParams;
|
||||
|
||||
private static readonly IDictionary _params;
|
||||
|
||||
private static readonly ISet pkcs15RsaEncryption;
|
||||
|
||||
private static readonly IDictionary digestOids;
|
||||
|
||||
private static readonly IDictionary digestBuilders;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_RSA;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_DSA;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_ECDSA;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_RSA_PSS;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_GOST3410;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410_2012_256;
|
||||
|
||||
private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410_2012_512;
|
||||
|
||||
static DefaultSignatureAlgorithmIdentifierFinder()
|
||||
{
|
||||
algorithms = Platform.CreateHashtable();
|
||||
noParams = new HashSet();
|
||||
_params = Platform.CreateHashtable();
|
||||
pkcs15RsaEncryption = new HashSet();
|
||||
digestOids = Platform.CreateHashtable();
|
||||
digestBuilders = Platform.CreateHashtable();
|
||||
ENCRYPTION_RSA = PkcsObjectIdentifiers.RsaEncryption;
|
||||
ENCRYPTION_DSA = X9ObjectIdentifiers.IdDsaWithSha1;
|
||||
ENCRYPTION_ECDSA = X9ObjectIdentifiers.ECDsaWithSha1;
|
||||
ENCRYPTION_RSA_PSS = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.GostR3410x94;
|
||||
ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.GostR3410x2001;
|
||||
ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
|
||||
ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512;
|
||||
algorithms["MD2WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
|
||||
algorithms["MD2WITHRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
|
||||
algorithms["MD5WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
|
||||
algorithms["MD5WITHRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
|
||||
algorithms["SHA1WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
|
||||
algorithms["SHA1WITHRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
|
||||
algorithms["SHA-1WITHRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
|
||||
algorithms["SHA224WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption;
|
||||
algorithms["SHA224WITHRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption;
|
||||
algorithms["SHA256WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
|
||||
algorithms["SHA256WITHRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
|
||||
algorithms["SHA384WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption;
|
||||
algorithms["SHA384WITHRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption;
|
||||
algorithms["SHA512WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption;
|
||||
algorithms["SHA512WITHRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption;
|
||||
algorithms["SHA1WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA224WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA256WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA384WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA512WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA3-224WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA3-256WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA3-384WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["SHA3-512WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
|
||||
algorithms["RIPEMD160WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160;
|
||||
algorithms["RIPEMD160WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160;
|
||||
algorithms["RIPEMD128WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128;
|
||||
algorithms["RIPEMD128WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128;
|
||||
algorithms["RIPEMD256WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256;
|
||||
algorithms["RIPEMD256WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256;
|
||||
algorithms["SHA1WITHDSA"] = X9ObjectIdentifiers.IdDsaWithSha1;
|
||||
algorithms["SHA-1WITHDSA"] = X9ObjectIdentifiers.IdDsaWithSha1;
|
||||
algorithms["DSAWITHSHA1"] = X9ObjectIdentifiers.IdDsaWithSha1;
|
||||
algorithms["SHA224WITHDSA"] = NistObjectIdentifiers.DsaWithSha224;
|
||||
algorithms["SHA256WITHDSA"] = NistObjectIdentifiers.DsaWithSha256;
|
||||
algorithms["SHA384WITHDSA"] = NistObjectIdentifiers.DsaWithSha384;
|
||||
algorithms["SHA512WITHDSA"] = NistObjectIdentifiers.DsaWithSha512;
|
||||
algorithms["SHA3-224WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_224;
|
||||
algorithms["SHA3-256WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_256;
|
||||
algorithms["SHA3-384WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_384;
|
||||
algorithms["SHA3-512WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_512;
|
||||
algorithms["SHA3-224WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_224;
|
||||
algorithms["SHA3-256WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_256;
|
||||
algorithms["SHA3-384WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_384;
|
||||
algorithms["SHA3-512WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_512;
|
||||
algorithms["SHA3-224WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224;
|
||||
algorithms["SHA3-256WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256;
|
||||
algorithms["SHA3-384WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384;
|
||||
algorithms["SHA3-512WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512;
|
||||
algorithms["SHA3-224WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224;
|
||||
algorithms["SHA3-256WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256;
|
||||
algorithms["SHA3-384WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384;
|
||||
algorithms["SHA3-512WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512;
|
||||
algorithms["SHA1WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1;
|
||||
algorithms["ECDSAWITHSHA1"] = X9ObjectIdentifiers.ECDsaWithSha1;
|
||||
algorithms["SHA224WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224;
|
||||
algorithms["SHA256WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224;
|
||||
algorithms["SHA384WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384;
|
||||
algorithms["SHA512WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256;
|
||||
algorithms["GOST3411WITHGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
|
||||
algorithms["GOST3411WITHGOST3410-94"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
|
||||
algorithms["GOST3411WITHECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
|
||||
algorithms["GOST3411WITHECGOST3410-2001"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
|
||||
algorithms["GOST3411WITHGOST3410-2001"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
|
||||
algorithms["GOST3411WITHECGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
|
||||
algorithms["GOST3411WITHECGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
|
||||
algorithms["GOST3411WITHGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
|
||||
algorithms["GOST3411WITHGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
|
||||
algorithms["GOST3411-2012-256WITHECGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
|
||||
algorithms["GOST3411-2012-512WITHECGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
|
||||
algorithms["GOST3411-2012-256WITHGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
|
||||
algorithms["GOST3411-2012-512WITHGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
|
||||
algorithms["SHA1WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA1;
|
||||
algorithms["SHA224WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA224;
|
||||
algorithms["SHA256WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA256;
|
||||
algorithms["SHA384WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA384;
|
||||
algorithms["SHA512WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA512;
|
||||
algorithms["RIPEMD160WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_RIPEMD160;
|
||||
algorithms["SHA1WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_1;
|
||||
algorithms["SHA224WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_224;
|
||||
algorithms["SHA256WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_256;
|
||||
algorithms["SHA384WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_384;
|
||||
algorithms["SHA512WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512;
|
||||
algorithms["SHA3-512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA3_512;
|
||||
algorithms["SHA512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA512;
|
||||
algorithms["SM3WITHSM2"] = GMObjectIdentifiers.sm2sign_with_sm3;
|
||||
algorithms["SHA256WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHA256;
|
||||
algorithms["SHA512WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHA512;
|
||||
algorithms["SHAKE128WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHAKE128;
|
||||
algorithms["SHAKE256WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHAKE256;
|
||||
algorithms["SHA256WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHA256;
|
||||
algorithms["SHA512WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHA512;
|
||||
algorithms["SHAKE128WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHAKE128;
|
||||
algorithms["SHAKE256WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHAKE256;
|
||||
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(NistObjectIdentifiers.DsaWithSha384);
|
||||
noParams.Add(NistObjectIdentifiers.DsaWithSha512);
|
||||
noParams.Add(NistObjectIdentifiers.IdDsaWithSha3_224);
|
||||
noParams.Add(NistObjectIdentifiers.IdDsaWithSha3_256);
|
||||
noParams.Add(NistObjectIdentifiers.IdDsaWithSha3_384);
|
||||
noParams.Add(NistObjectIdentifiers.IdDsaWithSha3_512);
|
||||
noParams.Add(NistObjectIdentifiers.IdEcdsaWithSha3_224);
|
||||
noParams.Add(NistObjectIdentifiers.IdEcdsaWithSha3_256);
|
||||
noParams.Add(NistObjectIdentifiers.IdEcdsaWithSha3_384);
|
||||
noParams.Add(NistObjectIdentifiers.IdEcdsaWithSha3_512);
|
||||
noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
|
||||
noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
noParams.Add(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
|
||||
noParams.Add(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
|
||||
noParams.Add(BCObjectIdentifiers.sphincs256_with_SHA512);
|
||||
noParams.Add(BCObjectIdentifiers.sphincs256_with_SHA3_512);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_with_SHA256);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_with_SHA512);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_with_SHAKE128);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_with_SHAKE256);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_mt_with_SHA256);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_mt_with_SHA512);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_mt_with_SHAKE128);
|
||||
noParams.Add(BCObjectIdentifiers.xmss_mt_with_SHAKE256);
|
||||
noParams.Add(GMObjectIdentifiers.sm2sign_with_sm3);
|
||||
pkcs15RsaEncryption.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
|
||||
pkcs15RsaEncryption.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption);
|
||||
pkcs15RsaEncryption.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption);
|
||||
pkcs15RsaEncryption.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption);
|
||||
pkcs15RsaEncryption.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption);
|
||||
pkcs15RsaEncryption.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
|
||||
pkcs15RsaEncryption.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
|
||||
pkcs15RsaEncryption.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
|
||||
pkcs15RsaEncryption.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224);
|
||||
pkcs15RsaEncryption.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256);
|
||||
pkcs15RsaEncryption.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384);
|
||||
pkcs15RsaEncryption.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512);
|
||||
AlgorithmIdentifier hashAlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
|
||||
_params["SHA1WITHRSAANDMGF1"] = CreatePssParams(hashAlgId, 20);
|
||||
AlgorithmIdentifier hashAlgId2 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
|
||||
_params["SHA224WITHRSAANDMGF1"] = CreatePssParams(hashAlgId2, 28);
|
||||
AlgorithmIdentifier hashAlgId3 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
|
||||
_params["SHA256WITHRSAANDMGF1"] = CreatePssParams(hashAlgId3, 32);
|
||||
AlgorithmIdentifier hashAlgId4 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
|
||||
_params["SHA384WITHRSAANDMGF1"] = CreatePssParams(hashAlgId4, 48);
|
||||
AlgorithmIdentifier hashAlgId5 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
|
||||
_params["SHA512WITHRSAANDMGF1"] = CreatePssParams(hashAlgId5, 64);
|
||||
AlgorithmIdentifier hashAlgId6 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_224, DerNull.Instance);
|
||||
_params["SHA3-224WITHRSAANDMGF1"] = CreatePssParams(hashAlgId6, 28);
|
||||
AlgorithmIdentifier hashAlgId7 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_256, DerNull.Instance);
|
||||
_params["SHA3-256WITHRSAANDMGF1"] = CreatePssParams(hashAlgId7, 32);
|
||||
AlgorithmIdentifier hashAlgId8 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_384, DerNull.Instance);
|
||||
_params["SHA3-384WITHRSAANDMGF1"] = CreatePssParams(hashAlgId8, 48);
|
||||
AlgorithmIdentifier hashAlgId9 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_512, DerNull.Instance);
|
||||
_params["SHA3-512WITHRSAANDMGF1"] = CreatePssParams(hashAlgId9, 64);
|
||||
digestOids[PkcsObjectIdentifiers.Sha224WithRsaEncryption] = NistObjectIdentifiers.IdSha224;
|
||||
digestOids[PkcsObjectIdentifiers.Sha256WithRsaEncryption] = NistObjectIdentifiers.IdSha256;
|
||||
digestOids[PkcsObjectIdentifiers.Sha384WithRsaEncryption] = NistObjectIdentifiers.IdSha384;
|
||||
digestOids[PkcsObjectIdentifiers.Sha512WithRsaEncryption] = NistObjectIdentifiers.IdSha512;
|
||||
digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha224;
|
||||
digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha256;
|
||||
digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha384;
|
||||
digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha512;
|
||||
digestOids[NistObjectIdentifiers.IdDsaWithSha3_224] = NistObjectIdentifiers.IdSha3_224;
|
||||
digestOids[NistObjectIdentifiers.IdDsaWithSha3_256] = NistObjectIdentifiers.IdSha3_256;
|
||||
digestOids[NistObjectIdentifiers.IdDsaWithSha3_384] = NistObjectIdentifiers.IdSha3_384;
|
||||
digestOids[NistObjectIdentifiers.IdDsaWithSha3_512] = NistObjectIdentifiers.IdSha3_512;
|
||||
digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_224] = NistObjectIdentifiers.IdSha3_224;
|
||||
digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_256] = NistObjectIdentifiers.IdSha3_256;
|
||||
digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_384] = NistObjectIdentifiers.IdSha3_384;
|
||||
digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_512] = NistObjectIdentifiers.IdSha3_512;
|
||||
digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224] = NistObjectIdentifiers.IdSha3_224;
|
||||
digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256] = NistObjectIdentifiers.IdSha3_256;
|
||||
digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384] = NistObjectIdentifiers.IdSha3_384;
|
||||
digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512] = NistObjectIdentifiers.IdSha3_512;
|
||||
digestOids[PkcsObjectIdentifiers.MD2WithRsaEncryption] = PkcsObjectIdentifiers.MD2;
|
||||
digestOids[PkcsObjectIdentifiers.MD4WithRsaEncryption] = PkcsObjectIdentifiers.MD4;
|
||||
digestOids[PkcsObjectIdentifiers.MD5WithRsaEncryption] = PkcsObjectIdentifiers.MD5;
|
||||
digestOids[PkcsObjectIdentifiers.Sha1WithRsaEncryption] = OiwObjectIdentifiers.IdSha1;
|
||||
digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128] = TeleTrusTObjectIdentifiers.RipeMD128;
|
||||
digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160] = TeleTrusTObjectIdentifiers.RipeMD160;
|
||||
digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256] = TeleTrusTObjectIdentifiers.RipeMD256;
|
||||
digestOids[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94] = CryptoProObjectIdentifiers.GostR3411;
|
||||
digestOids[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001] = CryptoProObjectIdentifiers.GostR3411;
|
||||
digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256;
|
||||
digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512;
|
||||
digestOids[GMObjectIdentifiers.sm2sign_with_sm3] = GMObjectIdentifiers.sm3;
|
||||
}
|
||||
|
||||
private static AlgorithmIdentifier Generate(string signatureAlgorithm)
|
||||
{
|
||||
string text = Strings.ToUpperCase(signatureAlgorithm);
|
||||
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)algorithms[text];
|
||||
if (derObjectIdentifier == null)
|
||||
{
|
||||
throw new ArgumentException("Unknown signature type requested: " + text);
|
||||
}
|
||||
AlgorithmIdentifier algorithmIdentifier = (noParams.Contains(derObjectIdentifier) ? new AlgorithmIdentifier(derObjectIdentifier) : ((!_params.Contains(text)) ? new AlgorithmIdentifier(derObjectIdentifier, DerNull.Instance) : new AlgorithmIdentifier(derObjectIdentifier, (Asn1Encodable)_params[text])));
|
||||
if (pkcs15RsaEncryption.Contains(derObjectIdentifier))
|
||||
{
|
||||
new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance);
|
||||
}
|
||||
if (algorithmIdentifier.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
|
||||
{
|
||||
_ = ((RsassaPssParameters)algorithmIdentifier.Parameters).HashAlgorithm;
|
||||
}
|
||||
else
|
||||
{
|
||||
new AlgorithmIdentifier((DerObjectIdentifier)digestOids[derObjectIdentifier], DerNull.Instance);
|
||||
}
|
||||
return algorithmIdentifier;
|
||||
}
|
||||
|
||||
private static RsassaPssParameters CreatePssParams(AlgorithmIdentifier hashAlgId, int saltSize)
|
||||
{
|
||||
return new RsassaPssParameters(hashAlgId, new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), new DerInteger(saltSize), new DerInteger(1));
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier Find(string sigAlgName)
|
||||
{
|
||||
return Generate(sigAlgName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class DefaultSignedAttributeTableGenerator : CmsAttributeTableGenerator
|
||||
{
|
||||
private readonly IDictionary table;
|
||||
|
||||
public DefaultSignedAttributeTableGenerator()
|
||||
{
|
||||
table = Platform.CreateHashtable();
|
||||
}
|
||||
|
||||
public DefaultSignedAttributeTableGenerator(AttributeTable attributeTable)
|
||||
{
|
||||
if (attributeTable != null)
|
||||
{
|
||||
table = attributeTable.ToDictionary();
|
||||
}
|
||||
else
|
||||
{
|
||||
table = Platform.CreateHashtable();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Hashtable createStandardAttributeTable(IDictionary parameters)
|
||||
{
|
||||
Hashtable hashtable = new Hashtable(table);
|
||||
DoCreateStandardAttributeTable(parameters, hashtable);
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
private void DoCreateStandardAttributeTable(IDictionary parameters, IDictionary std)
|
||||
{
|
||||
if (parameters.Contains(CmsAttributeTableParameter.ContentType) && !std.Contains(CmsAttributes.ContentType))
|
||||
{
|
||||
DerObjectIdentifier obj = (DerObjectIdentifier)parameters[CmsAttributeTableParameter.ContentType];
|
||||
Org.BouncyCastle.Asn1.Cms.Attribute attribute = new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(obj));
|
||||
std[attribute.AttrType] = attribute;
|
||||
}
|
||||
if (!std.Contains(CmsAttributes.SigningTime))
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.Attribute attribute2 = new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new Time(DateTime.UtcNow)));
|
||||
std[attribute2.AttrType] = attribute2;
|
||||
}
|
||||
if (!std.Contains(CmsAttributes.MessageDigest))
|
||||
{
|
||||
byte[] str = (byte[])parameters[CmsAttributeTableParameter.Digest];
|
||||
Org.BouncyCastle.Asn1.Cms.Attribute attribute3 = new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(str)));
|
||||
std[attribute3.AttrType] = attribute3;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual AttributeTable GetAttributes(IDictionary parameters)
|
||||
{
|
||||
IDictionary attrs = createStandardAttributeTable(parameters);
|
||||
return new AttributeTable(attrs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class EnvelopedDataHelper
|
||||
{
|
||||
private static readonly IDictionary BaseCipherNames;
|
||||
|
||||
private static readonly IDictionary MacAlgNames;
|
||||
|
||||
static EnvelopedDataHelper()
|
||||
{
|
||||
BaseCipherNames = Platform.CreateHashtable();
|
||||
MacAlgNames = Platform.CreateHashtable();
|
||||
BaseCipherNames.Add(PkcsObjectIdentifiers.DesEde3Cbc, "DESEDE");
|
||||
BaseCipherNames.Add(NistObjectIdentifiers.IdAes128Cbc, "AES");
|
||||
BaseCipherNames.Add(NistObjectIdentifiers.IdAes192Cbc, "AES");
|
||||
BaseCipherNames.Add(NistObjectIdentifiers.IdAes256Cbc, "AES");
|
||||
MacAlgNames.Add(PkcsObjectIdentifiers.DesEde3Cbc, "DESEDEMac");
|
||||
MacAlgNames.Add(NistObjectIdentifiers.IdAes128Cbc, "AESMac");
|
||||
MacAlgNames.Add(NistObjectIdentifiers.IdAes192Cbc, "AESMac");
|
||||
MacAlgNames.Add(NistObjectIdentifiers.IdAes256Cbc, "AESMac");
|
||||
MacAlgNames.Add(PkcsObjectIdentifiers.RC2Cbc, "RC2Mac");
|
||||
}
|
||||
|
||||
public static object CreateContentCipher(bool forEncryption, ICipherParameters encKey, AlgorithmIdentifier encryptionAlgID)
|
||||
{
|
||||
return CipherFactory.CreateContentCipher(forEncryption, encKey, encryptionAlgID);
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier GenerateEncryptionAlgID(DerObjectIdentifier encryptionOID, KeyParameter encKey, SecureRandom random)
|
||||
{
|
||||
return AlgorithmIdentifierFactory.GenerateEncryptionAlgID(encryptionOID, encKey.GetKey().Length * 8, random);
|
||||
}
|
||||
|
||||
public CipherKeyGenerator CreateKeyGenerator(DerObjectIdentifier algorithm, SecureRandom random)
|
||||
{
|
||||
return CipherKeyGeneratorFactory.CreateKeyGenerator(algorithm, random);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal interface IDigestCalculator
|
||||
{
|
||||
byte[] GetDigest();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal interface ISignerInfoGenerator
|
||||
{
|
||||
SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, byte[] calculatedDigest);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Kisa;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Asn1.Ntt;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class KekRecipientInfoGenerator : RecipientInfoGenerator
|
||||
{
|
||||
private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
|
||||
|
||||
private KeyParameter keyEncryptionKey;
|
||||
|
||||
private string keyEncryptionKeyOID;
|
||||
|
||||
private KekIdentifier kekIdentifier;
|
||||
|
||||
private AlgorithmIdentifier keyEncryptionAlgorithm;
|
||||
|
||||
internal KekIdentifier KekIdentifier
|
||||
{
|
||||
set
|
||||
{
|
||||
kekIdentifier = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal KeyParameter KeyEncryptionKey
|
||||
{
|
||||
set
|
||||
{
|
||||
keyEncryptionKey = value;
|
||||
keyEncryptionAlgorithm = DetermineKeyEncAlg(keyEncryptionKeyOID, keyEncryptionKey);
|
||||
}
|
||||
}
|
||||
|
||||
internal string KeyEncryptionKeyOID
|
||||
{
|
||||
set
|
||||
{
|
||||
keyEncryptionKeyOID = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal KekRecipientInfoGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
|
||||
{
|
||||
byte[] key = contentEncryptionKey.GetKey();
|
||||
IWrapper wrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.Algorithm.Id);
|
||||
wrapper.Init(forWrapping: true, new ParametersWithRandom(keyEncryptionKey, random));
|
||||
Asn1OctetString encryptedKey = new DerOctetString(wrapper.Wrap(key, 0, key.Length));
|
||||
return new RecipientInfo(new KekRecipientInfo(kekIdentifier, keyEncryptionAlgorithm, encryptedKey));
|
||||
}
|
||||
|
||||
private static AlgorithmIdentifier DetermineKeyEncAlg(string algorithm, KeyParameter key)
|
||||
{
|
||||
if (Platform.StartsWith(algorithm, "DES"))
|
||||
{
|
||||
return new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgCms3DesWrap, DerNull.Instance);
|
||||
}
|
||||
if (Platform.StartsWith(algorithm, "RC2"))
|
||||
{
|
||||
return new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgCmsRC2Wrap, new DerInteger(58));
|
||||
}
|
||||
if (Platform.StartsWith(algorithm, "AES"))
|
||||
{
|
||||
return new AlgorithmIdentifier((key.GetKey().Length * 8) switch
|
||||
{
|
||||
128 => NistObjectIdentifiers.IdAes128Wrap,
|
||||
192 => NistObjectIdentifiers.IdAes192Wrap,
|
||||
256 => NistObjectIdentifiers.IdAes256Wrap,
|
||||
_ => throw new ArgumentException("illegal keysize in AES"),
|
||||
});
|
||||
}
|
||||
if (Platform.StartsWith(algorithm, "SEED"))
|
||||
{
|
||||
return new AlgorithmIdentifier(KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap);
|
||||
}
|
||||
if (Platform.StartsWith(algorithm, "CAMELLIA"))
|
||||
{
|
||||
return new AlgorithmIdentifier((key.GetKey().Length * 8) switch
|
||||
{
|
||||
128 => NttObjectIdentifiers.IdCamellia128Wrap,
|
||||
192 => NttObjectIdentifiers.IdCamellia192Wrap,
|
||||
256 => NttObjectIdentifiers.IdCamellia256Wrap,
|
||||
_ => throw new ArgumentException("illegal keysize in Camellia"),
|
||||
});
|
||||
}
|
||||
throw new ArgumentException("unknown algorithm");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class KekRecipientInformation : RecipientInformation
|
||||
{
|
||||
private KekRecipientInfo info;
|
||||
|
||||
internal KekRecipientInformation(KekRecipientInfo info, CmsSecureReadable secureReadable)
|
||||
: base(info.KeyEncryptionAlgorithm, secureReadable)
|
||||
{
|
||||
this.info = info;
|
||||
rid = new RecipientID();
|
||||
KekIdentifier kekID = info.KekID;
|
||||
rid.KeyIdentifier = kekID.KeyIdentifier.GetOctets();
|
||||
}
|
||||
|
||||
public override CmsTypedStream GetContentStream(ICipherParameters key)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] octets = info.EncryptedKey.GetOctets();
|
||||
IWrapper wrapper = WrapperUtilities.GetWrapper(keyEncAlg.Algorithm.Id);
|
||||
wrapper.Init(forWrapping: false, key);
|
||||
KeyParameter sKey = ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), wrapper.Unwrap(octets, 0, octets.Length));
|
||||
return GetContentFromSessionKey(sKey);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Cms.Ecc;
|
||||
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.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class KeyAgreeRecipientInfoGenerator : RecipientInfoGenerator
|
||||
{
|
||||
private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
|
||||
|
||||
private DerObjectIdentifier keyAgreementOID;
|
||||
|
||||
private DerObjectIdentifier keyEncryptionOID;
|
||||
|
||||
private IList recipientCerts;
|
||||
|
||||
private AsymmetricCipherKeyPair senderKeyPair;
|
||||
|
||||
internal DerObjectIdentifier KeyAgreementOID
|
||||
{
|
||||
set
|
||||
{
|
||||
keyAgreementOID = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal DerObjectIdentifier KeyEncryptionOID
|
||||
{
|
||||
set
|
||||
{
|
||||
keyEncryptionOID = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal ICollection RecipientCerts
|
||||
{
|
||||
set
|
||||
{
|
||||
recipientCerts = Platform.CreateArrayList(value);
|
||||
}
|
||||
}
|
||||
|
||||
internal AsymmetricCipherKeyPair SenderKeyPair
|
||||
{
|
||||
set
|
||||
{
|
||||
senderKeyPair = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal KeyAgreeRecipientInfoGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
|
||||
{
|
||||
byte[] key = contentEncryptionKey.GetKey();
|
||||
AsymmetricKeyParameter asymmetricKeyParameter = senderKeyPair.Public;
|
||||
ICipherParameters cipherParameters = senderKeyPair.Private;
|
||||
OriginatorIdentifierOrKey originator;
|
||||
try
|
||||
{
|
||||
originator = new OriginatorIdentifierOrKey(CreateOriginatorPublicKey(asymmetricKeyParameter));
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new InvalidKeyException("cannot extract originator public key: " + ex);
|
||||
}
|
||||
Asn1OctetString ukm = null;
|
||||
if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
try
|
||||
{
|
||||
IAsymmetricCipherKeyPairGenerator keyPairGenerator = GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID);
|
||||
keyPairGenerator.Init(((ECPublicKeyParameters)asymmetricKeyParameter).CreateKeyGenerationParameters(random));
|
||||
AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.GenerateKeyPair();
|
||||
ukm = new DerOctetString(new MQVuserKeyingMaterial(CreateOriginatorPublicKey(asymmetricCipherKeyPair.Public), null));
|
||||
cipherParameters = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters, (ECPrivateKeyParameters)asymmetricCipherKeyPair.Private, (ECPublicKeyParameters)asymmetricCipherKeyPair.Public);
|
||||
}
|
||||
catch (IOException ex2)
|
||||
{
|
||||
throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + ex2);
|
||||
}
|
||||
catch (SecurityUtilityException ex3)
|
||||
{
|
||||
throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + ex3);
|
||||
}
|
||||
}
|
||||
DerSequence parameters = new DerSequence(keyEncryptionOID, DerNull.Instance);
|
||||
AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(keyAgreementOID, parameters);
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (X509Certificate recipientCert in recipientCerts)
|
||||
{
|
||||
TbsCertificateStructure instance;
|
||||
try
|
||||
{
|
||||
instance = TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(recipientCert.GetTbsCertificate()));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ArgumentException("can't extract TBS structure from certificate");
|
||||
}
|
||||
IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(instance.Issuer, instance.SerialNumber.Value);
|
||||
KeyAgreeRecipientIdentifier id = new KeyAgreeRecipientIdentifier(issuerSerial);
|
||||
ICipherParameters cipherParameters2 = recipientCert.GetPublicKey();
|
||||
if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
cipherParameters2 = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters2, (ECPublicKeyParameters)cipherParameters2);
|
||||
}
|
||||
IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(keyAgreementOID, keyEncryptionOID.Id);
|
||||
basicAgreementWithKdf.Init(new ParametersWithRandom(cipherParameters, random));
|
||||
BigInteger s = basicAgreementWithKdf.CalculateAgreement(cipherParameters2);
|
||||
int qLength = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8;
|
||||
byte[] keyBytes = X9IntegerConverter.IntegerToBytes(s, qLength);
|
||||
KeyParameter parameters2 = ParameterUtilities.CreateKeyParameter(keyEncryptionOID, keyBytes);
|
||||
IWrapper wrapper = Helper.CreateWrapper(keyEncryptionOID.Id);
|
||||
wrapper.Init(forWrapping: true, new ParametersWithRandom(parameters2, random));
|
||||
byte[] str = wrapper.Wrap(key, 0, key.Length);
|
||||
Asn1OctetString encryptedKey = new DerOctetString(str);
|
||||
asn1EncodableVector.Add(new RecipientEncryptedKey(id, encryptedKey));
|
||||
}
|
||||
return new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncryptionAlgorithm, new DerSequence(asn1EncodableVector)));
|
||||
}
|
||||
|
||||
private static OriginatorPublicKey CreateOriginatorPublicKey(AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
|
||||
return new OriginatorPublicKey(new AlgorithmIdentifier(subjectPublicKeyInfo.AlgorithmID.Algorithm, DerNull.Instance), subjectPublicKeyInfo.PublicKeyData.GetBytes());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Cms.Ecc;
|
||||
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;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class KeyAgreeRecipientInformation : RecipientInformation
|
||||
{
|
||||
private KeyAgreeRecipientInfo info;
|
||||
|
||||
private Asn1OctetString encryptedKey;
|
||||
|
||||
internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info, CmsSecureReadable secureReadable)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Asn1Encodable recipientEncryptedKey in info.RecipientEncryptedKeys)
|
||||
{
|
||||
RecipientEncryptedKey instance = RecipientEncryptedKey.GetInstance(recipientEncryptedKey.ToAsn1Object());
|
||||
RecipientID recipientID = new RecipientID();
|
||||
KeyAgreeRecipientIdentifier identifier = instance.Identifier;
|
||||
Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber issuerAndSerialNumber = identifier.IssuerAndSerialNumber;
|
||||
if (issuerAndSerialNumber != null)
|
||||
{
|
||||
recipientID.Issuer = issuerAndSerialNumber.Name;
|
||||
recipientID.SerialNumber = issuerAndSerialNumber.SerialNumber.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
RecipientKeyIdentifier rKeyID = identifier.RKeyID;
|
||||
recipientID.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets();
|
||||
}
|
||||
infos.Add(new KeyAgreeRecipientInformation(info, recipientID, instance.EncryptedKey, secureReadable));
|
||||
}
|
||||
}
|
||||
catch (IOException innerException)
|
||||
{
|
||||
throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", innerException);
|
||||
}
|
||||
}
|
||||
|
||||
internal KeyAgreeRecipientInformation(KeyAgreeRecipientInfo info, RecipientID rid, Asn1OctetString encryptedKey, CmsSecureReadable secureReadable)
|
||||
: base(info.KeyEncryptionAlgorithm, secureReadable)
|
||||
{
|
||||
this.info = info;
|
||||
base.rid = rid;
|
||||
this.encryptedKey = encryptedKey;
|
||||
}
|
||||
|
||||
private AsymmetricKeyParameter GetSenderPublicKey(AsymmetricKeyParameter receiverPrivateKey, OriginatorIdentifierOrKey originator)
|
||||
{
|
||||
OriginatorPublicKey originatorPublicKey = originator.OriginatorPublicKey;
|
||||
if (originatorPublicKey != null)
|
||||
{
|
||||
return GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, originatorPublicKey);
|
||||
}
|
||||
OriginatorID originatorID = new OriginatorID();
|
||||
Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber issuerAndSerialNumber = originator.IssuerAndSerialNumber;
|
||||
if (issuerAndSerialNumber != null)
|
||||
{
|
||||
originatorID.Issuer = issuerAndSerialNumber.Name;
|
||||
originatorID.SerialNumber = issuerAndSerialNumber.SerialNumber.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
SubjectKeyIdentifier subjectKeyIdentifier = originator.SubjectKeyIdentifier;
|
||||
originatorID.SubjectKeyIdentifier = subjectKeyIdentifier.GetKeyIdentifier();
|
||||
}
|
||||
return GetPublicKeyFromOriginatorID(originatorID);
|
||||
}
|
||||
|
||||
private AsymmetricKeyParameter GetPublicKeyFromOriginatorPublicKey(AsymmetricKeyParameter receiverPrivateKey, OriginatorPublicKey originatorPublicKey)
|
||||
{
|
||||
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(receiverPrivateKey);
|
||||
SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo(privateKeyInfo.PrivateKeyAlgorithm, originatorPublicKey.PublicKey.GetBytes());
|
||||
return PublicKeyFactory.CreateKey(keyInfo);
|
||||
}
|
||||
|
||||
private AsymmetricKeyParameter GetPublicKeyFromOriginatorID(OriginatorID origID)
|
||||
{
|
||||
throw new CmsException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier");
|
||||
}
|
||||
|
||||
private KeyParameter CalculateAgreedWrapKey(string wrapAlg, AsymmetricKeyParameter senderPublicKey, AsymmetricKeyParameter receiverPrivateKey)
|
||||
{
|
||||
DerObjectIdentifier algorithm = keyEncAlg.Algorithm;
|
||||
ICipherParameters cipherParameters = senderPublicKey;
|
||||
ICipherParameters cipherParameters2 = receiverPrivateKey;
|
||||
if (algorithm.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
byte[] octets = info.UserKeyingMaterial.GetOctets();
|
||||
MQVuserKeyingMaterial instance = MQVuserKeyingMaterial.GetInstance(Asn1Object.FromByteArray(octets));
|
||||
AsymmetricKeyParameter publicKeyFromOriginatorPublicKey = GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, instance.EphemeralPublicKey);
|
||||
cipherParameters = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters, (ECPublicKeyParameters)publicKeyFromOriginatorPublicKey);
|
||||
cipherParameters2 = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters2, (ECPrivateKeyParameters)cipherParameters2);
|
||||
}
|
||||
IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(algorithm, wrapAlg);
|
||||
basicAgreementWithKdf.Init(cipherParameters2);
|
||||
BigInteger s = basicAgreementWithKdf.CalculateAgreement(cipherParameters);
|
||||
int qLength = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;
|
||||
byte[] keyBytes = X9IntegerConverter.IntegerToBytes(s, qLength);
|
||||
return ParameterUtilities.CreateKeyParameter(wrapAlg, keyBytes);
|
||||
}
|
||||
|
||||
private KeyParameter UnwrapSessionKey(string wrapAlg, KeyParameter agreedKey)
|
||||
{
|
||||
byte[] octets = encryptedKey.GetOctets();
|
||||
IWrapper wrapper = WrapperUtilities.GetWrapper(wrapAlg);
|
||||
wrapper.Init(forWrapping: false, agreedKey);
|
||||
byte[] keyBytes = wrapper.Unwrap(octets, 0, octets.Length);
|
||||
return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), keyBytes);
|
||||
}
|
||||
|
||||
internal KeyParameter GetSessionKey(AsymmetricKeyParameter receiverPrivateKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
string id = DerObjectIdentifier.GetInstance(Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id;
|
||||
AsymmetricKeyParameter senderPublicKey = GetSenderPublicKey(receiverPrivateKey, info.Originator);
|
||||
KeyParameter agreedKey = CalculateAgreedWrapKey(id, senderPublicKey, receiverPrivateKey);
|
||||
return UnwrapSessionKey(id, agreedKey);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (Exception e3)
|
||||
{
|
||||
throw new CmsException("originator key invalid.", e3);
|
||||
}
|
||||
}
|
||||
|
||||
public override CmsTypedStream GetContentStream(ICipherParameters key)
|
||||
{
|
||||
if (!(key is AsymmetricKeyParameter))
|
||||
{
|
||||
throw new ArgumentException("KeyAgreement requires asymmetric key", "key");
|
||||
}
|
||||
AsymmetricKeyParameter asymmetricKeyParameter = (AsymmetricKeyParameter)key;
|
||||
if (!asymmetricKeyParameter.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected private key", "key");
|
||||
}
|
||||
KeyParameter sessionKey = GetSessionKey(asymmetricKeyParameter);
|
||||
return GetContentFromSessionKey(sessionKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class KeyTransRecipientInfoGenerator : RecipientInfoGenerator
|
||||
{
|
||||
private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
|
||||
|
||||
private TbsCertificateStructure recipientTbsCert;
|
||||
|
||||
private AsymmetricKeyParameter recipientPublicKey;
|
||||
|
||||
private Asn1OctetString subjectKeyIdentifier;
|
||||
|
||||
private SubjectPublicKeyInfo info;
|
||||
|
||||
private IssuerAndSerialNumber issuerAndSerialNumber;
|
||||
|
||||
private SecureRandom random;
|
||||
|
||||
internal X509Certificate RecipientCert
|
||||
{
|
||||
set
|
||||
{
|
||||
recipientTbsCert = CmsUtilities.GetTbsCertificateStructure(value);
|
||||
recipientPublicKey = value.GetPublicKey();
|
||||
info = recipientTbsCert.SubjectPublicKeyInfo;
|
||||
}
|
||||
}
|
||||
|
||||
internal AsymmetricKeyParameter RecipientPublicKey
|
||||
{
|
||||
set
|
||||
{
|
||||
recipientPublicKey = value;
|
||||
try
|
||||
{
|
||||
info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(recipientPublicKey);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
throw new ArgumentException("can't extract key algorithm from this key");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal Asn1OctetString SubjectKeyIdentifier
|
||||
{
|
||||
set
|
||||
{
|
||||
subjectKeyIdentifier = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual AlgorithmIdentifier AlgorithmDetails => info.AlgorithmID;
|
||||
|
||||
internal KeyTransRecipientInfoGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
protected KeyTransRecipientInfoGenerator(IssuerAndSerialNumber issuerAndSerialNumber)
|
||||
{
|
||||
this.issuerAndSerialNumber = issuerAndSerialNumber;
|
||||
}
|
||||
|
||||
protected KeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier)
|
||||
{
|
||||
this.subjectKeyIdentifier = new DerOctetString(subjectKeyIdentifier);
|
||||
}
|
||||
|
||||
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
|
||||
{
|
||||
AlgorithmIdentifier algorithmDetails = AlgorithmDetails;
|
||||
this.random = random;
|
||||
byte[] str = GenerateWrappedKey(contentEncryptionKey);
|
||||
RecipientIdentifier rid;
|
||||
if (recipientTbsCert != null)
|
||||
{
|
||||
IssuerAndSerialNumber id = new IssuerAndSerialNumber(recipientTbsCert.Issuer, recipientTbsCert.SerialNumber.Value);
|
||||
rid = new RecipientIdentifier(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
rid = new RecipientIdentifier(subjectKeyIdentifier);
|
||||
}
|
||||
return new RecipientInfo(new KeyTransRecipientInfo(rid, algorithmDetails, new DerOctetString(str)));
|
||||
}
|
||||
|
||||
protected virtual byte[] GenerateWrappedKey(KeyParameter contentEncryptionKey)
|
||||
{
|
||||
byte[] key = contentEncryptionKey.GetKey();
|
||||
AlgorithmIdentifier algorithmID = info.AlgorithmID;
|
||||
IWrapper wrapper = Helper.CreateWrapper(algorithmID.Algorithm.Id);
|
||||
wrapper.Init(forWrapping: true, new ParametersWithRandom(recipientPublicKey, random));
|
||||
return wrapper.Wrap(key, 0, key.Length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class KeyTransRecipientInformation : RecipientInformation
|
||||
{
|
||||
private KeyTransRecipientInfo info;
|
||||
|
||||
internal KeyTransRecipientInformation(KeyTransRecipientInfo info, CmsSecureReadable secureReadable)
|
||||
: base(info.KeyEncryptionAlgorithm, secureReadable)
|
||||
{
|
||||
this.info = info;
|
||||
rid = new RecipientID();
|
||||
RecipientIdentifier recipientIdentifier = info.RecipientIdentifier;
|
||||
try
|
||||
{
|
||||
if (recipientIdentifier.IsTagged)
|
||||
{
|
||||
Asn1OctetString instance = Asn1OctetString.GetInstance(recipientIdentifier.ID);
|
||||
rid.SubjectKeyIdentifier = instance.GetOctets();
|
||||
}
|
||||
else
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber instance2 = Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber.GetInstance(recipientIdentifier.ID);
|
||||
rid.Issuer = instance2.Name;
|
||||
rid.SerialNumber = instance2.SerialNumber.Value;
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
throw new ArgumentException("invalid rid in KeyTransRecipientInformation");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetExchangeEncryptionAlgorithmName(AlgorithmIdentifier algo)
|
||||
{
|
||||
DerObjectIdentifier algorithm = algo.Algorithm;
|
||||
if (PkcsObjectIdentifiers.RsaEncryption.Equals(algorithm))
|
||||
{
|
||||
return "RSA//PKCS1Padding";
|
||||
}
|
||||
if (PkcsObjectIdentifiers.IdRsaesOaep.Equals(algorithm))
|
||||
{
|
||||
RsaesOaepParameters instance = RsaesOaepParameters.GetInstance(algo.Parameters);
|
||||
return "RSA//OAEPWITH" + DigestUtilities.GetAlgorithmName(instance.HashAlgorithm.Algorithm) + "ANDMGF1Padding";
|
||||
}
|
||||
return algorithm.Id;
|
||||
}
|
||||
|
||||
internal KeyParameter UnwrapKey(ICipherParameters key)
|
||||
{
|
||||
byte[] octets = info.EncryptedKey.GetOctets();
|
||||
string exchangeEncryptionAlgorithmName = GetExchangeEncryptionAlgorithmName(keyEncAlg);
|
||||
try
|
||||
{
|
||||
IWrapper wrapper = WrapperUtilities.GetWrapper(exchangeEncryptionAlgorithmName);
|
||||
wrapper.Init(forWrapping: false, key);
|
||||
return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), wrapper.Unwrap(octets, 0, octets.Length));
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (DataLengthException e3)
|
||||
{
|
||||
throw new CmsException("illegal blocksize in message.", e3);
|
||||
}
|
||||
catch (InvalidCipherTextException e4)
|
||||
{
|
||||
throw new CmsException("bad padding in message.", e4);
|
||||
}
|
||||
}
|
||||
|
||||
public override CmsTypedStream GetContentStream(ICipherParameters key)
|
||||
{
|
||||
KeyParameter sKey = UnwrapKey(key);
|
||||
return GetContentFromSessionKey(sKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class OriginatorID : X509CertStoreSelector
|
||||
{
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int num = Arrays.GetHashCode(base.SubjectKeyIdentifier);
|
||||
BigInteger bigInteger = base.SerialNumber;
|
||||
if (bigInteger != null)
|
||||
{
|
||||
num ^= bigInteger.GetHashCode();
|
||||
}
|
||||
X509Name x509Name = base.Issuer;
|
||||
if (x509Name != null)
|
||||
{
|
||||
num ^= x509Name.GetHashCode();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(obj is OriginatorID originatorID))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Arrays.AreEqual(base.SubjectKeyIdentifier, originatorID.SubjectKeyIdentifier) && object.Equals(base.SerialNumber, originatorID.SerialNumber))
|
||||
{
|
||||
return X509CertStoreSelector.IssuersMatch(base.Issuer, originatorID.Issuer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class OriginatorInfoGenerator
|
||||
{
|
||||
private readonly IList origCerts;
|
||||
|
||||
private readonly IList origCrls;
|
||||
|
||||
public OriginatorInfoGenerator(X509Certificate origCert)
|
||||
{
|
||||
origCerts = Platform.CreateArrayList(1);
|
||||
origCrls = null;
|
||||
origCerts.Add(origCert.CertificateStructure);
|
||||
}
|
||||
|
||||
public OriginatorInfoGenerator(IX509Store origCerts)
|
||||
: this(origCerts, null)
|
||||
{
|
||||
}
|
||||
|
||||
public OriginatorInfoGenerator(IX509Store origCerts, IX509Store origCrls)
|
||||
{
|
||||
this.origCerts = CmsUtilities.GetCertificatesFromStore(origCerts);
|
||||
this.origCrls = ((origCrls == null) ? null : CmsUtilities.GetCrlsFromStore(origCrls));
|
||||
}
|
||||
|
||||
public virtual OriginatorInfo Generate()
|
||||
{
|
||||
Asn1Set certs = CmsUtilities.CreateDerSetFromList(origCerts);
|
||||
Asn1Set crls = ((origCrls == null) ? null : CmsUtilities.CreateDerSetFromList(origCrls));
|
||||
return new OriginatorInfo(certs, crls);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class OriginatorInformation
|
||||
{
|
||||
private readonly OriginatorInfo originatorInfo;
|
||||
|
||||
internal OriginatorInformation(OriginatorInfo originatorInfo)
|
||||
{
|
||||
this.originatorInfo = originatorInfo;
|
||||
}
|
||||
|
||||
public virtual IX509Store GetCertificates()
|
||||
{
|
||||
Asn1Set certificates = originatorInfo.Certificates;
|
||||
if (certificates != null)
|
||||
{
|
||||
IList list = Platform.CreateArrayList(certificates.Count);
|
||||
foreach (Asn1Encodable item in certificates)
|
||||
{
|
||||
Asn1Object asn1Object = item.ToAsn1Object();
|
||||
if (asn1Object is Asn1Sequence)
|
||||
{
|
||||
list.Add(new X509Certificate(X509CertificateStructure.GetInstance(asn1Object)));
|
||||
}
|
||||
}
|
||||
return X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(list));
|
||||
}
|
||||
return X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(Platform.CreateArrayList()));
|
||||
}
|
||||
|
||||
public virtual IX509Store GetCrls()
|
||||
{
|
||||
Asn1Set certificates = originatorInfo.Certificates;
|
||||
if (certificates != null)
|
||||
{
|
||||
IList list = Platform.CreateArrayList(certificates.Count);
|
||||
foreach (Asn1Encodable item in certificates)
|
||||
{
|
||||
Asn1Object asn1Object = item.ToAsn1Object();
|
||||
if (asn1Object is Asn1Sequence)
|
||||
{
|
||||
list.Add(new X509Crl(CertificateList.GetInstance(asn1Object)));
|
||||
}
|
||||
}
|
||||
return X509StoreFactory.Create("CRL/Collection", new X509CollectionStoreParameters(list));
|
||||
}
|
||||
return X509StoreFactory.Create("CRL/Collection", new X509CollectionStoreParameters(Platform.CreateArrayList()));
|
||||
}
|
||||
|
||||
public virtual OriginatorInfo ToAsn1Structure()
|
||||
{
|
||||
return originatorInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class PasswordRecipientInfoGenerator : RecipientInfoGenerator
|
||||
{
|
||||
private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
|
||||
|
||||
private AlgorithmIdentifier keyDerivationAlgorithm;
|
||||
|
||||
private KeyParameter keyEncryptionKey;
|
||||
|
||||
private string keyEncryptionKeyOID;
|
||||
|
||||
internal AlgorithmIdentifier KeyDerivationAlgorithm
|
||||
{
|
||||
set
|
||||
{
|
||||
keyDerivationAlgorithm = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal KeyParameter KeyEncryptionKey
|
||||
{
|
||||
set
|
||||
{
|
||||
keyEncryptionKey = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string KeyEncryptionKeyOID
|
||||
{
|
||||
set
|
||||
{
|
||||
keyEncryptionKeyOID = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal PasswordRecipientInfoGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
|
||||
{
|
||||
byte[] key = contentEncryptionKey.GetKey();
|
||||
string rfc3211WrapperName = Helper.GetRfc3211WrapperName(keyEncryptionKeyOID);
|
||||
IWrapper wrapper = Helper.CreateWrapper(rfc3211WrapperName);
|
||||
int num = (Platform.StartsWith(rfc3211WrapperName, "DESEDE") ? 8 : 16);
|
||||
byte[] array = new byte[num];
|
||||
random.NextBytes(array);
|
||||
ICipherParameters parameters = new ParametersWithIV(keyEncryptionKey, array);
|
||||
wrapper.Init(forWrapping: true, new ParametersWithRandom(parameters, random));
|
||||
Asn1OctetString encryptedKey = new DerOctetString(wrapper.Wrap(key, 0, key.Length));
|
||||
DerSequence parameters2 = new DerSequence(new DerObjectIdentifier(keyEncryptionKeyOID), new DerOctetString(array));
|
||||
AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgPwriKek, parameters2);
|
||||
return new RecipientInfo(new PasswordRecipientInfo(keyDerivationAlgorithm, keyEncryptionAlgorithm, encryptedKey));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class PasswordRecipientInformation : RecipientInformation
|
||||
{
|
||||
private readonly PasswordRecipientInfo info;
|
||||
|
||||
public virtual AlgorithmIdentifier KeyDerivationAlgorithm => info.KeyDerivationAlgorithm;
|
||||
|
||||
internal PasswordRecipientInformation(PasswordRecipientInfo info, CmsSecureReadable secureReadable)
|
||||
: base(info.KeyEncryptionAlgorithm, secureReadable)
|
||||
{
|
||||
this.info = info;
|
||||
rid = new RecipientID();
|
||||
}
|
||||
|
||||
public override CmsTypedStream GetContentStream(ICipherParameters key)
|
||||
{
|
||||
try
|
||||
{
|
||||
AlgorithmIdentifier instance = AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm);
|
||||
Asn1Sequence asn1Sequence = (Asn1Sequence)instance.Parameters;
|
||||
byte[] octets = info.EncryptedKey.GetOctets();
|
||||
string id = DerObjectIdentifier.GetInstance(asn1Sequence[0]).Id;
|
||||
string rfc3211WrapperName = CmsEnvelopedHelper.Instance.GetRfc3211WrapperName(id);
|
||||
IWrapper wrapper = WrapperUtilities.GetWrapper(rfc3211WrapperName);
|
||||
byte[] octets2 = Asn1OctetString.GetInstance(asn1Sequence[1]).GetOctets();
|
||||
ICipherParameters encoded = ((CmsPbeKey)key).GetEncoded(id);
|
||||
encoded = new ParametersWithIV(encoded, octets2);
|
||||
wrapper.Init(forWrapping: false, encoded);
|
||||
KeyParameter sKey = ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), wrapper.Unwrap(octets, 0, octets.Length));
|
||||
return GetContentFromSessionKey(sKey);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Generators;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class Pkcs5Scheme2PbeKey : CmsPbeKey
|
||||
{
|
||||
[Obsolete("Use version taking 'char[]' instead")]
|
||||
public Pkcs5Scheme2PbeKey(string password, byte[] salt, int iterationCount)
|
||||
: this(password.ToCharArray(), salt, iterationCount)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use version taking 'char[]' instead")]
|
||||
public Pkcs5Scheme2PbeKey(string password, AlgorithmIdentifier keyDerivationAlgorithm)
|
||||
: this(password.ToCharArray(), keyDerivationAlgorithm)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs5Scheme2PbeKey(char[] password, byte[] salt, int iterationCount)
|
||||
: base(password, salt, iterationCount)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs5Scheme2PbeKey(char[] password, AlgorithmIdentifier keyDerivationAlgorithm)
|
||||
: base(password, keyDerivationAlgorithm)
|
||||
{
|
||||
}
|
||||
|
||||
internal override KeyParameter GetEncoded(string algorithmOid)
|
||||
{
|
||||
Pkcs5S2ParametersGenerator pkcs5S2ParametersGenerator = new Pkcs5S2ParametersGenerator();
|
||||
pkcs5S2ParametersGenerator.Init(PbeParametersGenerator.Pkcs5PasswordToBytes(password), salt, iterationCount);
|
||||
return (KeyParameter)pkcs5S2ParametersGenerator.GenerateDerivedParameters(algorithmOid, CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Generators;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class Pkcs5Scheme2Utf8PbeKey : CmsPbeKey
|
||||
{
|
||||
[Obsolete("Use version taking 'char[]' instead")]
|
||||
public Pkcs5Scheme2Utf8PbeKey(string password, byte[] salt, int iterationCount)
|
||||
: this(password.ToCharArray(), salt, iterationCount)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use version taking 'char[]' instead")]
|
||||
public Pkcs5Scheme2Utf8PbeKey(string password, AlgorithmIdentifier keyDerivationAlgorithm)
|
||||
: this(password.ToCharArray(), keyDerivationAlgorithm)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs5Scheme2Utf8PbeKey(char[] password, byte[] salt, int iterationCount)
|
||||
: base(password, salt, iterationCount)
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs5Scheme2Utf8PbeKey(char[] password, AlgorithmIdentifier keyDerivationAlgorithm)
|
||||
: base(password, keyDerivationAlgorithm)
|
||||
{
|
||||
}
|
||||
|
||||
internal override KeyParameter GetEncoded(string algorithmOid)
|
||||
{
|
||||
Pkcs5S2ParametersGenerator pkcs5S2ParametersGenerator = new Pkcs5S2ParametersGenerator();
|
||||
pkcs5S2ParametersGenerator.Init(PbeParametersGenerator.Pkcs5PasswordToUtf8Bytes(password), salt, iterationCount);
|
||||
return (KeyParameter)pkcs5S2ParametersGenerator.GenerateDerivedParameters(algorithmOid, CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class RecipientID : X509CertStoreSelector
|
||||
{
|
||||
private byte[] keyIdentifier;
|
||||
|
||||
public byte[] KeyIdentifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return Arrays.Clone(keyIdentifier);
|
||||
}
|
||||
set
|
||||
{
|
||||
keyIdentifier = Arrays.Clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int num = Arrays.GetHashCode(keyIdentifier) ^ Arrays.GetHashCode(base.SubjectKeyIdentifier);
|
||||
BigInteger bigInteger = base.SerialNumber;
|
||||
if (bigInteger != null)
|
||||
{
|
||||
num ^= bigInteger.GetHashCode();
|
||||
}
|
||||
X509Name x509Name = base.Issuer;
|
||||
if (x509Name != null)
|
||||
{
|
||||
num ^= x509Name.GetHashCode();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is RecipientID recipientID))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Arrays.AreEqual(keyIdentifier, recipientID.keyIdentifier) && Arrays.AreEqual(base.SubjectKeyIdentifier, recipientID.SubjectKeyIdentifier) && object.Equals(base.SerialNumber, recipientID.SerialNumber))
|
||||
{
|
||||
return X509CertStoreSelector.IssuersMatch(base.Issuer, recipientID.Issuer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public interface RecipientInfoGenerator
|
||||
{
|
||||
RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public abstract class RecipientInformation
|
||||
{
|
||||
internal RecipientID rid = new RecipientID();
|
||||
|
||||
internal AlgorithmIdentifier keyEncAlg;
|
||||
|
||||
internal CmsSecureReadable secureReadable;
|
||||
|
||||
private byte[] resultMac;
|
||||
|
||||
public RecipientID RecipientID => rid;
|
||||
|
||||
public AlgorithmIdentifier KeyEncryptionAlgorithmID => keyEncAlg;
|
||||
|
||||
public string KeyEncryptionAlgOid => keyEncAlg.Algorithm.Id;
|
||||
|
||||
public Asn1Object KeyEncryptionAlgParams => keyEncAlg.Parameters?.ToAsn1Object();
|
||||
|
||||
internal RecipientInformation(AlgorithmIdentifier keyEncAlg, CmsSecureReadable secureReadable)
|
||||
{
|
||||
this.keyEncAlg = keyEncAlg;
|
||||
this.secureReadable = secureReadable;
|
||||
}
|
||||
|
||||
internal string GetContentAlgorithmName()
|
||||
{
|
||||
AlgorithmIdentifier algorithm = secureReadable.Algorithm;
|
||||
return algorithm.Algorithm.Id;
|
||||
}
|
||||
|
||||
internal CmsTypedStream GetContentFromSessionKey(KeyParameter sKey)
|
||||
{
|
||||
CmsReadable readable = secureReadable.GetReadable(sKey);
|
||||
try
|
||||
{
|
||||
return new CmsTypedStream(readable.GetInputStream());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("error getting .", e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetContent(ICipherParameters key)
|
||||
{
|
||||
try
|
||||
{
|
||||
return CmsUtilities.StreamToByteArray(GetContentStream(key).ContentStream);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new Exception("unable to parse internal stream: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetMac()
|
||||
{
|
||||
if (resultMac == null)
|
||||
{
|
||||
object cryptoObject = secureReadable.CryptoObject;
|
||||
if (cryptoObject is IMac)
|
||||
{
|
||||
resultMac = MacUtilities.DoFinal((IMac)cryptoObject);
|
||||
}
|
||||
}
|
||||
return Arrays.Clone(resultMac);
|
||||
}
|
||||
|
||||
public abstract CmsTypedStream GetContentStream(ICipherParameters key);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class RecipientInformationStore
|
||||
{
|
||||
private readonly IList all;
|
||||
|
||||
private readonly IDictionary table = Platform.CreateHashtable();
|
||||
|
||||
public RecipientInformation this[RecipientID selector] => GetFirstRecipient(selector);
|
||||
|
||||
public int Count => all.Count;
|
||||
|
||||
public RecipientInformationStore(ICollection recipientInfos)
|
||||
{
|
||||
foreach (RecipientInformation recipientInfo in recipientInfos)
|
||||
{
|
||||
RecipientID recipientID = recipientInfo.RecipientID;
|
||||
IList list = (IList)table[recipientID];
|
||||
if (list == null)
|
||||
{
|
||||
list = (IList)(table[recipientID] = Platform.CreateArrayList(1));
|
||||
}
|
||||
list.Add(recipientInfo);
|
||||
}
|
||||
all = Platform.CreateArrayList(recipientInfos);
|
||||
}
|
||||
|
||||
public RecipientInformation GetFirstRecipient(RecipientID selector)
|
||||
{
|
||||
IList list = (IList)table[selector];
|
||||
if (list != null)
|
||||
{
|
||||
return (RecipientInformation)list[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ICollection GetRecipients()
|
||||
{
|
||||
return Platform.CreateArrayList(all);
|
||||
}
|
||||
|
||||
public ICollection GetRecipients(RecipientID selector)
|
||||
{
|
||||
IList list = (IList)table[selector];
|
||||
if (list != null)
|
||||
{
|
||||
return Platform.CreateArrayList(list);
|
||||
}
|
||||
return Platform.CreateArrayList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class SignerID : X509CertStoreSelector
|
||||
{
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int num = Arrays.GetHashCode(base.SubjectKeyIdentifier);
|
||||
BigInteger bigInteger = base.SerialNumber;
|
||||
if (bigInteger != null)
|
||||
{
|
||||
num ^= bigInteger.GetHashCode();
|
||||
}
|
||||
X509Name x509Name = base.Issuer;
|
||||
if (x509Name != null)
|
||||
{
|
||||
num ^= x509Name.GetHashCode();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(obj is SignerID signerID))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Arrays.AreEqual(base.SubjectKeyIdentifier, signerID.SubjectKeyIdentifier) && object.Equals(base.SerialNumber, signerID.SerialNumber))
|
||||
{
|
||||
return X509CertStoreSelector.IssuersMatch(base.Issuer, signerID.Issuer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class SignerInfoGenerator
|
||||
{
|
||||
internal X509Certificate certificate;
|
||||
|
||||
internal ISignatureFactory contentSigner;
|
||||
|
||||
internal SignerIdentifier sigId;
|
||||
|
||||
internal CmsAttributeTableGenerator signedGen;
|
||||
|
||||
internal CmsAttributeTableGenerator unsignedGen;
|
||||
|
||||
private bool isDirectSignature;
|
||||
|
||||
internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory signerFactory)
|
||||
: this(sigId, signerFactory, isDirectSignature: false)
|
||||
{
|
||||
}
|
||||
|
||||
internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory signerFactory, bool isDirectSignature)
|
||||
{
|
||||
this.sigId = sigId;
|
||||
contentSigner = signerFactory;
|
||||
this.isDirectSignature = isDirectSignature;
|
||||
if (this.isDirectSignature)
|
||||
{
|
||||
signedGen = null;
|
||||
unsignedGen = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
signedGen = new DefaultSignedAttributeTableGenerator();
|
||||
unsignedGen = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory contentSigner, CmsAttributeTableGenerator signedGen, CmsAttributeTableGenerator unsignedGen)
|
||||
{
|
||||
this.sigId = sigId;
|
||||
this.contentSigner = contentSigner;
|
||||
this.signedGen = signedGen;
|
||||
this.unsignedGen = unsignedGen;
|
||||
isDirectSignature = false;
|
||||
}
|
||||
|
||||
internal void setAssociatedCertificate(X509Certificate certificate)
|
||||
{
|
||||
this.certificate = certificate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class SignerInfoGeneratorBuilder
|
||||
{
|
||||
private bool directSignature;
|
||||
|
||||
private CmsAttributeTableGenerator signedGen;
|
||||
|
||||
private CmsAttributeTableGenerator unsignedGen;
|
||||
|
||||
public SignerInfoGeneratorBuilder SetDirectSignature(bool hasNoSignedAttributes)
|
||||
{
|
||||
directSignature = hasNoSignedAttributes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignerInfoGeneratorBuilder WithSignedAttributeGenerator(CmsAttributeTableGenerator signedGen)
|
||||
{
|
||||
this.signedGen = signedGen;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignerInfoGeneratorBuilder WithUnsignedAttributeGenerator(CmsAttributeTableGenerator unsignedGen)
|
||||
{
|
||||
this.unsignedGen = unsignedGen;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignerInfoGenerator Build(ISignatureFactory contentSigner, X509Certificate certificate)
|
||||
{
|
||||
SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certificate.IssuerDN, new DerInteger(certificate.SerialNumber)));
|
||||
SignerInfoGenerator signerInfoGenerator = CreateGenerator(contentSigner, sigId);
|
||||
signerInfoGenerator.setAssociatedCertificate(certificate);
|
||||
return signerInfoGenerator;
|
||||
}
|
||||
|
||||
public SignerInfoGenerator Build(ISignatureFactory signerFactory, byte[] subjectKeyIdentifier)
|
||||
{
|
||||
SignerIdentifier sigId = new SignerIdentifier(new DerOctetString(subjectKeyIdentifier));
|
||||
return CreateGenerator(signerFactory, sigId);
|
||||
}
|
||||
|
||||
private SignerInfoGenerator CreateGenerator(ISignatureFactory contentSigner, SignerIdentifier sigId)
|
||||
{
|
||||
if (directSignature)
|
||||
{
|
||||
return new SignerInfoGenerator(sigId, contentSigner, isDirectSignature: true);
|
||||
}
|
||||
if (signedGen != null || unsignedGen != null)
|
||||
{
|
||||
if (signedGen == null)
|
||||
{
|
||||
signedGen = new DefaultSignedAttributeTableGenerator();
|
||||
}
|
||||
return new SignerInfoGenerator(sigId, contentSigner, signedGen, unsignedGen);
|
||||
}
|
||||
return new SignerInfoGenerator(sigId, contentSigner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Signers;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class SignerInformation
|
||||
{
|
||||
private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
|
||||
|
||||
private SignerID sid;
|
||||
|
||||
private Org.BouncyCastle.Asn1.Cms.SignerInfo info;
|
||||
|
||||
private AlgorithmIdentifier digestAlgorithm;
|
||||
|
||||
private AlgorithmIdentifier encryptionAlgorithm;
|
||||
|
||||
private readonly Asn1Set signedAttributeSet;
|
||||
|
||||
private readonly Asn1Set unsignedAttributeSet;
|
||||
|
||||
private CmsProcessable content;
|
||||
|
||||
private byte[] signature;
|
||||
|
||||
private DerObjectIdentifier contentType;
|
||||
|
||||
private IDigestCalculator digestCalculator;
|
||||
|
||||
private byte[] resultDigest;
|
||||
|
||||
private Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttributeTable;
|
||||
|
||||
private Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributeTable;
|
||||
|
||||
private readonly bool isCounterSignature;
|
||||
|
||||
public bool IsCounterSignature => isCounterSignature;
|
||||
|
||||
public DerObjectIdentifier ContentType => contentType;
|
||||
|
||||
public SignerID SignerID => sid;
|
||||
|
||||
public int Version => info.Version.Value.IntValue;
|
||||
|
||||
public AlgorithmIdentifier DigestAlgorithmID => digestAlgorithm;
|
||||
|
||||
public string DigestAlgOid => digestAlgorithm.Algorithm.Id;
|
||||
|
||||
public Asn1Object DigestAlgParams => digestAlgorithm.Parameters?.ToAsn1Object();
|
||||
|
||||
public AlgorithmIdentifier EncryptionAlgorithmID => encryptionAlgorithm;
|
||||
|
||||
public string EncryptionAlgOid => encryptionAlgorithm.Algorithm.Id;
|
||||
|
||||
public Asn1Object EncryptionAlgParams => encryptionAlgorithm.Parameters?.ToAsn1Object();
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable SignedAttributes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (signedAttributeSet != null && signedAttributeTable == null)
|
||||
{
|
||||
signedAttributeTable = new Org.BouncyCastle.Asn1.Cms.AttributeTable(signedAttributeSet);
|
||||
}
|
||||
return signedAttributeTable;
|
||||
}
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable UnsignedAttributes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (unsignedAttributeSet != null && unsignedAttributeTable == null)
|
||||
{
|
||||
unsignedAttributeTable = new Org.BouncyCastle.Asn1.Cms.AttributeTable(unsignedAttributeSet);
|
||||
}
|
||||
return unsignedAttributeTable;
|
||||
}
|
||||
}
|
||||
|
||||
internal SignerInformation(Org.BouncyCastle.Asn1.Cms.SignerInfo info, DerObjectIdentifier contentType, CmsProcessable content, IDigestCalculator digestCalculator)
|
||||
{
|
||||
this.info = info;
|
||||
sid = new SignerID();
|
||||
this.contentType = contentType;
|
||||
isCounterSignature = contentType == null;
|
||||
try
|
||||
{
|
||||
SignerIdentifier signerID = info.SignerID;
|
||||
if (signerID.IsTagged)
|
||||
{
|
||||
Asn1OctetString instance = Asn1OctetString.GetInstance(signerID.ID);
|
||||
sid.SubjectKeyIdentifier = instance.GetEncoded();
|
||||
}
|
||||
else
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber instance2 = Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber.GetInstance(signerID.ID);
|
||||
sid.Issuer = instance2.Name;
|
||||
sid.SerialNumber = instance2.SerialNumber.Value;
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
throw new ArgumentException("invalid sid in SignerInfo");
|
||||
}
|
||||
digestAlgorithm = info.DigestAlgorithm;
|
||||
signedAttributeSet = info.AuthenticatedAttributes;
|
||||
unsignedAttributeSet = info.UnauthenticatedAttributes;
|
||||
encryptionAlgorithm = info.DigestEncryptionAlgorithm;
|
||||
signature = info.EncryptedDigest.GetOctets();
|
||||
this.content = content;
|
||||
this.digestCalculator = digestCalculator;
|
||||
}
|
||||
|
||||
protected SignerInformation(SignerInformation baseInfo)
|
||||
{
|
||||
info = baseInfo.info;
|
||||
contentType = baseInfo.contentType;
|
||||
isCounterSignature = baseInfo.IsCounterSignature;
|
||||
sid = baseInfo.SignerID;
|
||||
digestAlgorithm = info.DigestAlgorithm;
|
||||
signedAttributeSet = info.AuthenticatedAttributes;
|
||||
unsignedAttributeSet = info.UnauthenticatedAttributes;
|
||||
encryptionAlgorithm = info.DigestEncryptionAlgorithm;
|
||||
signature = info.EncryptedDigest.GetOctets();
|
||||
content = baseInfo.content;
|
||||
resultDigest = baseInfo.resultDigest;
|
||||
signedAttributeTable = baseInfo.signedAttributeTable;
|
||||
unsignedAttributeTable = baseInfo.unsignedAttributeTable;
|
||||
}
|
||||
|
||||
public byte[] GetContentDigest()
|
||||
{
|
||||
if (resultDigest == null)
|
||||
{
|
||||
throw new InvalidOperationException("method can only be called after verify.");
|
||||
}
|
||||
return (byte[])resultDigest.Clone();
|
||||
}
|
||||
|
||||
public byte[] GetSignature()
|
||||
{
|
||||
return (byte[])signature.Clone();
|
||||
}
|
||||
|
||||
public SignerInformationStore GetCounterSignatures()
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = UnsignedAttributes;
|
||||
if (unsignedAttributes == null)
|
||||
{
|
||||
return new SignerInformationStore(Platform.CreateArrayList(0));
|
||||
}
|
||||
IList list = Platform.CreateArrayList();
|
||||
Asn1EncodableVector all = unsignedAttributes.GetAll(CmsAttributes.CounterSignature);
|
||||
foreach (Org.BouncyCastle.Asn1.Cms.Attribute item in all)
|
||||
{
|
||||
Asn1Set attrValues = item.AttrValues;
|
||||
_ = attrValues.Count;
|
||||
_ = 1;
|
||||
foreach (Asn1Encodable item2 in attrValues)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.SignerInfo instance = Org.BouncyCastle.Asn1.Cms.SignerInfo.GetInstance(item2.ToAsn1Object());
|
||||
string digestAlgName = CmsSignedHelper.Instance.GetDigestAlgName(instance.DigestAlgorithm.Algorithm.Id);
|
||||
list.Add(new SignerInformation(instance, null, null, new CounterSignatureDigestCalculator(digestAlgName, GetSignature())));
|
||||
}
|
||||
}
|
||||
return new SignerInformationStore(list);
|
||||
}
|
||||
|
||||
public byte[] GetEncodedSignedAttributes()
|
||||
{
|
||||
if (signedAttributeSet != null)
|
||||
{
|
||||
return signedAttributeSet.GetEncoded("DER");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool DoVerify(AsymmetricKeyParameter key)
|
||||
{
|
||||
string digestAlgName = Helper.GetDigestAlgName(DigestAlgOid);
|
||||
IDigest digestInstance = Helper.GetDigestInstance(digestAlgName);
|
||||
DerObjectIdentifier algorithm = encryptionAlgorithm.Algorithm;
|
||||
Asn1Encodable parameters = encryptionAlgorithm.Parameters;
|
||||
ISigner signer;
|
||||
if (algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
throw new CmsException("RSASSA-PSS signature must specify algorithm parameters");
|
||||
}
|
||||
try
|
||||
{
|
||||
RsassaPssParameters instance = RsassaPssParameters.GetInstance(parameters.ToAsn1Object());
|
||||
if (!instance.HashAlgorithm.Algorithm.Equals(digestAlgorithm.Algorithm))
|
||||
{
|
||||
throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm");
|
||||
}
|
||||
if (!instance.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1))
|
||||
{
|
||||
throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF");
|
||||
}
|
||||
IDigest digest = DigestUtilities.GetDigest(instance.HashAlgorithm.Algorithm);
|
||||
int intValue = instance.SaltLength.Value.IntValue;
|
||||
byte b = (byte)instance.TrailerField.Value.IntValue;
|
||||
if (b != 1)
|
||||
{
|
||||
throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1");
|
||||
}
|
||||
signer = new PssSigner(new RsaBlindedEngine(), digest, intValue);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CmsException("failed to set RSASSA-PSS signature parameters", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string algorithm2 = digestAlgName + "with" + Helper.GetEncryptionAlgName(EncryptionAlgOid);
|
||||
signer = Helper.GetSignatureInstance(algorithm2);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (digestCalculator != null)
|
||||
{
|
||||
resultDigest = digestCalculator.GetDigest();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (content != null)
|
||||
{
|
||||
content.Write(new DigestSink(digestInstance));
|
||||
}
|
||||
else if (signedAttributeSet == null)
|
||||
{
|
||||
throw new CmsException("data not encapsulated in signature - use detached constructor.");
|
||||
}
|
||||
resultDigest = DigestUtilities.DoFinal(digestInstance);
|
||||
}
|
||||
}
|
||||
catch (IOException e2)
|
||||
{
|
||||
throw new CmsException("can't process mime object to create signature.", e2);
|
||||
}
|
||||
Asn1Object singleValuedSignedAttribute = GetSingleValuedSignedAttribute(CmsAttributes.ContentType, "content-type");
|
||||
if (singleValuedSignedAttribute == null)
|
||||
{
|
||||
if (!isCounterSignature && signedAttributeSet != null)
|
||||
{
|
||||
throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isCounterSignature)
|
||||
{
|
||||
throw new CmsException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
|
||||
}
|
||||
if (!(singleValuedSignedAttribute is DerObjectIdentifier))
|
||||
{
|
||||
throw new CmsException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
|
||||
}
|
||||
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)singleValuedSignedAttribute;
|
||||
if (!derObjectIdentifier.Equals(contentType))
|
||||
{
|
||||
throw new CmsException("content-type attribute value does not match eContentType");
|
||||
}
|
||||
}
|
||||
Asn1Object singleValuedSignedAttribute2 = GetSingleValuedSignedAttribute(CmsAttributes.MessageDigest, "message-digest");
|
||||
if (singleValuedSignedAttribute2 == null)
|
||||
{
|
||||
if (signedAttributeSet != null)
|
||||
{
|
||||
throw new CmsException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(singleValuedSignedAttribute2 is Asn1OctetString))
|
||||
{
|
||||
throw new CmsException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
|
||||
}
|
||||
Asn1OctetString asn1OctetString = (Asn1OctetString)singleValuedSignedAttribute2;
|
||||
if (!Arrays.AreEqual(resultDigest, asn1OctetString.GetOctets()))
|
||||
{
|
||||
throw new CmsException("message-digest attribute value does not match calculated value");
|
||||
}
|
||||
}
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttributes = SignedAttributes;
|
||||
if (signedAttributes != null && signedAttributes.GetAll(CmsAttributes.CounterSignature).Count > 0)
|
||||
{
|
||||
throw new CmsException("A countersignature attribute MUST NOT be a signed attribute");
|
||||
}
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = UnsignedAttributes;
|
||||
if (unsignedAttributes != null)
|
||||
{
|
||||
foreach (Org.BouncyCastle.Asn1.Cms.Attribute item in unsignedAttributes.GetAll(CmsAttributes.CounterSignature))
|
||||
{
|
||||
if (item.AttrValues.Count < 1)
|
||||
{
|
||||
throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue");
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
signer.Init(forSigning: false, key);
|
||||
if (signedAttributeSet == null)
|
||||
{
|
||||
if (digestCalculator != null)
|
||||
{
|
||||
return VerifyDigest(resultDigest, key, GetSignature());
|
||||
}
|
||||
if (content != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
content.Write(new SignerSink(signer));
|
||||
}
|
||||
catch (SignatureException ex)
|
||||
{
|
||||
throw new CmsStreamException("signature problem: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] encodedSignedAttributes = GetEncodedSignedAttributes();
|
||||
signer.BlockUpdate(encodedSignedAttributes, 0, encodedSignedAttributes.Length);
|
||||
}
|
||||
return signer.VerifySignature(GetSignature());
|
||||
}
|
||||
catch (InvalidKeyException e3)
|
||||
{
|
||||
throw new CmsException("key not appropriate to signature in message.", e3);
|
||||
}
|
||||
catch (IOException e4)
|
||||
{
|
||||
throw new CmsException("can't process mime object to create signature.", e4);
|
||||
}
|
||||
catch (SignatureException ex2)
|
||||
{
|
||||
throw new CmsException("invalid signature format in message: " + ex2.Message, ex2);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsNull(Asn1Encodable o)
|
||||
{
|
||||
if (!(o is Asn1Null))
|
||||
{
|
||||
return o == null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private DigestInfo DerDecode(byte[] encoding)
|
||||
{
|
||||
if (encoding[0] != 48)
|
||||
{
|
||||
throw new IOException("not a digest info object");
|
||||
}
|
||||
DigestInfo instance = DigestInfo.GetInstance(Asn1Object.FromByteArray(encoding));
|
||||
if (instance.GetEncoded().Length != encoding.Length)
|
||||
{
|
||||
throw new CmsException("malformed RSA signature");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private bool VerifyDigest(byte[] digest, AsymmetricKeyParameter key, byte[] signature)
|
||||
{
|
||||
string encryptionAlgName = Helper.GetEncryptionAlgName(EncryptionAlgOid);
|
||||
try
|
||||
{
|
||||
if (encryptionAlgName.Equals("RSA"))
|
||||
{
|
||||
IBufferedCipher bufferedCipher = CmsEnvelopedHelper.Instance.CreateAsymmetricCipher("RSA/ECB/PKCS1Padding");
|
||||
bufferedCipher.Init(forEncryption: false, key);
|
||||
byte[] encoding = bufferedCipher.DoFinal(signature);
|
||||
DigestInfo digestInfo = DerDecode(encoding);
|
||||
if (!digestInfo.AlgorithmID.Algorithm.Equals(digestAlgorithm.Algorithm))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!IsNull(digestInfo.AlgorithmID.Parameters))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
byte[] digest2 = digestInfo.GetDigest();
|
||||
return Arrays.ConstantTimeAreEqual(digest, digest2);
|
||||
}
|
||||
if (encryptionAlgName.Equals("DSA"))
|
||||
{
|
||||
ISigner signer = SignerUtilities.GetSigner("NONEwithDSA");
|
||||
signer.Init(forSigning: false, key);
|
||||
signer.BlockUpdate(digest, 0, digest.Length);
|
||||
return signer.VerifySignature(signature);
|
||||
}
|
||||
throw new CmsException("algorithm: " + encryptionAlgName + " not supported in base signatures.");
|
||||
}
|
||||
catch (SecurityUtilityException ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
catch (GeneralSecurityException ex2)
|
||||
{
|
||||
throw new CmsException("Exception processing signature: " + ex2, ex2);
|
||||
}
|
||||
catch (IOException ex3)
|
||||
{
|
||||
throw new CmsException("Exception decoding signature: " + ex3, ex3);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Verify(AsymmetricKeyParameter pubKey)
|
||||
{
|
||||
if (pubKey.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected public key", "pubKey");
|
||||
}
|
||||
GetSigningTime();
|
||||
return DoVerify(pubKey);
|
||||
}
|
||||
|
||||
public bool Verify(X509Certificate cert)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.Time signingTime = GetSigningTime();
|
||||
if (signingTime != null)
|
||||
{
|
||||
cert.CheckValidity(signingTime.Date);
|
||||
}
|
||||
return DoVerify(cert.GetPublicKey());
|
||||
}
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.SignerInfo ToSignerInfo()
|
||||
{
|
||||
return info;
|
||||
}
|
||||
|
||||
private Asn1Object GetSingleValuedSignedAttribute(DerObjectIdentifier attrOID, string printableName)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = UnsignedAttributes;
|
||||
if (unsignedAttributes != null && unsignedAttributes.GetAll(attrOID).Count > 0)
|
||||
{
|
||||
throw new CmsException("The " + printableName + " attribute MUST NOT be an unsigned attribute");
|
||||
}
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttributes = SignedAttributes;
|
||||
if (signedAttributes == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Asn1EncodableVector all = signedAttributes.GetAll(attrOID);
|
||||
switch (all.Count)
|
||||
{
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.Attribute attribute = (Org.BouncyCastle.Asn1.Cms.Attribute)all[0];
|
||||
Asn1Set attrValues = attribute.AttrValues;
|
||||
if (attrValues.Count != 1)
|
||||
{
|
||||
throw new CmsException("A " + printableName + " attribute MUST have a single attribute value");
|
||||
}
|
||||
return attrValues[0].ToAsn1Object();
|
||||
}
|
||||
default:
|
||||
throw new CmsException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the " + printableName + " attribute");
|
||||
}
|
||||
}
|
||||
|
||||
private Org.BouncyCastle.Asn1.Cms.Time GetSigningTime()
|
||||
{
|
||||
Asn1Object singleValuedSignedAttribute = GetSingleValuedSignedAttribute(CmsAttributes.SigningTime, "signing-time");
|
||||
if (singleValuedSignedAttribute == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Org.BouncyCastle.Asn1.Cms.Time.GetInstance(singleValuedSignedAttribute);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
throw new CmsException("signing-time attribute value not a valid 'Time' structure");
|
||||
}
|
||||
}
|
||||
|
||||
public static SignerInformation ReplaceUnsignedAttributes(SignerInformation signerInformation, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.SignerInfo signerInfo = signerInformation.info;
|
||||
Asn1Set unauthenticatedAttributes = null;
|
||||
if (unsignedAttributes != null)
|
||||
{
|
||||
unauthenticatedAttributes = new DerSet(unsignedAttributes.ToAsn1EncodableVector());
|
||||
}
|
||||
return new SignerInformation(new Org.BouncyCastle.Asn1.Cms.SignerInfo(signerInfo.SignerID, signerInfo.DigestAlgorithm, signerInfo.AuthenticatedAttributes, signerInfo.DigestEncryptionAlgorithm, signerInfo.EncryptedDigest, unauthenticatedAttributes), signerInformation.contentType, signerInformation.content, null);
|
||||
}
|
||||
|
||||
public static SignerInformation AddCounterSigners(SignerInformation signerInformation, SignerInformationStore counterSigners)
|
||||
{
|
||||
Org.BouncyCastle.Asn1.Cms.SignerInfo signerInfo = signerInformation.info;
|
||||
Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = signerInformation.UnsignedAttributes;
|
||||
Asn1EncodableVector asn1EncodableVector = ((unsignedAttributes == null) ? new Asn1EncodableVector() : unsignedAttributes.ToAsn1EncodableVector());
|
||||
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
||||
foreach (SignerInformation signer in counterSigners.GetSigners())
|
||||
{
|
||||
asn1EncodableVector2.Add(signer.ToSignerInfo());
|
||||
}
|
||||
asn1EncodableVector.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.CounterSignature, new DerSet(asn1EncodableVector2)));
|
||||
return new SignerInformation(new Org.BouncyCastle.Asn1.Cms.SignerInfo(signerInfo.SignerID, signerInfo.DigestAlgorithm, signerInfo.AuthenticatedAttributes, signerInfo.DigestEncryptionAlgorithm, signerInfo.EncryptedDigest, new DerSet(asn1EncodableVector)), signerInformation.contentType, signerInformation.content, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class SignerInformationStore
|
||||
{
|
||||
private readonly IList all;
|
||||
|
||||
private readonly IDictionary table = Platform.CreateHashtable();
|
||||
|
||||
public int Count => all.Count;
|
||||
|
||||
public SignerInformationStore(SignerInformation signerInfo)
|
||||
{
|
||||
all = Platform.CreateArrayList(1);
|
||||
all.Add(signerInfo);
|
||||
SignerID signerID = signerInfo.SignerID;
|
||||
table[signerID] = all;
|
||||
}
|
||||
|
||||
public SignerInformationStore(ICollection signerInfos)
|
||||
{
|
||||
foreach (SignerInformation signerInfo in signerInfos)
|
||||
{
|
||||
SignerID signerID = signerInfo.SignerID;
|
||||
IList list = (IList)table[signerID];
|
||||
if (list == null)
|
||||
{
|
||||
list = (IList)(table[signerID] = Platform.CreateArrayList(1));
|
||||
}
|
||||
list.Add(signerInfo);
|
||||
}
|
||||
all = Platform.CreateArrayList(signerInfos);
|
||||
}
|
||||
|
||||
public SignerInformation GetFirstSigner(SignerID selector)
|
||||
{
|
||||
IList list = (IList)table[selector];
|
||||
if (list != null)
|
||||
{
|
||||
return (SignerInformation)list[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ICollection GetSigners()
|
||||
{
|
||||
return Platform.CreateArrayList(all);
|
||||
}
|
||||
|
||||
public ICollection GetSigners(SignerID selector)
|
||||
{
|
||||
IList list = (IList)table[selector];
|
||||
if (list != null)
|
||||
{
|
||||
return Platform.CreateArrayList(list);
|
||||
}
|
||||
return Platform.CreateArrayList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class SimpleAttributeTableGenerator : CmsAttributeTableGenerator
|
||||
{
|
||||
private readonly AttributeTable attributes;
|
||||
|
||||
public SimpleAttributeTableGenerator(AttributeTable attributes)
|
||||
{
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public virtual AttributeTable GetAttributes(IDictionary parameters)
|
||||
{
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user