init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
namespace Org.BouncyCastle.Crmf;
public class AuthenticatorControl : IControl
{
private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_authenticator;
private readonly DerUtf8String token;
public DerObjectIdentifier Type => type;
public Asn1Encodable Value => token;
public AuthenticatorControl(DerUtf8String token)
{
this.token = token;
}
public AuthenticatorControl(string token)
{
this.token = new DerUtf8String(token);
}
}

View File

@@ -0,0 +1,159 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Operators;
namespace Org.BouncyCastle.Crmf;
public class CertificateRequestMessage
{
public static readonly int popRaVerified = 0;
public static readonly int popSigningKey = 1;
public static readonly int popKeyEncipherment = 2;
public static readonly int popKeyAgreement = 3;
private readonly CertReqMsg certReqMsg;
private readonly Controls controls;
public bool HasControls => controls != null;
public bool HasProofOfPossession => certReqMsg.Popo != null;
public int ProofOfPossession => certReqMsg.Popo.Type;
public bool HasSigningKeyProofOfPossessionWithPkMac
{
get
{
ProofOfPossession popo = certReqMsg.Popo;
if (popo.Type == popSigningKey)
{
PopoSigningKey instance = PopoSigningKey.GetInstance(popo.Object);
return instance.PoposkInput.PublicKeyMac != null;
}
return false;
}
}
private static CertReqMsg ParseBytes(byte[] encoding)
{
return CertReqMsg.GetInstance(encoding);
}
public CertificateRequestMessage(byte[] encoded)
: this(CertReqMsg.GetInstance(encoded))
{
}
public CertificateRequestMessage(CertReqMsg certReqMsg)
{
this.certReqMsg = certReqMsg;
controls = certReqMsg.CertReq.Controls;
}
public CertReqMsg ToAsn1Structure()
{
return certReqMsg;
}
public CertTemplate GetCertTemplate()
{
return certReqMsg.CertReq.CertTemplate;
}
public bool HasControl(DerObjectIdentifier objectIdentifier)
{
return FindControl(objectIdentifier) != null;
}
public IControl GetControl(DerObjectIdentifier type)
{
AttributeTypeAndValue attributeTypeAndValue = FindControl(type);
if (attributeTypeAndValue != null)
{
if (attributeTypeAndValue.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions))
{
return new PkiArchiveControl(PkiArchiveOptions.GetInstance(attributeTypeAndValue.Value));
}
if (attributeTypeAndValue.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_regToken))
{
return new RegTokenControl(DerUtf8String.GetInstance(attributeTypeAndValue.Value));
}
if (attributeTypeAndValue.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_authenticator))
{
return new AuthenticatorControl(DerUtf8String.GetInstance(attributeTypeAndValue.Value));
}
}
return null;
}
public AttributeTypeAndValue FindControl(DerObjectIdentifier type)
{
if (controls == null)
{
return null;
}
AttributeTypeAndValue[] array = controls.ToAttributeTypeAndValueArray();
AttributeTypeAndValue result = null;
for (int i = 0; i < array.Length; i++)
{
if (array[i].Type.Equals(type))
{
result = array[i];
break;
}
}
return result;
}
public bool IsValidSigningKeyPop(IVerifierFactoryProvider verifierProvider)
{
ProofOfPossession popo = certReqMsg.Popo;
if (popo.Type == popSigningKey)
{
PopoSigningKey instance = PopoSigningKey.GetInstance(popo.Object);
if (instance.PoposkInput != null && instance.PoposkInput.PublicKeyMac != null)
{
throw new InvalidOperationException("verification requires password check");
}
return verifySignature(verifierProvider, instance);
}
throw new InvalidOperationException("not Signing Key type of proof of possession");
}
private bool verifySignature(IVerifierFactoryProvider verifierFactoryProvider, PopoSigningKey signKey)
{
IStreamCalculator streamCalculator;
try
{
IVerifierFactory verifierFactory = verifierFactoryProvider.CreateVerifierFactory(signKey.AlgorithmIdentifier);
streamCalculator = verifierFactory.CreateCalculator();
}
catch (Exception ex)
{
throw new CrmfException("unable to create verifier: " + ex.Message, ex);
}
if (signKey.PoposkInput != null)
{
byte[] derEncoded = signKey.GetDerEncoded();
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
}
else
{
byte[] derEncoded2 = certReqMsg.CertReq.GetDerEncoded();
streamCalculator.Stream.Write(derEncoded2, 0, derEncoded2.Length);
}
DefaultVerifierResult defaultVerifierResult = (DefaultVerifierResult)streamCalculator.GetResult();
return defaultVerifierResult.IsVerified(signKey.Signature.GetBytes());
}
public byte[] GetEncoded()
{
return certReqMsg.GetEncoded();
}
}

View File

@@ -0,0 +1,236 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crmf;
public class CertificateRequestMessageBuilder
{
private readonly BigInteger _certReqId;
private X509ExtensionsGenerator _extGenerator;
private CertTemplateBuilder _templateBuilder;
private IList _controls = Platform.CreateArrayList();
private ISignatureFactory _popSigner;
private PKMacBuilder _pkMacBuilder;
private char[] _password;
private GeneralName _sender;
private int _popoType = 2;
private PopoPrivKey _popoPrivKey;
private Asn1Null _popRaVerified;
private PKMacValue _agreeMac;
public CertificateRequestMessageBuilder(BigInteger certReqId)
{
_certReqId = certReqId;
_extGenerator = new X509ExtensionsGenerator();
_templateBuilder = new CertTemplateBuilder();
}
public CertificateRequestMessageBuilder SetPublicKey(SubjectPublicKeyInfo publicKeyInfo)
{
if (publicKeyInfo != null)
{
_templateBuilder.SetPublicKey(publicKeyInfo);
}
return this;
}
public CertificateRequestMessageBuilder SetIssuer(X509Name issuer)
{
if (issuer != null)
{
_templateBuilder.SetIssuer(issuer);
}
return this;
}
public CertificateRequestMessageBuilder SetSubject(X509Name subject)
{
if (subject != null)
{
_templateBuilder.SetSubject(subject);
}
return this;
}
public CertificateRequestMessageBuilder SetSerialNumber(BigInteger serialNumber)
{
if (serialNumber != null)
{
_templateBuilder.SetSerialNumber(new DerInteger(serialNumber));
}
return this;
}
public CertificateRequestMessageBuilder SetValidity(Time notBefore, Time notAfter)
{
_templateBuilder.SetValidity(new OptionalValidity(notBefore, notAfter));
return this;
}
public CertificateRequestMessageBuilder AddExtension(DerObjectIdentifier oid, bool critical, Asn1Encodable value)
{
_extGenerator.AddExtension(oid, critical, value);
return this;
}
public CertificateRequestMessageBuilder AddExtension(DerObjectIdentifier oid, bool critical, byte[] value)
{
_extGenerator.AddExtension(oid, critical, value);
return this;
}
public CertificateRequestMessageBuilder AddControl(IControl control)
{
_controls.Add(control);
return this;
}
public CertificateRequestMessageBuilder SetProofOfPossessionSignKeySigner(ISignatureFactory popoSignatureFactory)
{
if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null)
{
throw new InvalidOperationException("only one proof of possession is allowed.");
}
_popSigner = popoSignatureFactory;
return this;
}
public CertificateRequestMessageBuilder SetProofOfPossessionSubsequentMessage(SubsequentMessage msg)
{
if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null)
{
throw new InvalidOperationException("only one proof of possession is allowed.");
}
_popoType = 2;
_popoPrivKey = new PopoPrivKey(msg);
return this;
}
public CertificateRequestMessageBuilder SetProofOfPossessionSubsequentMessage(int type, SubsequentMessage msg)
{
if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null)
{
throw new InvalidOperationException("only one proof of possession is allowed.");
}
if (type != 2 && type != 3)
{
throw new ArgumentException("type must be ProofOfPossession.TYPE_KEY_ENCIPHERMENT || ProofOfPossession.TYPE_KEY_AGREEMENT");
}
_popoType = type;
_popoPrivKey = new PopoPrivKey(msg);
return this;
}
public CertificateRequestMessageBuilder SetProofOfPossessionAgreeMac(PKMacValue macValue)
{
if (_popSigner != null || _popRaVerified != null || _popoPrivKey != null)
{
throw new InvalidOperationException("only one proof of possession allowed");
}
_agreeMac = macValue;
return this;
}
public CertificateRequestMessageBuilder SetProofOfPossessionRaVerified()
{
if (_popSigner != null || _popoPrivKey != null)
{
throw new InvalidOperationException("only one proof of possession allowed");
}
_popRaVerified = DerNull.Instance;
return this;
}
public CertificateRequestMessageBuilder SetAuthInfoPKMAC(PKMacBuilder pkmacFactory, char[] password)
{
_pkMacBuilder = pkmacFactory;
_password = password;
return this;
}
public CertificateRequestMessageBuilder SetAuthInfoSender(X509Name sender)
{
return SetAuthInfoSender(new GeneralName(sender));
}
public CertificateRequestMessageBuilder SetAuthInfoSender(GeneralName sender)
{
_sender = sender;
return this;
}
public CertificateRequestMessage Build()
{
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(new DerInteger(_certReqId));
if (!_extGenerator.IsEmpty)
{
_templateBuilder.SetExtensions(_extGenerator.Generate());
}
asn1EncodableVector.Add(_templateBuilder.Build());
if (_controls.Count > 0)
{
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
foreach (object control2 in _controls)
{
IControl control = (IControl)control2;
asn1EncodableVector2.Add(new AttributeTypeAndValue(control.Type, control.Value));
}
asn1EncodableVector.Add(new DerSequence(asn1EncodableVector2));
}
CertRequest instance = CertRequest.GetInstance(new DerSequence(asn1EncodableVector));
asn1EncodableVector = new Asn1EncodableVector(instance);
if (_popSigner != null)
{
CertTemplate certTemplate = instance.CertTemplate;
if (certTemplate.Subject == null || certTemplate.PublicKey == null)
{
SubjectPublicKeyInfo publicKey = instance.CertTemplate.PublicKey;
ProofOfPossessionSigningKeyBuilder proofOfPossessionSigningKeyBuilder = new ProofOfPossessionSigningKeyBuilder(publicKey);
if (_sender != null)
{
proofOfPossessionSigningKeyBuilder.SetSender(_sender);
}
else
{
proofOfPossessionSigningKeyBuilder.SetPublicKeyMac(_pkMacBuilder, _password);
}
asn1EncodableVector.Add(new ProofOfPossession(proofOfPossessionSigningKeyBuilder.Build(_popSigner)));
}
else
{
ProofOfPossessionSigningKeyBuilder proofOfPossessionSigningKeyBuilder2 = new ProofOfPossessionSigningKeyBuilder(instance);
asn1EncodableVector.Add(new ProofOfPossession(proofOfPossessionSigningKeyBuilder2.Build(_popSigner)));
}
}
else if (_popoPrivKey != null)
{
asn1EncodableVector.Add(new ProofOfPossession(_popoType, _popoPrivKey));
}
else if (_agreeMac != null)
{
asn1EncodableVector.Add(new ProofOfPossession(3, PopoPrivKey.GetInstance(new DerTaggedObject(explicitly: false, 3, _agreeMac), isExplicit: true)));
}
else if (_popRaVerified != null)
{
asn1EncodableVector.Add(new ProofOfPossession());
}
return new CertificateRequestMessage(CertReqMsg.GetInstance(new DerSequence(asn1EncodableVector)));
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace Org.BouncyCastle.Crmf;
public class CrmfException : Exception
{
public CrmfException()
{
}
public CrmfException(string message)
: base(message)
{
}
public CrmfException(string message, Exception innerException)
: base(message, innerException)
{
}
}

View File

@@ -0,0 +1,18 @@
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crmf;
public class DefaultPKMacPrimitivesProvider : IPKMacPrimitivesProvider
{
public IDigest CreateDigest(AlgorithmIdentifier digestAlg)
{
return DigestUtilities.GetDigest(digestAlg.Algorithm);
}
public IMac CreateMac(AlgorithmIdentifier macAlg)
{
return MacUtilities.GetMac(macAlg.Algorithm);
}
}

View File

@@ -0,0 +1,27 @@
using Org.BouncyCastle.Crypto;
namespace Org.BouncyCastle.Crmf;
internal class DefaultPKMacResult : IBlockResult
{
private readonly IMac mac;
public DefaultPKMacResult(IMac mac)
{
this.mac = mac;
}
public byte[] Collect()
{
byte[] array = new byte[mac.GetMacSize()];
mac.DoFinal(array, 0);
return array;
}
public int Collect(byte[] sig, int sigOff)
{
byte[] array = Collect();
array.CopyTo(sig, sigOff);
return array.Length;
}
}

View File

@@ -0,0 +1,110 @@
using System;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.IO;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Crmf;
public class EncryptedValueBuilder
{
private readonly IKeyWrapper wrapper;
private readonly ICipherBuilderWithKey encryptor;
private readonly IEncryptedValuePadder padder;
public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor)
: this(wrapper, encryptor, null)
{
}
public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor, IEncryptedValuePadder padder)
{
this.wrapper = wrapper;
this.encryptor = encryptor;
this.padder = padder;
}
public EncryptedValue Build(char[] revocationPassphrase)
{
return EncryptData(PadData(Strings.ToUtf8ByteArray(revocationPassphrase)));
}
public EncryptedValue Build(X509Certificate holder)
{
try
{
return EncryptData(PadData(holder.GetEncoded()));
}
catch (IOException ex)
{
throw new CrmfException("cannot encode certificate: " + ex.Message, ex);
}
}
public EncryptedValue Build(PrivateKeyInfo privateKeyInfo)
{
Pkcs8EncryptedPrivateKeyInfoBuilder pkcs8EncryptedPrivateKeyInfoBuilder = new Pkcs8EncryptedPrivateKeyInfoBuilder(privateKeyInfo);
AlgorithmIdentifier privateKeyAlgorithm = privateKeyInfo.PrivateKeyAlgorithm;
AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails;
try
{
Pkcs8EncryptedPrivateKeyInfo pkcs8EncryptedPrivateKeyInfo = pkcs8EncryptedPrivateKeyInfoBuilder.Build(encryptor);
DerBitString encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect());
AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails;
Asn1OctetString valueHint = null;
return new EncryptedValue(privateKeyAlgorithm, symmAlg, encSymmKey, keyAlg, valueHint, new DerBitString(pkcs8EncryptedPrivateKeyInfo.GetEncryptedData()));
}
catch (Exception ex)
{
throw new CrmfException("cannot wrap key: " + ex.Message, ex);
}
}
private EncryptedValue EncryptData(byte[] data)
{
MemoryOutputStream memoryOutputStream = new MemoryOutputStream();
Stream stream = encryptor.BuildCipher(memoryOutputStream).Stream;
try
{
stream.Write(data, 0, data.Length);
stream.Close();
}
catch (IOException ex)
{
throw new CrmfException("cannot process data: " + ex.Message, ex);
}
AlgorithmIdentifier intendedAlg = null;
AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails;
DerBitString encSymmKey;
try
{
encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect());
}
catch (Exception ex2)
{
throw new CrmfException("cannot wrap key: " + ex2.Message, ex2);
}
AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails;
Asn1OctetString valueHint = null;
DerBitString encValue = new DerBitString(memoryOutputStream.ToArray());
return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, encValue);
}
private byte[] PadData(byte[] data)
{
if (padder != null)
{
return padder.GetPaddedData(data);
}
return data;
}
}

View File

@@ -0,0 +1,10 @@
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Crmf;
public interface IControl
{
DerObjectIdentifier Type { get; }
Asn1Encodable Value { get; }
}

View File

@@ -0,0 +1,8 @@
namespace Org.BouncyCastle.Crmf;
public interface IEncryptedValuePadder
{
byte[] GetPaddedData(byte[] data);
byte[] GetUnpaddedData(byte[] paddedData);
}

View File

@@ -0,0 +1,11 @@
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
namespace Org.BouncyCastle.Crmf;
public interface IPKMacPrimitivesProvider
{
IDigest CreateDigest(AlgorithmIdentifier digestAlg);
IMac CreateMac(AlgorithmIdentifier macAlg);
}

View File

@@ -0,0 +1,139 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.Iana;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crmf;
public class PKMacBuilder
{
private AlgorithmIdentifier owf;
private AlgorithmIdentifier mac;
private IPKMacPrimitivesProvider provider;
private SecureRandom random;
private PbmParameter parameters;
private int iterationCount;
private int saltLength;
private byte[] salt;
private int maxIterations;
public PKMacBuilder()
: this(new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1), 1000, new AlgorithmIdentifier(IanaObjectIdentifiers.HmacSha1, DerNull.Instance), new DefaultPKMacPrimitivesProvider())
{
}
public PKMacBuilder(IPKMacPrimitivesProvider provider)
: this(new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1), 1000, new AlgorithmIdentifier(IanaObjectIdentifiers.HmacSha1, DerNull.Instance), provider)
{
}
public PKMacBuilder(IPKMacPrimitivesProvider provider, AlgorithmIdentifier digestAlgorithmIdentifier, AlgorithmIdentifier macAlgorithmIdentifier)
: this(digestAlgorithmIdentifier, 1000, macAlgorithmIdentifier, provider)
{
}
public PKMacBuilder(IPKMacPrimitivesProvider provider, int maxIterations)
{
this.provider = provider;
this.maxIterations = maxIterations;
}
private PKMacBuilder(AlgorithmIdentifier digestAlgorithmIdentifier, int iterationCount, AlgorithmIdentifier macAlgorithmIdentifier, IPKMacPrimitivesProvider provider)
{
this.iterationCount = iterationCount;
mac = macAlgorithmIdentifier;
owf = digestAlgorithmIdentifier;
this.provider = provider;
}
public PKMacBuilder SetSaltLength(int saltLength)
{
if (saltLength < 8)
{
throw new ArgumentException("salt length must be at least 8 bytes");
}
this.saltLength = saltLength;
return this;
}
public PKMacBuilder SetIterationCount(int iterationCount)
{
if (iterationCount < 100)
{
throw new ArgumentException("iteration count must be at least 100");
}
CheckIterationCountCeiling(iterationCount);
this.iterationCount = iterationCount;
return this;
}
public PKMacBuilder SetParameters(PbmParameter parameters)
{
CheckIterationCountCeiling(parameters.IterationCount.Value.IntValue);
this.parameters = parameters;
return this;
}
public PKMacBuilder SetSecureRandom(SecureRandom random)
{
this.random = random;
return this;
}
public IMacFactory Build(char[] password)
{
if (parameters != null)
{
return GenCalculator(parameters, password);
}
byte[] buffer = new byte[saltLength];
if (random == null)
{
random = new SecureRandom();
}
random.NextBytes(buffer);
return GenCalculator(new PbmParameter(buffer, owf, iterationCount, mac), password);
}
private void CheckIterationCountCeiling(int iterationCount)
{
if (maxIterations > 0 && iterationCount > maxIterations)
{
throw new ArgumentException("iteration count exceeds limit (" + iterationCount + " > " + maxIterations + ")");
}
}
private IMacFactory GenCalculator(PbmParameter parameters, char[] password)
{
byte[] array = Strings.ToUtf8ByteArray(password);
byte[] octets = parameters.Salt.GetOctets();
byte[] array2 = new byte[array.Length + octets.Length];
Array.Copy(array, 0, array2, 0, array.Length);
Array.Copy(octets, 0, array2, array.Length, octets.Length);
IDigest digest = provider.CreateDigest(parameters.Owf);
int num = parameters.IterationCount.Value.IntValue;
digest.BlockUpdate(array2, 0, array2.Length);
array2 = new byte[digest.GetDigestSize()];
digest.DoFinal(array2, 0);
while (--num > 0)
{
digest.BlockUpdate(array2, 0, array2.Length);
digest.DoFinal(array2, 0);
}
byte[] key = array2;
return new PKMacFactory(key, parameters);
}
}

View File

@@ -0,0 +1,30 @@
using Org.BouncyCastle.Asn1.Cmp;
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.Crmf;
internal class PKMacFactory : IMacFactory
{
protected readonly PbmParameter parameters;
private readonly byte[] key;
public virtual object AlgorithmDetails => new AlgorithmIdentifier(CmpObjectIdentifiers.passwordBasedMac, parameters);
public PKMacFactory(byte[] key, PbmParameter parameters)
{
this.key = Arrays.Clone(key);
this.parameters = parameters;
}
public virtual IStreamCalculator CreateCalculator()
{
IMac mac = MacUtilities.GetMac(parameters.Mac.Algorithm);
mac.Init(new KeyParameter(key));
return new PKMacStreamCalculator(mac);
}
}

View File

@@ -0,0 +1,22 @@
using System.IO;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.IO;
namespace Org.BouncyCastle.Crmf;
internal class PKMacStreamCalculator : IStreamCalculator
{
private readonly MacSink _stream;
public Stream Stream => _stream;
public PKMacStreamCalculator(IMac mac)
{
_stream = new MacSink(mac);
}
public object GetResult()
{
return new DefaultPKMacResult(_stream.Mac);
}
}

View File

@@ -0,0 +1,58 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Cms;
namespace Org.BouncyCastle.Crmf;
public class PkiArchiveControl : IControl
{
public static readonly int encryptedPrivKey = 0;
public static readonly int keyGenParameters = 1;
public static readonly int archiveRemGenPrivKey = 2;
private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions;
private readonly PkiArchiveOptions pkiArchiveOptions;
public DerObjectIdentifier Type => type;
public Asn1Encodable Value => pkiArchiveOptions;
public int ArchiveType => pkiArchiveOptions.Type;
public bool EnvelopedData
{
get
{
EncryptedKey instance = EncryptedKey.GetInstance(pkiArchiveOptions.Value);
return !instance.IsEncryptedValue;
}
}
public PkiArchiveControl(PkiArchiveOptions pkiArchiveOptions)
{
this.pkiArchiveOptions = pkiArchiveOptions;
}
public CmsEnvelopedData GetEnvelopedData()
{
try
{
EncryptedKey instance = EncryptedKey.GetInstance(pkiArchiveOptions.Value);
EnvelopedData instance2 = Org.BouncyCastle.Asn1.Cms.EnvelopedData.GetInstance(instance.Value);
return new CmsEnvelopedData(new ContentInfo(CmsObjectIdentifiers.EnvelopedData, instance2));
}
catch (CmsException ex)
{
throw new CrmfException("CMS parsing error: " + ex.Message, ex);
}
catch (Exception ex2)
{
throw new CrmfException("CRMF parsing error: " + ex2.Message, ex2);
}
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.IO;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Cms;
using Org.BouncyCastle.Crypto;
namespace Org.BouncyCastle.Crmf;
public class PkiArchiveControlBuilder
{
private CmsEnvelopedDataGenerator envGen;
private CmsProcessableByteArray keyContent;
public PkiArchiveControlBuilder(PrivateKeyInfo privateKeyInfo, GeneralName generalName)
{
EncKeyWithID encKeyWithID = new EncKeyWithID(privateKeyInfo, generalName);
try
{
keyContent = new CmsProcessableByteArray(CrmfObjectIdentifiers.id_ct_encKeyWithID, encKeyWithID.GetEncoded());
}
catch (IOException innerException)
{
throw new InvalidOperationException("unable to encode key and general name info", innerException);
}
envGen = new CmsEnvelopedDataGenerator();
}
public PkiArchiveControlBuilder AddRecipientGenerator(RecipientInfoGenerator recipientGen)
{
envGen.AddRecipientInfoGenerator(recipientGen);
return this;
}
public PkiArchiveControl Build(ICipherBuilderWithKey contentEncryptor)
{
CmsEnvelopedData cmsEnvelopedData = envGen.Generate(keyContent, contentEncryptor);
EnvelopedData instance = EnvelopedData.GetInstance(cmsEnvelopedData.ContentInfo.Content);
return new PkiArchiveControl(new PkiArchiveOptions(new EncryptedKey(instance)));
}
}

View File

@@ -0,0 +1,79 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Operators;
namespace Org.BouncyCastle.Crmf;
public class ProofOfPossessionSigningKeyBuilder
{
private CertRequest _certRequest;
private SubjectPublicKeyInfo _pubKeyInfo;
private GeneralName _name;
private PKMacValue _publicKeyMAC;
public ProofOfPossessionSigningKeyBuilder(CertRequest certRequest)
{
_certRequest = certRequest;
}
public ProofOfPossessionSigningKeyBuilder(SubjectPublicKeyInfo pubKeyInfo)
{
_pubKeyInfo = pubKeyInfo;
}
public ProofOfPossessionSigningKeyBuilder SetSender(GeneralName name)
{
_name = name;
return this;
}
public ProofOfPossessionSigningKeyBuilder SetPublicKeyMac(PKMacBuilder generator, char[] password)
{
IMacFactory macFactory = generator.Build(password);
IStreamCalculator streamCalculator = macFactory.CreateCalculator();
byte[] derEncoded = _pubKeyInfo.GetDerEncoded();
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
streamCalculator.Stream.Flush();
streamCalculator.Stream.Close();
_publicKeyMAC = new PKMacValue((AlgorithmIdentifier)macFactory.AlgorithmDetails, new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect()));
return this;
}
public PopoSigningKey Build(ISignatureFactory signer)
{
if (_name != null && _publicKeyMAC != null)
{
throw new InvalidOperationException("name and publicKeyMAC cannot both be set.");
}
IStreamCalculator streamCalculator = signer.CreateCalculator();
PopoSigningKeyInput popoSigningKeyInput;
if (_certRequest != null)
{
popoSigningKeyInput = null;
byte[] derEncoded = _certRequest.GetDerEncoded();
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
}
else if (_name != null)
{
popoSigningKeyInput = new PopoSigningKeyInput(_name, _pubKeyInfo);
byte[] derEncoded = popoSigningKeyInput.GetDerEncoded();
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
}
else
{
popoSigningKeyInput = new PopoSigningKeyInput(_publicKeyMAC, _pubKeyInfo);
byte[] derEncoded = popoSigningKeyInput.GetDerEncoded();
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
}
streamCalculator.Stream.Flush();
streamCalculator.Stream.Close();
DefaultSignatureResult defaultSignatureResult = (DefaultSignatureResult)streamCalculator.GetResult();
return new PopoSigningKey(popoSigningKeyInput, (AlgorithmIdentifier)signer.AlgorithmDetails, new DerBitString(defaultSignatureResult.Collect()));
}
}

View File

@@ -0,0 +1,25 @@
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
namespace Org.BouncyCastle.Crmf;
public class RegTokenControl : IControl
{
private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_regToken;
private readonly DerUtf8String token;
public DerObjectIdentifier Type => type;
public Asn1Encodable Value => token;
public RegTokenControl(DerUtf8String token)
{
this.token = token;
}
public RegTokenControl(string token)
{
this.token = new DerUtf8String(token);
}
}