diff --git a/crypto/src/asn1/cmp/GeneralPKIMessage.cs b/crypto/src/cmp/GeneralPkiMessage.cs
index d91b8ef7e..d91b8ef7e 100644
--- a/crypto/src/asn1/cmp/GeneralPKIMessage.cs
+++ b/crypto/src/cmp/GeneralPkiMessage.cs
diff --git a/crypto/src/asn1/cmp/ProtectedPkiMessage.cs b/crypto/src/cmp/ProtectedPkiMessage.cs
index c39f06ad0..159f08722 100644
--- a/crypto/src/asn1/cmp/ProtectedPkiMessage.cs
+++ b/crypto/src/cmp/ProtectedPkiMessage.cs
@@ -3,6 +3,8 @@ using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.Text;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
@@ -10,8 +12,9 @@ using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Crmf;
-namespace Org.BouncyCastle.Asn1.Cmp
+namespace Org.BouncyCastle.Cmp
{
public class ProtectedPkiMessage
@@ -64,29 +67,31 @@ namespace Org.BouncyCastle.Asn1.Cmp
return res;
}
-
-
+ public bool Verify(IVerifierFactory verifierFactory)
+ {
+ IStreamCalculator streamCalculator = verifierFactory.CreateCalculator();
+
+ IVerifier result = (IVerifier)Process(streamCalculator);
+
+ return result.IsVerified(pkiMessage.Protection.GetBytes());
+ }
- public bool Verify(IVerifierFactory verifier)
+ private Object Process(IStreamCalculator streamCalculator)
{
Asn1EncodableVector avec = new Asn1EncodableVector();
avec.Add(pkiMessage.Header);
avec.Add(pkiMessage.Body);
byte[] enc = new DerSequence(avec).GetDerEncoded();
- IStreamCalculator streamCalculator = verifier.CreateCalculator();
-
streamCalculator.Stream.Write(enc,0,enc.Length);
streamCalculator.Stream.Flush();
streamCalculator.Stream.Close();
- IVerifier result = (IVerifier) streamCalculator.GetResult();
- return result.IsVerified(pkiMessage.Protection.GetBytes());
+ return streamCalculator.GetResult();
}
-
- public bool Verify(Asn1MacFactoryProvider asn1Factory, byte[] password)
+ public bool Verify(PKMacBuilder pkMacBuilder, char[] password)
{
if (!CmpObjectIdentifiers.passwordBasedMac.Equals(pkiMessage.Header.ProtectionAlg.Algorithm))
{
@@ -95,13 +100,11 @@ namespace Org.BouncyCastle.Asn1.Cmp
PbmParameter parameter = PbmParameter.GetInstance(pkiMessage.Header.ProtectionAlg.Parameters);
- PkMacFactory macFactory = (PkMacFactory)asn1Factory.CreateMacFactory(parameter);
-
- macFactory.Password = password;
- MacVerifierFactory macVerifierFactory = new MacVerifierFactory(macFactory);
+ pkMacBuilder.SetParameters(parameter);
- return Verify(macVerifierFactory);
- }
+ IBlockResult result = (IBlockResult)Process(pkMacBuilder.Build(password).CreateCalculator());
+ return Arrays.ConstantTimeAreEqual(result.Collect(), this.pkiMessage.Protection.GetBytes());
+ }
}
}
diff --git a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
index 22a004669..e660f844a 100644
--- a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
+++ b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
@@ -1,11 +1,13 @@
using System;
using System.Collections;
+using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Crmf;
namespace Org.BouncyCastle.Cmp
{
@@ -153,14 +155,13 @@ namespace Org.BouncyCastle.Cmp
signer.Stream.Write(encoded, 0, encoded.Length);
Object result = signer.GetResult();
-
if (result is DefaultSignatureResult)
{
- return ((DefaultSignatureResult) result).Collect();
+ return ((DefaultSignatureResult)result).Collect();
}
- else if (result is DefaultMacAndDigestResult)
+ else if (result is IBlockResult)
{
- return ((DefaultMacAndDigestResult) result).MacResult;
+ return ((IBlockResult)result).Collect();
}
else if (result is byte[])
{
diff --git a/crypto/src/crmf/CertificateRequestMessageBuilder.cs b/crypto/src/crmf/CertificateRequestMessageBuilder.cs
index 10a575abe..384f6a965 100644
--- a/crypto/src/crmf/CertificateRequestMessageBuilder.cs
+++ b/crypto/src/crmf/CertificateRequestMessageBuilder.cs
@@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Crmf
private CertTemplateBuilder _templateBuilder;
private ArrayList _controls= new ArrayList();
private ISignatureFactory _popSigner;
- private PkMacFactory _pkMacBuilder;
+ private PKMacBuilder _pkMacBuilder;
private char[] _password;
private GeneralName _sender;
private int _popoType = ProofOfPossession.TYPE_KEY_ENCIPHERMENT;
@@ -161,7 +161,7 @@ namespace Org.BouncyCastle.Crmf
return this;
}
- public CertificateRequestMessageBuilder SetAuthInfoPKMAC(PkMacFactory pkmacFactory, char[] password)
+ public CertificateRequestMessageBuilder SetAuthInfoPKMAC(PKMacBuilder pkmacFactory, char[] password)
{
this._pkMacBuilder = pkmacFactory;
this._password = password;
diff --git a/crypto/src/crmf/DefaultPKMacPrimitivesProvider.cs b/crypto/src/crmf/DefaultPKMacPrimitivesProvider.cs
new file mode 100644
index 000000000..1757d6a92
--- /dev/null
+++ b/crypto/src/crmf/DefaultPKMacPrimitivesProvider.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Crypto.Parameters;
+
+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);
+ }
+ }
+}
diff --git a/crypto/src/crmf/IPKMacPrimitivesProvider.cs b/crypto/src/crmf/IPKMacPrimitivesProvider.cs
new file mode 100644
index 000000000..8b90be515
--- /dev/null
+++ b/crypto/src/crmf/IPKMacPrimitivesProvider.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cmp;
+using Org.BouncyCastle.Asn1.Iana;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto.IO;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Crypto;
+
+namespace Org.BouncyCastle.Crmf
+{
+ public interface IPKMacPrimitivesProvider
+ {
+ IDigest CreateDigest(AlgorithmIdentifier digestAlg);
+
+ IMac CreateMac(AlgorithmIdentifier macAlg);
+ }
+}
diff --git a/crypto/src/crmf/PKMacBuilder.cs b/crypto/src/crmf/PKMacBuilder.cs
new file mode 100644
index 000000000..5e3a5844d
--- /dev/null
+++ b/crypto/src/crmf/PKMacBuilder.cs
@@ -0,0 +1,256 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cmp;
+using Org.BouncyCastle.Asn1.Iana;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Cms;
+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.Encoders;
+
+
+namespace Org.BouncyCastle.Crmf
+{
+
+ class PKMacStreamCalculator : IStreamCalculator
+ {
+ private readonly MacSink _stream;
+
+ public PKMacStreamCalculator(IMac mac)
+ {
+ _stream = new MacSink(mac);
+ }
+
+ public Stream Stream
+ {
+ get { return _stream; }
+ }
+
+ public object GetResult()
+ {
+ return new DefaultPKMacResult(_stream.Mac);
+ }
+ }
+
+ class PKMacFactory : IMacFactory
+ {
+ protected readonly PbmParameter parameters;
+ private byte[] key;
+
+
+ public PKMacFactory(byte[] key, PbmParameter parameters)
+ {
+ this.key = Arrays.Clone(key);
+
+ this.parameters = parameters;
+ }
+
+ public virtual object AlgorithmDetails
+ {
+ get { return new AlgorithmIdentifier(CmpObjectIdentifiers.passwordBasedMac, parameters); }
+ }
+
+ public virtual IStreamCalculator CreateCalculator()
+ {
+ IMac mac = MacUtilities.GetMac(parameters.Mac.Algorithm);
+
+ mac.Init(new KeyParameter(key));
+
+ return new PKMacStreamCalculator(mac);
+ }
+ }
+
+ class DefaultPKMacResult: IBlockResult
+ {
+ private readonly IMac mac;
+
+ public DefaultPKMacResult(IMac mac)
+ {
+ this.mac = mac;
+ }
+
+ public byte[] Collect()
+ {
+ byte[] res = new byte[mac.GetMacSize()];
+
+ mac.DoFinal(res, 0);
+
+ return res;
+ }
+
+ public int Collect(byte[] sig, int sigOff)
+ {
+ byte[] signature = Collect();
+ signature.CopyTo(sig, sigOff);
+ return signature.Length;
+ }
+ }
+
+ 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, int maxIterations)
+ {
+ this.provider = provider;
+ this.maxIterations = maxIterations;
+ }
+
+ private PKMacBuilder(AlgorithmIdentifier digestAlgorithmIdentifier, int iterationCount, AlgorithmIdentifier macAlgorithmIdentifier, IPKMacPrimitivesProvider provider)
+ {
+ this.iterationCount = iterationCount;
+ this.mac = macAlgorithmIdentifier;
+ this.owf = digestAlgorithmIdentifier;
+ this.provider = provider;
+ }
+
+ /**
+ * Set the salt length in octets.
+ *
+ * @param saltLength length in octets of the salt to be generated.
+ * @return the generator
+ */
+ 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);
+ }
+ else
+ {
+ byte[] salt = new byte[saltLength];
+
+ if (random == null)
+ {
+ this.random = new SecureRandom();
+ }
+
+ random.NextBytes(salt);
+
+ return genCalculator(new PbmParameter(salt, 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)
+ {
+ // From RFC 4211
+ //
+ // 1. Generate a random salt value S
+ //
+ // 2. Append the salt to the pw. K = pw || salt.
+ //
+ // 3. Hash the value of K. K = HASH(K)
+ //
+ // 4. Iter = Iter - 1. If Iter is greater than zero. Goto step 3.
+ //
+ // 5. Compute an HMAC as documented in [HMAC].
+ //
+ // MAC = HASH( K XOR opad, HASH( K XOR ipad, data) )
+ //
+ // Where opad and ipad are defined in [HMAC].
+ byte[] pw = Strings.ToUtf8ByteArray(password);
+ byte[] salt = parameters.Salt.GetOctets();
+ byte[] K = new byte[pw.Length + salt.Length];
+
+ System.Array.Copy(pw, 0, K, 0, pw.Length);
+ System.Array.Copy(salt, 0, K, pw.Length, salt.Length);
+
+ IDigest digest = provider.CreateDigest(parameters.Owf);
+
+ int iter = parameters.IterationCount.Value.IntValue;
+
+ digest.BlockUpdate(K, 0, K.Length);
+
+ K = new byte[digest.GetDigestSize()];
+
+ digest.DoFinal(K, 0);
+
+ while (--iter > 0)
+ {
+ digest.BlockUpdate(K, 0, K.Length);
+
+ digest.DoFinal(K, 0);
+ }
+
+ byte[] key = K;
+
+ return new PKMacFactory(key, parameters);
+ }
+ }
+}
diff --git a/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs b/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs
new file mode 100644
index 000000000..8457585ff
--- /dev/null
+++ b/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Crmf;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Crypto.Paddings;
+
+namespace Org.BouncyCastle.Crmf
+{
+ public class ProofOfPossessionSigningKeyBuilder
+ {
+ private CertRequest _certRequest;
+ private SubjectPublicKeyInfo _pubKeyInfo;
+ private GeneralName _name;
+ private PKMacValue _publicKeyMAC;
+
+ public ProofOfPossessionSigningKeyBuilder(CertRequest certRequest)
+ {
+ this._certRequest = certRequest;
+ }
+
+ public ProofOfPossessionSigningKeyBuilder(SubjectPublicKeyInfo pubKeyInfo)
+ {
+ this._pubKeyInfo = pubKeyInfo;
+ }
+
+ public ProofOfPossessionSigningKeyBuilder setSender(GeneralName name)
+ {
+ this._name = name;
+
+ return this;
+ }
+
+ public ProofOfPossessionSigningKeyBuilder setPublicKeyMac(PKMacBuilder generator, char[] password)
+ {
+ IMacFactory fact = generator.Build(password);
+
+ IStreamCalculator calc = fact.CreateCalculator();
+ byte[] d = _pubKeyInfo.GetDerEncoded();
+ calc.Stream.Write(d, 0, d.Length);
+ calc.Stream.Flush();
+ calc.Stream.Close();
+
+ this._publicKeyMAC = new PKMacValue(
+ (AlgorithmIdentifier)fact.AlgorithmDetails,
+ new DerBitString(((IBlockResult)calc.GetResult()).Collect()));
+
+ return this;
+ }
+
+ public PopoSigningKey build(ISignatureFactory signer)
+ {
+ if (_name != null && _publicKeyMAC != null)
+ {
+ throw new InvalidOperationException("name and publicKeyMAC cannot both be set.");
+ }
+
+ PopoSigningKeyInput popo;
+ byte[] b;
+ IStreamCalculator calc = signer.CreateCalculator();
+ if (_certRequest != null)
+ {
+ popo = null;
+ b = _certRequest.GetDerEncoded();
+ calc.Stream.Write(b, 0, b.Length);
+
+ }
+ else if (_name != null)
+ {
+ popo = new PopoSigningKeyInput(_name, _pubKeyInfo);
+ b = popo.GetDerEncoded();
+ calc.Stream.Write(b, 0, b.Length);
+ }
+ else
+ {
+ popo = new PopoSigningKeyInput(_publicKeyMAC, _pubKeyInfo);
+ b = popo.GetDerEncoded();
+ calc.Stream.Write(b, 0, b.Length);
+ }
+
+ calc.Stream.Flush();
+ calc.Stream.Close();
+ DefaultSignatureResult res = (DefaultSignatureResult)calc.GetResult();
+ return new PopoSigningKey(popo, (AlgorithmIdentifier)signer.AlgorithmDetails, new DerBitString(res.Collect()));
+ }
+ }
+}
diff --git a/crypto/src/crypto/operators/Asn1Mac.cs b/crypto/src/crypto/operators/Asn1Mac.cs
deleted file mode 100644
index ff70e5849..000000000
--- a/crypto/src/crypto/operators/Asn1Mac.cs
+++ /dev/null
@@ -1,410 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.Cmp;
-using Org.BouncyCastle.Asn1.Iana;
-using Org.BouncyCastle.Asn1.Nist;
-using Org.BouncyCastle.Asn1.Oiw;
-using Org.BouncyCastle.Asn1.Pkcs;
-using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Cms;
-using Org.BouncyCastle.Crypto.IO;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Encoders;
-
-namespace Org.BouncyCastle.Crypto.Operators
-{
-
- public class DefaultMacStreamCalculator : IStreamCalculator
- {
- private readonly MacSink _stream;
-
- public DefaultMacStreamCalculator(IMac mac)
- {
- _stream = new MacSink(mac);
- }
-
- public void Init(KeyParameter key)
- {
- _stream.Mac.Init(key);
- }
-
- public Stream Stream
- {
- get { return _stream; }
- }
- public object GetResult()
- {
- byte[] res = new byte[_stream.Mac.GetMacSize()];
- _stream.Mac.DoFinal(res, 0);
- return res;
- }
- }
-
-
- public class DefaultMacAndDigestStreamCalculator : IStreamCalculator
- {
-
- private readonly MacSink macSink;
- private readonly DigestSink digestSink;
- private readonly Stream _stream;
-
-
- public DefaultMacAndDigestStreamCalculator(IMac imac, IDigest idigest)
- {
- this.macSink = new MacSink(imac);
- this.digestSink = new DigestSink(idigest);
- _stream = new MergedStream(macSink,digestSink);
- }
-
-
- public void Init(KeyParameter macKey)
- {
- this.macSink.Mac.Init(macKey);
- }
-
- public void Init(PbmParameter parameter, byte[] password)
- {
-
- byte[] pw = password;
- byte[] salt = parameter.Salt.GetOctets();
- byte[] K = new byte[pw.Length + salt.Length];
-
- System.Array.Copy(pw,K,pw.Length);
- System.Array.Copy(salt,0,K,pw.Length,salt.Length);
- int iter = parameter.IterationCount.Value.IntValue;
- this.digestSink.Digest.Reset();
-
- IDigest dig = DigestUtilities.GetDigest(digestSink.Digest.AlgorithmName);
-
-
-
- dig.BlockUpdate(K,0,K.Length);
- K = new byte[dig.GetDigestSize()];
- dig.DoFinal(K, 0);
- iter--;
-
- do
- {
- dig.BlockUpdate(K,0,K.Length);
- dig.DoFinal(K, 0);
- } while (--iter > 0);
-
- macSink.Mac.Init(new KeyParameter(K));
- }
-
-
-
- public Stream Stream
- {
- get { return _stream; }
- }
-
-
- public object GetResult()
- {
- byte[] macResult = new byte[macSink.Mac.GetMacSize()];
- macSink.Mac.DoFinal(macResult, 0);
- byte[] digestResult = new byte[digestSink.Digest.GetByteLength()];
- digestSink.Digest.DoFinal(digestResult, 0);
- return new DefaultMacAndDigestResult(digestResult, macResult);
- }
-
- private class MergedStream : Stream
- {
-
- private Stream aStream;
- private Stream bStream;
-
- public MergedStream(Stream aStream, Stream bStream)
- {
- this.aStream = aStream;
- this.bStream = bStream;
- }
-
- public override void Flush()
- {
- aStream.Flush();
- bStream.Flush();
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- aStream.Seek(offset, origin);
- return bStream.Seek(offset, origin);
- }
-
- public override void SetLength(long value)
- {
- aStream.SetLength(value);
- bStream.SetLength(value);
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- aStream.Read(buffer, offset, count);
- return bStream.Read(buffer, offset, count);
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- aStream.Write(buffer, offset, count);
- bStream.Write(buffer, offset, count);
- }
-
- public override bool CanRead
- {
- get { return bStream.CanRead && aStream.CanRead; }
- }
- public override bool CanSeek
- {
- get { return bStream.CanSeek && aStream.CanSeek; }
-
- }
- public override bool CanWrite {
- get { return bStream.CanWrite && aStream.CanWrite; }
-
- }
- public override long Length {
- get
- {
- return aStream.Length;
- }
- }
- public override long Position
- {
- get { return aStream.Position; }
-
- set { aStream.Position = value; }
- }
- }
- }
-
- public struct DefaultMacAndDigestResult
- {
- public DefaultMacAndDigestResult(byte[] digestResult, byte[] macResult)
- {
- DigestResult = digestResult;
- MacResult = macResult;
- }
-
- public byte[] DigestResult { get; }
-
- public byte[] MacResult { get; }
- }
-
- public class Asn1MacFactory : IMacFactory
- {
- protected readonly AlgorithmIdentifier MacAlgorithmIdentifier;
-
-
-
- public Asn1MacFactory(AlgorithmIdentifier macAlgorithmIdentifier)
- {
- MacAlgorithmIdentifier = macAlgorithmIdentifier;
- }
-
-
-
- public virtual object AlgorithmDetails
- {
- get { return MacAlgorithmIdentifier; }
- }
-
- public virtual IStreamCalculator CreateCalculator()
- {
- IMac mac = MacUtilities.GetMac(MacAlgorithmIdentifier.Algorithm);
- return new DefaultMacStreamCalculator(mac);
- }
- }
-
-
- public interface IMacFactoryProvider
- {
- IMacFactory CreateMacFactory(AlgorithmIdentifier algorithmIdentifier);
- }
-
- public class Asn1MacFactoryProvider : IMacFactoryProvider
- {
- public IMacFactory CreateMacFactory(AlgorithmIdentifier algorithmIdentifier)
- {
- return new Asn1MacFactory(algorithmIdentifier);
- }
-
- public IMacFactory CreateMacFactory(AlgorithmIdentifier digestAlgorithmIdentifier, AlgorithmIdentifier macAlgorithmIdentifier)
- {
- return new PkMacFactory(digestAlgorithmIdentifier,macAlgorithmIdentifier);
- }
-
- public IMacFactory CreateMacFactory(PbmParameter parameter)
- {
- return new PkMacFactory(parameter);
- }
-
- }
-
-
-
- public class PkMacFactory:Asn1MacFactory
- {
- private readonly AlgorithmIdentifier _digestAlgorithmIdentifier;
- private byte[] password;
- private int iterationCount;
- private byte[] salt;
-
-
-
- public PkMacFactory(SecureRandom random) : base(new AlgorithmIdentifier(IanaObjectIdentifiers.HmacSha1))
- {
- this._digestAlgorithmIdentifier = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
- this.iterationCount = 1000;
- this.salt = new byte[20];
- random.NextBytes(salt);
- }
-
- public PkMacFactory(AlgorithmIdentifier digestAlgorithmIdentifier, AlgorithmIdentifier macAlgorithmIdentifier) : base(macAlgorithmIdentifier)
- {
- this._digestAlgorithmIdentifier = digestAlgorithmIdentifier;
- }
-
- public PkMacFactory(PbmParameter parameter):base(parameter.Mac)
- {
- this._digestAlgorithmIdentifier = parameter.Owf;
- this.salt = parameter.Salt.GetOctets();
- this.iterationCount = parameter.IterationCount.Value.IntValue;
- }
-
- public override object AlgorithmDetails
- {
- get
- {
- return new AlgorithmIdentifier(CmpObjectIdentifiers.passwordBasedMac,
- new PbmParameter(salt, _digestAlgorithmIdentifier, iterationCount, MacAlgorithmIdentifier));
- }
- }
-
-
- public int IterationCount
- {
- set { this.iterationCount = value; }
- }
- public byte[] Salt
- {
- set { this.salt = value;}
- }
- public byte[] Password {
- set { this.password = value; }
- }
-
-
- public override IStreamCalculator CreateCalculator()
- {
-
- DefaultMacAndDigestStreamCalculator calc = new DefaultMacAndDigestStreamCalculator(
- MacUtilities.GetMac(this.MacAlgorithmIdentifier.Algorithm),
- DigestUtilities.GetDigest(_digestAlgorithmIdentifier.Algorithm));
-
- PbmParameter parameter = new PbmParameter(salt, _digestAlgorithmIdentifier,iterationCount,MacAlgorithmIdentifier);
- calc.Init(parameter, password);
-
-
- return calc;
- }
-
- }
-
-
- public class MacVerifierFactory : IVerifierFactory
- {
- private readonly IMacFactory _macFactory;
-
-
- public MacVerifierFactory(IMacFactory macFactory)
- {
- this._macFactory = macFactory;
- }
-
- public object AlgorithmDetails
- {
- get { return _macFactory.AlgorithmDetails; }
- }
- public IStreamCalculator CreateCalculator()
- {
- return new MacVerifier(_macFactory.CreateCalculator());
- }
-
- private class MacVerifier : IStreamCalculator
- {
- public IStreamCalculator _calculator;
-
- public MacVerifier(IStreamCalculator calculator)
- {
- _calculator = calculator;
- }
-
- public Stream Stream
- {
- get { return _calculator.Stream; }
- }
-
- public object GetResult()
- {
- object result = _calculator.GetResult();
- if (result is byte[])
- {
- return new DefaultMacVerifierResult((byte[])result);
- } else if (result is DefaultMacAndDigestResult)
- {
- return new DefaultMacVerifierResult(((DefaultMacAndDigestResult)result).MacResult);
-
- }
-
- throw new InvalidOperationException("calculator did not return byte[] or DefaultMacVerifierResult");
- }
- }
-
- }
-
-
- public class DefaultMacVerifierResult:IVerifier
- {
- private readonly byte[] _calculatedResult;
-
- public DefaultMacVerifierResult(byte[] calculatedResult)
- {
- this._calculatedResult = calculatedResult;
- }
-
-
- public bool IsVerified(byte[] data)
- {
- return Arrays.ConstantTimeAreEqual(_calculatedResult, data);
- }
-
- public bool IsVerified(byte[] source, int off, int length)
- {
- if (_calculatedResult.Length != length)
- {
- return false;
- }
-
- //
- // Must be constant time.
- //
- int j = 0;
- int nonEqual = 0;
- for (int i = off; i < off + length; i++)
- {
- nonEqual |= (_calculatedResult[j++] ^ source[i]);
- }
-
- return nonEqual == 0;
- }
- }
-
-
-}
|