1
mirror of https://github.com/carlospolop/PEASS-ng synced 2024-11-24 01:26:22 +01:00

- added saved password extraction for: Opera, Firefox, Chrome

This commit is contained in:
makikvues 2021-01-28 10:19:27 +01:00
parent 27e8867236
commit 977e183068
282 changed files with 134704 additions and 32 deletions

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle
{
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class CryptoException
: Exception
{
public CryptoException()
{
}
public CryptoException(
string message)
: base(message)
{
}
public CryptoException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle
{
/**
* this exception is thrown if a buffer that is meant to have output
* copied into it turns out to be too short, or if we've been given
* insufficient input. In general this exception will Get thrown rather
* than an ArrayOutOfBounds exception.
*/
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class DataLengthException
: CryptoException
{
/**
* base constructor.
*/
public DataLengthException()
{
}
/**
* create a DataLengthException with the given message.
*
* @param message the message to be carried with the exception.
*/
public DataLengthException(
string message)
: base(message)
{
}
public DataLengthException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@ -0,0 +1,6 @@
namespace BrowserPass.BouncyCastle
{
public interface ICipherParameters
{
}
}

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle
{
/**
* interface that a message digest conforms to.
*/
public interface IDigest
{
/**
* return the algorithm name
*
* @return the algorithm name
*/
string AlgorithmName { get; }
/**
* return the size, in bytes, of the digest produced by this message digest.
*
* @return the size, in bytes, of the digest produced by this message digest.
*/
int GetDigestSize();
/**
* return the size, in bytes, of the internal buffer used by this digest.
*
* @return the size, in bytes, of the internal buffer used by this digest.
*/
int GetByteLength();
/**
* update the message digest with a single byte.
*
* @param inByte the input byte to be entered.
*/
void Update(byte input);
/**
* update the message digest with a block of bytes.
*
* @param input the byte array containing the data.
* @param inOff the offset into the byte array where the data starts.
* @param len the length of the data.
*/
void BlockUpdate(byte[] input, int inOff, int length);
/**
* Close the digest, producing the final digest value. The doFinal
* call leaves the digest reset.
*
* @param output the array the digest is to be copied into.
* @param outOff the offset into the out array the digest is to start at.
*/
int DoFinal(byte[] output, int outOff);
/**
* reset the digest back to it's initial state.
*/
void Reset();
}
}

View File

@ -0,0 +1,30 @@
# The Bouncy Castle Crypto Package For C Sharp
The Bouncy Castle Crypto package is a C\# implementation of cryptographic algorithms and protocols, it was developed by the Legion of the Bouncy Castle, a registered Australian Charity, with a little help! The Legion, and the latest goings on with this package, can be found at [https://www.bouncycastle.org](https://www.bouncycastle.org). In addition to providing basic cryptography algorithms, the package also provides support for CMS, TSP, X.509 certificate generation and a variety of other standards such as OpenPGP.
The Legion also gratefully acknowledges the contributions made to this package by others (see [here](https://www.bouncycastle.org/csharp/contributors.html) for the current list). If you would like to contribute to our efforts please feel free to get in touch with us or visit our [donations page](https://www.bouncycastle.org/donate), sponsor some specific work, or purchase a support contract through [Crypto Workshop](https://www.cryptoworkshop.com).
Except where otherwise stated, this software is distributed under a license based on the MIT X Consortium license. To view the license, [see here](https://www.bouncycastle.org/licence.html). The OpenPGP library also includes a modified BZIP2 library which is licensed under the [Apache Software License, Version 2.0](http://www.apache.org/licenses/).
**Note**: this source tree is not the FIPS version of the APIs - if you are interested in our FIPS version please contact us directly at [office@bouncycastle.org](mailto:office@bouncycastle.org).
## Mailing Lists
For those who are interested, there are 2 mailing lists for participation in this project. To subscribe use the links below and include the word subscribe in the message body. (To unsubscribe, replace **subscribe** with **unsubscribe** in the message body)
* [announce-crypto-csharp-request@bouncycastle.org](mailto:announce-crypto-csharp-request@bouncycastle.org)
This mailing list is for new release announcements only, general subscribers cannot post to it.
* [dev-crypto-csharp-request@bouncycastle.org](mailto:dev-crypto-csharp-request@bouncycastle.org)
This mailing list is for discussion of development of the package. This includes bugs, comments, requests for enhancements, questions about use or operation.
**NOTE:**You need to be subscribed to send mail to the above mailing list.
## Feedback
If you want to provide feedback directly to the members of **The Legion** then please use [feedback-crypto@bouncycastle.org](mailto:feedback-crypto@bouncycastle.org), if you want to help this project survive please consider [donating](https://www.bouncycastle.org/donate).
For bug reporting/requests you can report issues here on github, via feedback-crypto if required. We will accept pull requests based on this repository as well, but only on the basis that any code included may be distributed under the [Bouncy Castle License](https://www.bouncycastle.org/licence.html).
## Finally
Enjoy!

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public abstract class Asn1Encodable
: IAsn1Convertible
{
public const string Der = "DER";
public const string Ber = "BER";
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Asn1OutputStream aOut = new Asn1OutputStream(bOut);
aOut.WriteObject(this);
return bOut.ToArray();
}
public byte[] GetEncoded(
string encoding)
{
if (encoding.Equals(Der))
{
MemoryStream bOut = new MemoryStream();
DerOutputStream dOut = new DerOutputStream(bOut);
dOut.WriteObject(this);
return bOut.ToArray();
}
return GetEncoded();
}
/**
* Return the DER encoding of the object, null if the DER encoding can not be made.
*
* @return a DER byte array, null otherwise.
*/
public byte[] GetDerEncoded()
{
try
{
return GetEncoded(Der);
}
catch (IOException)
{
return null;
}
}
public sealed override int GetHashCode()
{
return ToAsn1Object().CallAsn1GetHashCode();
}
public sealed override bool Equals(
object obj)
{
if (obj == this)
return true;
IAsn1Convertible other = obj as IAsn1Convertible;
if (other == null)
return false;
Asn1Object o1 = ToAsn1Object();
Asn1Object o2 = other.ToAsn1Object();
return o1 == o2 || (null != o2 && o1.CallAsn1Equals(o2));
}
public abstract Asn1Object ToAsn1Object();
}
}

View File

@ -0,0 +1,195 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs.
*/
public class Asn1EncodableVector
: IEnumerable
{
internal static readonly Asn1Encodable[] EmptyElements = new Asn1Encodable[0];
private const int DefaultCapacity = 10;
private Asn1Encodable[] elements;
private int elementCount;
private bool copyOnWrite;
public static Asn1EncodableVector FromEnumerable(IEnumerable e)
{
Asn1EncodableVector v = new Asn1EncodableVector();
foreach (Asn1Encodable obj in e)
{
v.Add(obj);
}
return v;
}
public Asn1EncodableVector()
: this(DefaultCapacity)
{
}
public Asn1EncodableVector(int initialCapacity)
{
if (initialCapacity < 0)
throw new ArgumentException("must not be negative", "initialCapacity");
this.elements = (initialCapacity == 0) ? EmptyElements : new Asn1Encodable[initialCapacity];
this.elementCount = 0;
this.copyOnWrite = false;
}
public Asn1EncodableVector(params Asn1Encodable[] v)
: this()
{
Add(v);
}
public void Add(Asn1Encodable element)
{
if (null == element)
throw new ArgumentNullException("element");
int capacity = elements.Length;
int minCapacity = elementCount + 1;
if ((minCapacity > capacity) | copyOnWrite)
{
Reallocate(minCapacity);
}
this.elements[elementCount] = element;
this.elementCount = minCapacity;
}
public void Add(params Asn1Encodable[] objs)
{
foreach (Asn1Encodable obj in objs)
{
Add(obj);
}
}
public void AddOptional(params Asn1Encodable[] objs)
{
if (objs != null)
{
foreach (Asn1Encodable obj in objs)
{
if (obj != null)
{
Add(obj);
}
}
}
}
public void AddOptionalTagged(bool isExplicit, int tagNo, Asn1Encodable obj)
{
if (null != obj)
{
Add(new DerTaggedObject(isExplicit, tagNo, obj));
}
}
public void AddAll(Asn1EncodableVector other)
{
if (null == other)
throw new ArgumentNullException("other");
int otherElementCount = other.Count;
if (otherElementCount < 1)
return;
int capacity = elements.Length;
int minCapacity = elementCount + otherElementCount;
if ((minCapacity > capacity) | copyOnWrite)
{
Reallocate(minCapacity);
}
int i = 0;
do
{
Asn1Encodable otherElement = other[i];
if (null == otherElement)
throw new NullReferenceException("'other' elements cannot be null");
this.elements[elementCount + i] = otherElement;
}
while (++i < otherElementCount);
this.elementCount = minCapacity;
}
public Asn1Encodable this[int index]
{
get
{
if (index >= elementCount)
throw new IndexOutOfRangeException(index + " >= " + elementCount);
return elements[index];
}
}
public int Count
{
get { return elementCount; }
}
public IEnumerator GetEnumerator()
{
return CopyElements().GetEnumerator();
}
internal Asn1Encodable[] CopyElements()
{
if (0 == elementCount)
return EmptyElements;
Asn1Encodable[] copy = new Asn1Encodable[elementCount];
Array.Copy(elements, 0, copy, 0, elementCount);
return copy;
}
internal Asn1Encodable[] TakeElements()
{
if (0 == elementCount)
return EmptyElements;
if (elements.Length == elementCount)
{
this.copyOnWrite = true;
return elements;
}
Asn1Encodable[] copy = new Asn1Encodable[elementCount];
Array.Copy(elements, 0, copy, 0, elementCount);
return copy;
}
private void Reallocate(int minCapacity)
{
int oldCapacity = elements.Length;
int newCapacity = System.Math.Max(oldCapacity, minCapacity + (minCapacity >> 1));
Asn1Encodable[] copy = new Asn1Encodable[newCapacity];
Array.Copy(elements, 0, copy, 0, elementCount);
this.elements = copy;
this.copyOnWrite = false;
}
internal static Asn1Encodable[] CloneElements(Asn1Encodable[] elements)
{
return elements.Length < 1 ? EmptyElements : (Asn1Encodable[])elements.Clone();
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class Asn1Exception
: IOException
{
public Asn1Exception()
: base()
{
}
public Asn1Exception(
string message)
: base(message)
{
}
public Asn1Exception(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@ -0,0 +1,435 @@
using BrowserPass.BouncyCastle.asn1.util;
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util.io;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* a general purpose ASN.1 decoder - note: this class differs from the
* others in that it returns null after it has read the last object in
* the stream. If an ASN.1 Null is encountered a Der/BER Null object is
* returned.
*/
public class Asn1InputStream
: FilterStream
{
private readonly int limit;
private readonly byte[][] tmpBuffers;
internal static int FindLimit(Stream input)
{
if (input is LimitedInputStream)
return ((LimitedInputStream)input).Limit;
if (input is Asn1InputStream)
return ((Asn1InputStream)input).Limit;
if (input is MemoryStream)
{
MemoryStream mem = (MemoryStream)input;
return (int)(mem.Length - mem.Position);
}
return int.MaxValue;
}
public Asn1InputStream(
Stream inputStream)
: this(inputStream, FindLimit(inputStream))
{
}
/**
* Create an ASN1InputStream where no DER object will be longer than limit.
*
* @param input stream containing ASN.1 encoded data.
* @param limit maximum size of a DER encoded object.
*/
public Asn1InputStream(
Stream inputStream,
int limit)
: base(inputStream)
{
this.limit = limit;
this.tmpBuffers = new byte[16][];
}
/**
* Create an ASN1InputStream based on the input byte array. The length of DER objects in
* the stream is automatically limited to the length of the input array.
*
* @param input array containing ASN.1 encoded data.
*/
public Asn1InputStream(
byte[] input)
: this(new MemoryStream(input, false), input.Length)
{
}
/**
* build an object given its tag and the number of bytes to construct it from.
*/
private Asn1Object BuildObject(
int tag,
int tagNo,
int length)
{
bool isConstructed = (tag & Asn1Tags.Constructed) != 0;
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this.s, length, limit);
if ((tag & Asn1Tags.Application) != 0)
{
return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray());
}
if ((tag & Asn1Tags.Tagged) != 0)
{
return new Asn1StreamParser(defIn).ReadTaggedObject(isConstructed, tagNo);
}
if (isConstructed)
{
// TODO There are other tags that may be constructed (e.g. BitString)
switch (tagNo)
{
case Asn1Tags.OctetString:
{
//
// yes, people actually do this...
//
Asn1EncodableVector v = ReadVector(defIn);
Asn1OctetString[] strings = new Asn1OctetString[v.Count];
for (int i = 0; i != strings.Length; i++)
{
Asn1Encodable asn1Obj = v[i];
if (!(asn1Obj is Asn1OctetString))
{
throw new Asn1Exception("unknown object encountered in constructed OCTET STRING: "
+ Platform.GetTypeName(asn1Obj));
}
strings[i] = (Asn1OctetString)asn1Obj;
}
return new BerOctetString(strings);
}
case Asn1Tags.Sequence:
return CreateDerSequence(defIn);
case Asn1Tags.Set:
return CreateDerSet(defIn);
case Asn1Tags.External:
return new DerExternal(ReadVector(defIn));
default:
throw new IOException("unknown tag " + tagNo + " encountered");
}
}
return CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers);
}
internal virtual Asn1EncodableVector ReadVector(DefiniteLengthInputStream dIn)
{
if (dIn.Remaining < 1)
return new Asn1EncodableVector(0);
Asn1InputStream subStream = new Asn1InputStream(dIn);
Asn1EncodableVector v = new Asn1EncodableVector();
Asn1Object o;
while ((o = subStream.ReadObject()) != null)
{
v.Add(o);
}
return v;
}
internal virtual DerSequence CreateDerSequence(
DefiniteLengthInputStream dIn)
{
return DerSequence.FromVector(ReadVector(dIn));
}
internal virtual DerSet CreateDerSet(
DefiniteLengthInputStream dIn)
{
return DerSet.FromVector(ReadVector(dIn), false);
}
public Asn1Object ReadObject()
{
int tag = ReadByte();
if (tag <= 0)
{
if (tag == 0)
throw new IOException("unexpected end-of-contents marker");
return null;
}
//
// calculate tag number
//
int tagNo = ReadTagNumber(this.s, tag);
bool isConstructed = (tag & Asn1Tags.Constructed) != 0;
//
// calculate length
//
int length = ReadLength(this.s, limit, false);
if (length < 0) // indefinite-length method
{
if (!isConstructed)
throw new IOException("indefinite-length primitive encoding encountered");
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this.s, limit);
Asn1StreamParser sp = new Asn1StreamParser(indIn, limit);
if ((tag & Asn1Tags.Application) != 0)
{
return new BerApplicationSpecificParser(tagNo, sp).ToAsn1Object();
}
if ((tag & Asn1Tags.Tagged) != 0)
{
return new BerTaggedObjectParser(true, tagNo, sp).ToAsn1Object();
}
// TODO There are other tags that may be constructed (e.g. BitString)
switch (tagNo)
{
case Asn1Tags.OctetString:
return new BerOctetStringParser(sp).ToAsn1Object();
case Asn1Tags.Sequence:
return new BerSequenceParser(sp).ToAsn1Object();
case Asn1Tags.Set:
return new BerSetParser(sp).ToAsn1Object();
case Asn1Tags.External:
return new DerExternalParser(sp).ToAsn1Object();
default:
throw new IOException("unknown BER object encountered");
}
}
else
{
try
{
return BuildObject(tag, tagNo, length);
}
catch (ArgumentException e)
{
throw new Asn1Exception("corrupted stream detected", e);
}
}
}
internal virtual int Limit
{
get { return limit; }
}
internal static int ReadTagNumber(
Stream s,
int tag)
{
int tagNo = tag & 0x1f;
//
// with tagged object tag number is bottom 5 bits, or stored at the start of the content
//
if (tagNo == 0x1f)
{
tagNo = 0;
int b = s.ReadByte();
// X.690-0207 8.1.2.4.2
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
if ((b & 0x7f) == 0) // Note: -1 will pass
throw new IOException("corrupted stream - invalid high tag number found");
while ((b >= 0) && ((b & 0x80) != 0))
{
tagNo |= (b & 0x7f);
tagNo <<= 7;
b = s.ReadByte();
}
if (b < 0)
throw new EndOfStreamException("EOF found inside tag value.");
tagNo |= (b & 0x7f);
}
return tagNo;
}
internal static int ReadLength(Stream s, int limit, bool isParsing)
{
int length = s.ReadByte();
if (length < 0)
throw new EndOfStreamException("EOF found when length expected");
if (length == 0x80)
return -1; // indefinite-length encoding
if (length > 127)
{
int size = length & 0x7f;
// Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
if (size > 4)
throw new IOException("DER length more than 4 bytes: " + size);
length = 0;
for (int i = 0; i < size; i++)
{
int next = s.ReadByte();
if (next < 0)
throw new EndOfStreamException("EOF found reading length");
length = (length << 8) + next;
}
if (length < 0)
throw new IOException("corrupted stream - negative length found");
if (length >= limit && !isParsing) // after all we must have read at least 1 byte
throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
}
return length;
}
private static byte[] GetBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers)
{
int len = defIn.Remaining;
if (len >= tmpBuffers.Length)
{
return defIn.ToArray();
}
byte[] buf = tmpBuffers[len];
if (buf == null)
{
buf = tmpBuffers[len] = new byte[len];
}
defIn.ReadAllIntoByteArray(buf);
return buf;
}
private static char[] GetBmpCharBuffer(DefiniteLengthInputStream defIn)
{
int remainingBytes = defIn.Remaining;
if (0 != (remainingBytes & 1))
throw new IOException("malformed BMPString encoding encountered");
char[] str = new char[remainingBytes / 2];
int stringPos = 0;
byte[] buf = new byte[8];
while (remainingBytes >= 8)
{
if (Streams.ReadFully(defIn, buf, 0, 8) != 8)
throw new EndOfStreamException("EOF encountered in middle of BMPString");
str[stringPos] = (char)((buf[0] << 8) | (buf[1] & 0xFF));
str[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
str[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
str[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
stringPos += 4;
remainingBytes -= 8;
}
if (remainingBytes > 0)
{
if (Streams.ReadFully(defIn, buf, 0, remainingBytes) != remainingBytes)
throw new EndOfStreamException("EOF encountered in middle of BMPString");
int bufPos = 0;
do
{
int b1 = buf[bufPos++] << 8;
int b2 = buf[bufPos++] & 0xFF;
str[stringPos++] = (char)(b1 | b2);
}
while (bufPos < remainingBytes);
}
if (0 != defIn.Remaining || str.Length != stringPos)
throw new InvalidOperationException();
return str;
}
internal static Asn1Object CreatePrimitiveDerObject(
int tagNo,
DefiniteLengthInputStream defIn,
byte[][] tmpBuffers)
{
switch (tagNo)
{
case Asn1Tags.BmpString:
return new DerBmpString(GetBmpCharBuffer(defIn));
case Asn1Tags.Boolean:
return DerBoolean.FromOctetString(GetBuffer(defIn, tmpBuffers));
case Asn1Tags.Enumerated:
return DerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers));
case Asn1Tags.ObjectIdentifier:
return DerObjectIdentifier.FromOctetString(GetBuffer(defIn, tmpBuffers));
}
byte[] bytes = defIn.ToArray();
switch (tagNo)
{
case Asn1Tags.BitString:
return DerBitString.FromAsn1Octets(bytes);
case Asn1Tags.GeneralizedTime:
return new DerGeneralizedTime(bytes);
case Asn1Tags.GeneralString:
return new DerGeneralString(bytes);
case Asn1Tags.GraphicString:
return new DerGraphicString(bytes);
case Asn1Tags.IA5String:
return new DerIA5String(bytes);
case Asn1Tags.Integer:
return new DerInteger(bytes, false);
case Asn1Tags.Null:
return DerNull.Instance; // actual content is ignored (enforce 0 length?)
case Asn1Tags.NumericString:
return new DerNumericString(bytes);
case Asn1Tags.OctetString:
return new DerOctetString(bytes);
case Asn1Tags.PrintableString:
return new DerPrintableString(bytes);
case Asn1Tags.T61String:
return new DerT61String(bytes);
case Asn1Tags.UniversalString:
return new DerUniversalString(bytes);
case Asn1Tags.UtcTime:
return new DerUtcTime(bytes);
case Asn1Tags.Utf8String:
return new DerUtf8String(bytes);
case Asn1Tags.VideotexString:
return new DerVideotexString(bytes);
case Asn1Tags.VisibleString:
return new DerVisibleString(bytes);
default:
throw new IOException("unknown tag " + tagNo + " encountered");
}
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* A Null object.
*/
public abstract class Asn1Null
: Asn1Object
{
internal Asn1Null()
{
}
public override string ToString()
{
return "NULL";
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public abstract class Asn1Object
: Asn1Encodable
{
/// <summary>Create a base ASN.1 object from a byte array.</summary>
/// <param name="data">The byte array to parse.</param>
/// <returns>The base ASN.1 object represented by the byte array.</returns>
/// <exception cref="IOException">
/// If there is a problem parsing the data, or parsing an object did not exhaust the available data.
/// </exception>
public static Asn1Object FromByteArray(
byte[] data)
{
try
{
MemoryStream input = new MemoryStream(data, false);
Asn1InputStream asn1 = new Asn1InputStream(input, data.Length);
Asn1Object result = asn1.ReadObject();
if (input.Position != input.Length)
throw new IOException("extra data found after object");
return result;
}
catch (InvalidCastException)
{
throw new IOException("cannot recognise object in byte array");
}
}
/// <summary>Read a base ASN.1 object from a stream.</summary>
/// <param name="inStr">The stream to parse.</param>
/// <returns>The base ASN.1 object represented by the byte array.</returns>
/// <exception cref="IOException">If there is a problem parsing the data.</exception>
public static Asn1Object FromStream(
Stream inStr)
{
try
{
return new Asn1InputStream(inStr).ReadObject();
}
catch (InvalidCastException)
{
throw new IOException("cannot recognise object in stream");
}
}
public sealed override Asn1Object ToAsn1Object()
{
return this;
}
internal abstract void Encode(DerOutputStream derOut);
protected abstract bool Asn1Equals(Asn1Object asn1Object);
protected abstract int Asn1GetHashCode();
internal bool CallAsn1Equals(Asn1Object obj)
{
return Asn1Equals(obj);
}
internal int CallAsn1GetHashCode()
{
return Asn1GetHashCode();
}
}
}

View File

@ -0,0 +1,129 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util.encoders;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public abstract class Asn1OctetString
: Asn1Object, Asn1OctetStringParser
{
internal byte[] str;
/**
* return an Octet string from a tagged object.
*
* @param obj the tagged object holding the object we want.
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static Asn1OctetString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is Asn1OctetString)
{
return GetInstance(o);
}
return BerOctetString.FromSequence(Asn1Sequence.GetInstance(o));
}
/**
* return an Octet string from the given object.
*
* @param obj the object we want converted.
* @exception ArgumentException if the object cannot be converted.
*/
public static Asn1OctetString GetInstance(object obj)
{
if (obj == null || obj is Asn1OctetString)
{
return (Asn1OctetString)obj;
}
else if (obj is byte[])
{
try
{
return GetInstance(FromByteArray((byte[])obj));
}
catch (IOException e)
{
throw new ArgumentException("failed to construct OCTET STRING from byte[]: " + e.Message);
}
}
// TODO: this needs to be deleted in V2
else if (obj is Asn1TaggedObject)
{
return GetInstance(((Asn1TaggedObject)obj).GetObject());
}
else if (obj is Asn1Encodable)
{
Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object();
if (primitive is Asn1OctetString)
{
return (Asn1OctetString)primitive;
}
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* @param string the octets making up the octet string.
*/
internal Asn1OctetString(
byte[] str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public Stream GetOctetStream()
{
return new MemoryStream(str, false);
}
public Asn1OctetStringParser Parser
{
get { return this; }
}
public virtual byte[] GetOctets()
{
return str;
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerOctetString other = asn1Object as DerOctetString;
if (other == null)
return false;
return Arrays.AreEqual(GetOctets(), other.GetOctets());
}
public override string ToString()
{
return "#" + Hex.ToHexString(str);
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public interface Asn1OctetStringParser
: IAsn1Convertible
{
Stream GetOctetStream();
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class Asn1OutputStream
: DerOutputStream
{
public Asn1OutputStream(Stream os) : base(os)
{
}
[Obsolete("Use version taking an Asn1Encodable arg instead")]
public override void WriteObject(
object obj)
{
if (obj == null)
{
WriteNull();
}
else if (obj is Asn1Object)
{
((Asn1Object)obj).Encode(this);
}
else if (obj is Asn1Encodable)
{
((Asn1Encodable)obj).ToAsn1Object().Encode(this);
}
else
{
throw new IOException("object not Asn1Encodable");
}
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class Asn1ParsingException
: InvalidOperationException
{
public Asn1ParsingException()
: base()
{
}
public Asn1ParsingException(
string message)
: base(message)
{
}
public Asn1ParsingException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@ -0,0 +1,255 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util.collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public abstract class Asn1Sequence
: Asn1Object, IEnumerable
{
// NOTE: Only non-readonly to support LazyDerSequence
internal Asn1Encodable[] elements;
/**
* return an Asn1Sequence from the given object.
*
* @param obj the object we want converted.
* @exception ArgumentException if the object cannot be converted.
*/
public static Asn1Sequence GetInstance(
object obj)
{
if (obj == null || obj is Asn1Sequence)
{
return (Asn1Sequence)obj;
}
else if (obj is Asn1SequenceParser)
{
return GetInstance(((Asn1SequenceParser)obj).ToAsn1Object());
}
else if (obj is byte[])
{
try
{
return GetInstance(FromByteArray((byte[])obj));
}
catch (IOException e)
{
throw new ArgumentException("failed to construct sequence from byte[]: " + e.Message);
}
}
else if (obj is Asn1Encodable)
{
Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object();
if (primitive is Asn1Sequence)
{
return (Asn1Sequence)primitive;
}
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* Return an ASN1 sequence from a tagged object. There is a special
* case here, if an object appears to have been explicitly tagged on
* reading but we were expecting it to be implicitly tagged in the
* normal course of events it indicates that we lost the surrounding
* sequence - so we need to add it back (this will happen if the tagged
* object is a sequence that contains other sequences). If you are
* dealing with implicitly tagged sequences you really <b>should</b>
* be using this method.
*
* @param obj the tagged object.
* @param explicitly true if the object is meant to be explicitly tagged,
* false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static Asn1Sequence GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
Asn1Object inner = obj.GetObject();
if (explicitly)
{
if (!obj.IsExplicit())
throw new ArgumentException("object implicit - explicit expected.");
return (Asn1Sequence)inner;
}
//
// constructed object which appears to be explicitly tagged
// when it should be implicit means we have to add the
// surrounding sequence.
//
if (obj.IsExplicit())
{
if (obj is BerTaggedObject)
{
return new BerSequence(inner);
}
return new DerSequence(inner);
}
if (inner is Asn1Sequence)
{
return (Asn1Sequence)inner;
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
protected internal Asn1Sequence()
{
this.elements = Asn1EncodableVector.EmptyElements;
}
protected internal Asn1Sequence(Asn1Encodable element)
{
if (null == element)
throw new ArgumentNullException("element");
this.elements = new Asn1Encodable[] { element };
}
protected internal Asn1Sequence(params Asn1Encodable[] elements)
{
if (Arrays.IsNullOrContainsNull(elements))
throw new NullReferenceException("'elements' cannot be null, or contain null");
this.elements = Asn1EncodableVector.CloneElements(elements);
}
protected internal Asn1Sequence(Asn1EncodableVector elementVector)
{
if (null == elementVector)
throw new ArgumentNullException("elementVector");
this.elements = elementVector.TakeElements();
}
public virtual IEnumerator GetEnumerator()
{
return elements.GetEnumerator();
}
private class Asn1SequenceParserImpl
: Asn1SequenceParser
{
private readonly Asn1Sequence outer;
private readonly int max;
private int index;
public Asn1SequenceParserImpl(
Asn1Sequence outer)
{
this.outer = outer;
this.max = outer.Count;
}
public IAsn1Convertible ReadObject()
{
if (index == max)
return null;
Asn1Encodable obj = outer[index++];
if (obj is Asn1Sequence)
return ((Asn1Sequence)obj).Parser;
if (obj is Asn1Set)
return ((Asn1Set)obj).Parser;
// NB: Asn1OctetString implements Asn1OctetStringParser directly
// if (obj is Asn1OctetString)
// return ((Asn1OctetString)obj).Parser;
return obj;
}
public Asn1Object ToAsn1Object()
{
return outer;
}
}
public virtual Asn1SequenceParser Parser
{
get { return new Asn1SequenceParserImpl(this); }
}
/**
* return the object at the sequence position indicated by index.
*
* @param index the sequence number (starting at zero) of the object
* @return the object at the sequence position indicated by index.
*/
public virtual Asn1Encodable this[int index]
{
get { return elements[index]; }
}
public virtual int Count
{
get { return elements.Length; }
}
public virtual Asn1Encodable[] ToArray()
{
return Asn1EncodableVector.CloneElements(elements);
}
protected override int Asn1GetHashCode()
{
//return Arrays.GetHashCode(elements);
int i = elements.Length;
int hc = i + 1;
while (--i >= 0)
{
hc *= 257;
hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode();
}
return hc;
}
protected override bool Asn1Equals(Asn1Object asn1Object)
{
Asn1Sequence that = asn1Object as Asn1Sequence;
if (null == that)
return false;
int count = this.Count;
if (that.Count != count)
return false;
for (int i = 0; i < count; ++i)
{
Asn1Object o1 = this.elements[i].ToAsn1Object();
Asn1Object o2 = that.elements[i].ToAsn1Object();
if (o1 != o2 && !o1.CallAsn1Equals(o2))
return false;
}
return true;
}
public override string ToString()
{
return CollectionUtilities.ToString(elements);
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public interface Asn1SequenceParser
: IAsn1Convertible
{
IAsn1Convertible ReadObject();
}
}

View File

@ -0,0 +1,337 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util.collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
abstract public class Asn1Set
: Asn1Object, IEnumerable
{
// NOTE: Only non-readonly to support LazyDerSet
internal Asn1Encodable[] elements;
/**
* return an ASN1Set from the given object.
*
* @param obj the object we want converted.
* @exception ArgumentException if the object cannot be converted.
*/
public static Asn1Set GetInstance(
object obj)
{
if (obj == null || obj is Asn1Set)
{
return (Asn1Set)obj;
}
else if (obj is Asn1SetParser)
{
return Asn1Set.GetInstance(((Asn1SetParser)obj).ToAsn1Object());
}
else if (obj is byte[])
{
try
{
return Asn1Set.GetInstance(FromByteArray((byte[])obj));
}
catch (IOException e)
{
throw new ArgumentException("failed to construct set from byte[]: " + e.Message);
}
}
else if (obj is Asn1Encodable)
{
Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object();
if (primitive is Asn1Set)
{
return (Asn1Set)primitive;
}
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* Return an ASN1 set from a tagged object. There is a special
* case here, if an object appears to have been explicitly tagged on
* reading but we were expecting it to be implicitly tagged in the
* normal course of events it indicates that we lost the surrounding
* set - so we need to add it back (this will happen if the tagged
* object is a sequence that contains other sequences). If you are
* dealing with implicitly tagged sets you really <b>should</b>
* be using this method.
*
* @param obj the tagged object.
* @param explicitly true if the object is meant to be explicitly tagged
* false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static Asn1Set GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
Asn1Object inner = obj.GetObject();
if (explicitly)
{
if (!obj.IsExplicit())
throw new ArgumentException("object implicit - explicit expected.");
return (Asn1Set)inner;
}
//
// constructed object which appears to be explicitly tagged
// and it's really implicit means we have to add the
// surrounding sequence.
//
if (obj.IsExplicit())
{
return new DerSet(inner);
}
if (inner is Asn1Set)
{
return (Asn1Set)inner;
}
//
// in this case the parser returns a sequence, convert it
// into a set.
//
if (inner is Asn1Sequence)
{
Asn1EncodableVector v = new Asn1EncodableVector();
Asn1Sequence s = (Asn1Sequence)inner;
foreach (Asn1Encodable ae in s)
{
v.Add(ae);
}
// TODO Should be able to construct set directly from sequence?
return new DerSet(v, false);
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
protected internal Asn1Set()
{
this.elements = Asn1EncodableVector.EmptyElements;
}
protected internal Asn1Set(Asn1Encodable element)
{
if (null == element)
throw new ArgumentNullException("element");
this.elements = new Asn1Encodable[] { element };
}
protected internal Asn1Set(params Asn1Encodable[] elements)
{
if (Arrays.IsNullOrContainsNull(elements))
throw new NullReferenceException("'elements' cannot be null, or contain null");
this.elements = Asn1EncodableVector.CloneElements(elements);
}
protected internal Asn1Set(Asn1EncodableVector elementVector)
{
if (null == elementVector)
throw new ArgumentNullException("elementVector");
this.elements = elementVector.TakeElements();
}
public virtual IEnumerator GetEnumerator()
{
return elements.GetEnumerator();
}
/**
* return the object at the set position indicated by index.
*
* @param index the set number (starting at zero) of the object
* @return the object at the set position indicated by index.
*/
public virtual Asn1Encodable this[int index]
{
get { return elements[index]; }
}
public virtual int Count
{
get { return elements.Length; }
}
public virtual Asn1Encodable[] ToArray()
{
return Asn1EncodableVector.CloneElements(elements);
}
private class Asn1SetParserImpl
: Asn1SetParser
{
private readonly Asn1Set outer;
private readonly int max;
private int index;
public Asn1SetParserImpl(
Asn1Set outer)
{
this.outer = outer;
this.max = outer.Count;
}
public IAsn1Convertible ReadObject()
{
if (index == max)
return null;
Asn1Encodable obj = outer[index++];
if (obj is Asn1Sequence)
return ((Asn1Sequence)obj).Parser;
if (obj is Asn1Set)
return ((Asn1Set)obj).Parser;
// NB: Asn1OctetString implements Asn1OctetStringParser directly
// if (obj is Asn1OctetString)
// return ((Asn1OctetString)obj).Parser;
return obj;
}
public virtual Asn1Object ToAsn1Object()
{
return outer;
}
}
public Asn1SetParser Parser
{
get { return new Asn1SetParserImpl(this); }
}
protected override int Asn1GetHashCode()
{
//return Arrays.GetHashCode(elements);
int i = elements.Length;
int hc = i + 1;
while (--i >= 0)
{
hc *= 257;
hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode();
}
return hc;
}
protected override bool Asn1Equals(Asn1Object asn1Object)
{
Asn1Set that = asn1Object as Asn1Set;
if (null == that)
return false;
int count = this.Count;
if (that.Count != count)
return false;
for (int i = 0; i < count; ++i)
{
Asn1Object o1 = this.elements[i].ToAsn1Object();
Asn1Object o2 = that.elements[i].ToAsn1Object();
if (o1 != o2 && !o1.CallAsn1Equals(o2))
return false;
}
return true;
}
protected internal void Sort()
{
if (elements.Length < 2)
return;
#if PORTABLE
this.elements = elements
.Cast<Asn1Encodable>()
.Select(a => new { Item = a, Key = a.GetEncoded(Asn1Encodable.Der) })
.OrderBy(t => t.Key, new DerComparer())
.Select(t => t.Item)
.ToArray();
#else
int count = elements.Length;
byte[][] keys = new byte[count][];
for (int i = 0; i < count; ++i)
{
keys[i] = elements[i].GetEncoded(Asn1Encodable.Der);
}
Array.Sort(keys, elements, new DerComparer());
#endif
}
public override string ToString()
{
return CollectionUtilities.ToString(elements);
}
#if PORTABLE
private class DerComparer
: IComparer<byte[]>
{
public int Compare(byte[] x, byte[] y)
{
byte[] a = x, b = y;
#else
private class DerComparer
: IComparer
{
public int Compare(object x, object y)
{
byte[] a = (byte[])x, b = (byte[])y;
#endif
Debug.Assert(a.Length >= 2 && b.Length >= 2);
/*
* NOTE: Set elements in DER encodings are ordered first according to their tags (class and
* number); the CONSTRUCTED bit is not part of the tag.
*
* For SET-OF, this is unimportant. All elements have the same tag and DER requires them to
* either all be in constructed form or all in primitive form, according to that tag. The
* elements are effectively ordered according to their content octets.
*
* For SET, the elements will have distinct tags, and each will be in constructed or
* primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
* ordering inversions.
*/
int a0 = a[0] & ~Asn1Tags.Constructed;
int b0 = b[0] & ~Asn1Tags.Constructed;
if (a0 != b0)
return a0 < b0 ? -1 : 1;
int len = System.Math.Min(a.Length, b.Length);
for (int i = 1; i < len; ++i)
{
byte ai = a[i], bi = b[i];
if (ai != bi)
return ai < bi ? -1 : 1;
}
Debug.Assert(a.Length == b.Length);
return 0;
}
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public interface Asn1SetParser
: IAsn1Convertible
{
IAsn1Convertible ReadObject();
}
}

View File

@ -0,0 +1,241 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class Asn1StreamParser
{
private readonly Stream _in;
private readonly int _limit;
private readonly byte[][] tmpBuffers;
public Asn1StreamParser(
Stream inStream)
: this(inStream, Asn1InputStream.FindLimit(inStream))
{
}
public Asn1StreamParser(
Stream inStream,
int limit)
{
if (!inStream.CanRead)
throw new ArgumentException("Expected stream to be readable", "inStream");
this._in = inStream;
this._limit = limit;
this.tmpBuffers = new byte[16][];
}
public Asn1StreamParser(
byte[] encoding)
: this(new MemoryStream(encoding, false), encoding.Length)
{
}
internal IAsn1Convertible ReadIndef(int tagValue)
{
// Note: INDEF => CONSTRUCTED
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
switch (tagValue)
{
case Asn1Tags.External:
return new DerExternalParser(this);
case Asn1Tags.OctetString:
return new BerOctetStringParser(this);
case Asn1Tags.Sequence:
return new BerSequenceParser(this);
case Asn1Tags.Set:
return new BerSetParser(this);
default:
throw new Asn1Exception("unknown BER object encountered: 0x" + tagValue.ToString("X"));
}
}
internal IAsn1Convertible ReadImplicit(bool constructed, int tag)
{
if (_in is IndefiniteLengthInputStream)
{
if (!constructed)
throw new IOException("indefinite-length primitive encoding encountered");
return ReadIndef(tag);
}
if (constructed)
{
switch (tag)
{
case Asn1Tags.Set:
return new DerSetParser(this);
case Asn1Tags.Sequence:
return new DerSequenceParser(this);
case Asn1Tags.OctetString:
return new BerOctetStringParser(this);
}
}
else
{
switch (tag)
{
case Asn1Tags.Set:
throw new Asn1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
case Asn1Tags.Sequence:
throw new Asn1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
case Asn1Tags.OctetString:
return new DerOctetStringParser((DefiniteLengthInputStream)_in);
}
}
throw new Asn1Exception("implicit tagging not implemented");
}
internal Asn1Object ReadTaggedObject(bool constructed, int tag)
{
if (!constructed)
{
// Note: !CONSTRUCTED => IMPLICIT
DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
return new DerTaggedObject(false, tag, new DerOctetString(defIn.ToArray()));
}
Asn1EncodableVector v = ReadVector();
if (_in is IndefiniteLengthInputStream)
{
return v.Count == 1
? new BerTaggedObject(true, tag, v[0])
: new BerTaggedObject(false, tag, BerSequence.FromVector(v));
}
return v.Count == 1
? new DerTaggedObject(true, tag, v[0])
: new DerTaggedObject(false, tag, DerSequence.FromVector(v));
}
public virtual IAsn1Convertible ReadObject()
{
int tag = _in.ReadByte();
if (tag == -1)
return null;
// turn of looking for "00" while we resolve the tag
Set00Check(false);
//
// calculate tag number
//
int tagNo = Asn1InputStream.ReadTagNumber(_in, tag);
bool isConstructed = (tag & Asn1Tags.Constructed) != 0;
//
// calculate length
//
int length = Asn1InputStream.ReadLength(_in, _limit,
tagNo == Asn1Tags.OctetString || tagNo == Asn1Tags.Sequence || tagNo == Asn1Tags.Set || tagNo == Asn1Tags.External);
if (length < 0) // indefinite-length method
{
if (!isConstructed)
throw new IOException("indefinite-length primitive encoding encountered");
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
Asn1StreamParser sp = new Asn1StreamParser(indIn, _limit);
if ((tag & Asn1Tags.Application) != 0)
{
return new BerApplicationSpecificParser(tagNo, sp);
}
if ((tag & Asn1Tags.Tagged) != 0)
{
return new BerTaggedObjectParser(true, tagNo, sp);
}
return sp.ReadIndef(tagNo);
}
else
{
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
if ((tag & Asn1Tags.Application) != 0)
{
return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray());
}
if ((tag & Asn1Tags.Tagged) != 0)
{
return new BerTaggedObjectParser(isConstructed, tagNo, new Asn1StreamParser(defIn));
}
if (isConstructed)
{
// TODO There are other tags that may be constructed (e.g. BitString)
switch (tagNo)
{
case Asn1Tags.OctetString:
//
// yes, people actually do this...
//
return new BerOctetStringParser(new Asn1StreamParser(defIn));
case Asn1Tags.Sequence:
return new DerSequenceParser(new Asn1StreamParser(defIn));
case Asn1Tags.Set:
return new DerSetParser(new Asn1StreamParser(defIn));
case Asn1Tags.External:
return new DerExternalParser(new Asn1StreamParser(defIn));
default:
throw new IOException("unknown tag " + tagNo + " encountered");
}
}
// Some primitive encodings can be handled by parsers too...
switch (tagNo)
{
case Asn1Tags.OctetString:
return new DerOctetStringParser(defIn);
}
try
{
return Asn1InputStream.CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers);
}
catch (ArgumentException e)
{
throw new Asn1Exception("corrupted stream detected", e);
}
}
}
private void Set00Check(
bool enabled)
{
if (_in is IndefiniteLengthInputStream)
{
((IndefiniteLengthInputStream)_in).SetEofOn00(enabled);
}
}
internal Asn1EncodableVector ReadVector()
{
IAsn1Convertible obj = ReadObject();
if (null == obj)
return new Asn1EncodableVector(0);
Asn1EncodableVector v = new Asn1EncodableVector();
do
{
v.Add(obj.ToAsn1Object());
}
while ((obj = ReadObject()) != null);
return v;
}
}
}

View File

@ -0,0 +1,191 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
* rules (as with sequences).
*/
public abstract class Asn1TaggedObject
: Asn1Object, Asn1TaggedObjectParser
{
internal static bool IsConstructed(bool isExplicit, Asn1Object obj)
{
if (isExplicit || obj is Asn1Sequence || obj is Asn1Set)
return true;
Asn1TaggedObject tagged = obj as Asn1TaggedObject;
if (tagged == null)
return false;
return IsConstructed(tagged.IsExplicit(), tagged.GetObject());
}
internal int tagNo;
// internal bool empty;
internal bool explicitly = true;
internal Asn1Encodable obj;
static public Asn1TaggedObject GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
if (explicitly)
{
return GetInstance(obj.GetObject());
}
throw new ArgumentException("implicitly tagged tagged object");
}
static public Asn1TaggedObject GetInstance(
object obj)
{
if (obj == null || obj is Asn1TaggedObject)
{
return (Asn1TaggedObject)obj;
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
protected Asn1TaggedObject(
int tagNo,
Asn1Encodable obj)
{
this.explicitly = true;
this.tagNo = tagNo;
this.obj = obj;
}
/**
* @param explicitly true if the object is explicitly tagged.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
protected Asn1TaggedObject(
bool explicitly,
int tagNo,
Asn1Encodable obj)
{
// IAsn1Choice marker interface 'insists' on explicit tagging
this.explicitly = explicitly || (obj is IAsn1Choice);
this.tagNo = tagNo;
this.obj = obj;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
Asn1TaggedObject other = asn1Object as Asn1TaggedObject;
if (other == null)
return false;
return this.tagNo == other.tagNo
// && this.empty == other.empty
&& this.explicitly == other.explicitly // TODO Should this be part of equality?
&& Platform.Equals(GetObject(), other.GetObject());
}
protected override int Asn1GetHashCode()
{
int code = tagNo.GetHashCode();
// TODO: actually this is wrong - the problem is that a re-encoded
// object may end up with a different hashCode due to implicit
// tagging. As implicit tagging is ambiguous if a sequence is involved
// it seems the only correct method for both equals and hashCode is to
// compare the encodings...
// code ^= explicitly.GetHashCode();
if (obj != null)
{
code ^= obj.GetHashCode();
}
return code;
}
public int TagNo
{
get { return tagNo; }
}
/**
* return whether or not the object may be explicitly tagged.
* <p>
* Note: if the object has been read from an input stream, the only
* time you can be sure if isExplicit is returning the true state of
* affairs is if it returns false. An implicitly tagged object may appear
* to be explicitly tagged, so you need to understand the context under
* which the reading was done as well, see GetObject below.</p>
*/
public bool IsExplicit()
{
return explicitly;
}
public bool IsEmpty()
{
return false; //empty;
}
/**
* return whatever was following the tag.
* <p>
* Note: tagged objects are generally context dependent if you're
* trying to extract a tagged object you should be going via the
* appropriate GetInstance method.</p>
*/
public Asn1Object GetObject()
{
if (obj != null)
{
return obj.ToAsn1Object();
}
return null;
}
/**
* Return the object held in this tagged object as a parser assuming it has
* the type of the passed in tag. If the object doesn't have a parser
* associated with it, the base object is returned.
*/
public IAsn1Convertible GetObjectParser(
int tag,
bool isExplicit)
{
switch (tag)
{
case Asn1Tags.Set:
return Asn1Set.GetInstance(this, isExplicit).Parser;
case Asn1Tags.Sequence:
return Asn1Sequence.GetInstance(this, isExplicit).Parser;
case Asn1Tags.OctetString:
return Asn1OctetString.GetInstance(this, isExplicit).Parser;
}
if (isExplicit)
{
return GetObject();
}
throw Platform.CreateNotImplementedException("implicit tagging for tag: " + tag);
}
public override string ToString()
{
return "[" + tagNo + "]" + obj;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public interface Asn1TaggedObjectParser
: IAsn1Convertible
{
int TagNo { get; }
IAsn1Convertible GetObjectParser(int tag, bool isExplicit);
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class Asn1Tags
{
public const int Boolean = 0x01;
public const int Integer = 0x02;
public const int BitString = 0x03;
public const int OctetString = 0x04;
public const int Null = 0x05;
public const int ObjectIdentifier = 0x06;
public const int External = 0x08;
public const int Enumerated = 0x0a;
public const int Sequence = 0x10;
public const int SequenceOf = 0x10; // for completeness
public const int Set = 0x11;
public const int SetOf = 0x11; // for completeness
public const int NumericString = 0x12;
public const int PrintableString = 0x13;
public const int T61String = 0x14;
public const int VideotexString = 0x15;
public const int IA5String = 0x16;
public const int UtcTime = 0x17;
public const int GeneralizedTime = 0x18;
public const int GraphicString = 0x19;
public const int VisibleString = 0x1a;
public const int GeneralString = 0x1b;
public const int UniversalString = 0x1c;
public const int BmpString = 0x1e;
public const int Utf8String = 0x0c;
public const int Constructed = 0x20;
public const int Application = 0x40;
public const int Tagged = 0x80;
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerApplicationSpecific
: DerApplicationSpecific
{
public BerApplicationSpecific(
int tagNo,
Asn1EncodableVector vec)
: base(tagNo, vec)
{
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerApplicationSpecificParser
: IAsn1ApplicationSpecificParser
{
private readonly int tag;
private readonly Asn1StreamParser parser;
internal BerApplicationSpecificParser(
int tag,
Asn1StreamParser parser)
{
this.tag = tag;
this.parser = parser;
}
public IAsn1Convertible ReadObject()
{
return parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new BerApplicationSpecific(tag, parser.ReadVector());
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerBitString
: DerBitString
{
public BerBitString(byte[] data, int padBits)
: base(data, padBits)
{
}
public BerBitString(byte[] data)
: base(data)
{
}
public BerBitString(int namedBits)
: base(namedBits)
{
}
public BerBitString(Asn1Encodable obj)
: base(obj)
{
}
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData);
}
else
{
base.Encode(derOut);
}
}
}
}

View File

@ -0,0 +1,180 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerOctetString
: DerOctetString, IEnumerable
{
private static readonly int DefaultChunkSize = 1000;
public static BerOctetString FromSequence(Asn1Sequence seq)
{
int count = seq.Count;
Asn1OctetString[] v = new Asn1OctetString[count];
for (int i = 0; i < count; ++i)
{
v[i] = Asn1OctetString.GetInstance(seq[i]);
}
return new BerOctetString(v);
}
private static byte[] ToBytes(Asn1OctetString[] octs)
{
MemoryStream bOut = new MemoryStream();
foreach (Asn1OctetString o in octs)
{
byte[] octets = o.GetOctets();
bOut.Write(octets, 0, octets.Length);
}
return bOut.ToArray();
}
private static Asn1OctetString[] ToOctetStringArray(IEnumerable e)
{
IList list = Platform.CreateArrayList(e);
int count = list.Count;
Asn1OctetString[] v = new Asn1OctetString[count];
for (int i = 0; i < count; ++i)
{
v[i] = Asn1OctetString.GetInstance(list[i]);
}
return v;
}
private readonly int chunkSize;
private readonly Asn1OctetString[] octs;
[Obsolete("Will be removed")]
public BerOctetString(IEnumerable e)
: this(ToOctetStringArray(e))
{
}
public BerOctetString(byte[] str)
: this(str, DefaultChunkSize)
{
}
public BerOctetString(Asn1OctetString[] octs)
: this(octs, DefaultChunkSize)
{
}
public BerOctetString(byte[] str, int chunkSize)
: this(str, null, chunkSize)
{
}
public BerOctetString(Asn1OctetString[] octs, int chunkSize)
: this(ToBytes(octs), octs, chunkSize)
{
}
private BerOctetString(byte[] str, Asn1OctetString[] octs, int chunkSize)
: base(str)
{
this.octs = octs;
this.chunkSize = chunkSize;
}
/**
* return the DER octets that make up this string.
*/
public IEnumerator GetEnumerator()
{
if (octs == null)
return new ChunkEnumerator(str, chunkSize);
return octs.GetEnumerator();
}
[Obsolete("Use GetEnumerator() instead")]
public IEnumerator GetObjects()
{
return GetEnumerator();
}
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteByte(Asn1Tags.Constructed | Asn1Tags.OctetString);
derOut.WriteByte(0x80);
//
// write out the octet array
//
foreach (Asn1OctetString oct in this)
{
derOut.WriteObject(oct);
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
private class ChunkEnumerator
: IEnumerator
{
private readonly byte[] octets;
private readonly int chunkSize;
private DerOctetString currentChunk = null;
private int nextChunkPos = 0;
internal ChunkEnumerator(byte[] octets, int chunkSize)
{
this.octets = octets;
this.chunkSize = chunkSize;
}
public object Current
{
get
{
if (null == currentChunk)
throw new InvalidOperationException();
return currentChunk;
}
}
public bool MoveNext()
{
if (nextChunkPos >= octets.Length)
{
this.currentChunk = null;
return false;
}
int length = System.Math.Min(octets.Length - nextChunkPos, chunkSize);
byte[] chunk = new byte[length];
Array.Copy(octets, nextChunkPos, chunk, 0, length);
this.currentChunk = new DerOctetString(chunk);
this.nextChunkPos += length;
return true;
}
public void Reset()
{
this.currentChunk = null;
this.nextChunkPos = 0;
}
}
}
}

View File

@ -0,0 +1,39 @@
using BrowserPass.BouncyCastle.util.io;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerOctetStringParser
: Asn1OctetStringParser
{
private readonly Asn1StreamParser _parser;
internal BerOctetStringParser(
Asn1StreamParser parser)
{
_parser = parser;
}
public Stream GetOctetStream()
{
return new ConstructedOctetStream(_parser);
}
public Asn1Object ToAsn1Object()
{
try
{
return new BerOctetString(Streams.ReadAll(GetOctetStream()));
}
catch (IOException e)
{
throw new Asn1ParsingException("IOException converting stream to byte array: " + e.Message, e);
}
}
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerOutputStream
: DerOutputStream
{
public BerOutputStream(Stream os) : base(os)
{
}
[Obsolete("Use version taking an Asn1Encodable arg instead")]
public override void WriteObject(
object obj)
{
if (obj == null)
{
WriteNull();
}
else if (obj is Asn1Object)
{
((Asn1Object)obj).Encode(this);
}
else if (obj is Asn1Encodable)
{
((Asn1Encodable)obj).ToAsn1Object().Encode(this);
}
else
{
throw new IOException("object not BerEncodable");
}
}
}
}

View File

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerSequence
: DerSequence
{
public static new readonly BerSequence Empty = new BerSequence();
public static new BerSequence FromVector(Asn1EncodableVector elementVector)
{
return elementVector.Count < 1 ? Empty : new BerSequence(elementVector);
}
/**
* create an empty sequence
*/
public BerSequence()
: base()
{
}
/**
* create a sequence containing one object
*/
public BerSequence(Asn1Encodable element)
: base(element)
{
}
public BerSequence(params Asn1Encodable[] elements)
: base(elements)
{
}
/**
* create a sequence containing a vector of objects.
*/
public BerSequence(Asn1EncodableVector elementVector)
: base(elementVector)
{
}
internal override void Encode(DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteByte(Asn1Tags.Sequence | Asn1Tags.Constructed);
derOut.WriteByte(0x80);
foreach (Asn1Encodable o in this)
{
derOut.WriteObject(o);
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerSequenceParser
: Asn1SequenceParser
{
private readonly Asn1StreamParser _parser;
internal BerSequenceParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new BerSequence(_parser.ReadVector());
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerSet
: DerSet
{
public static new readonly BerSet Empty = new BerSet();
public static new BerSet FromVector(Asn1EncodableVector elementVector)
{
return elementVector.Count < 1 ? Empty : new BerSet(elementVector);
}
internal static new BerSet FromVector(Asn1EncodableVector elementVector, bool needsSorting)
{
return elementVector.Count < 1 ? Empty : new BerSet(elementVector, needsSorting);
}
/**
* create an empty sequence
*/
public BerSet()
: base()
{
}
/**
* create a set containing one object
*/
public BerSet(Asn1Encodable element)
: base(element)
{
}
/**
* create a set containing a vector of objects.
*/
public BerSet(Asn1EncodableVector elementVector)
: base(elementVector, false)
{
}
internal BerSet(Asn1EncodableVector elementVector, bool needsSorting)
: base(elementVector, needsSorting)
{
}
internal override void Encode(DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteByte(Asn1Tags.Set | Asn1Tags.Constructed);
derOut.WriteByte(0x80);
foreach (Asn1Encodable o in this)
{
derOut.WriteObject(o);
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerSetParser
: Asn1SetParser
{
private readonly Asn1StreamParser _parser;
internal BerSetParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new BerSet(_parser.ReadVector(), false);
}
}
}

View File

@ -0,0 +1,111 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* BER TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
* rules (as with sequences).
*/
public class BerTaggedObject
: DerTaggedObject
{
/**
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
public BerTaggedObject(
int tagNo,
Asn1Encodable obj)
: base(tagNo, obj)
{
}
/**
* @param explicitly true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
public BerTaggedObject(
bool explicitly,
int tagNo,
Asn1Encodable obj)
: base(explicitly, tagNo, obj)
{
}
/**
* create an implicitly tagged object that contains a zero
* length sequence.
*/
public BerTaggedObject(
int tagNo)
: base(false, tagNo, BerSequence.Empty)
{
}
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteTag((byte)(Asn1Tags.Constructed | Asn1Tags.Tagged), tagNo);
derOut.WriteByte(0x80);
if (!IsEmpty())
{
if (!explicitly)
{
IEnumerable eObj;
if (obj is Asn1OctetString)
{
if (obj is BerOctetString)
{
eObj = (BerOctetString)obj;
}
else
{
Asn1OctetString octs = (Asn1OctetString)obj;
eObj = new BerOctetString(octs.GetOctets());
}
}
else if (obj is Asn1Sequence)
{
eObj = (Asn1Sequence)obj;
}
else if (obj is Asn1Set)
{
eObj = (Asn1Set)obj;
}
else
{
throw Platform.CreateNotImplementedException(Platform.GetTypeName(obj));
}
foreach (Asn1Encodable o in eObj)
{
derOut.WriteObject(o);
}
}
else
{
derOut.WriteObject(obj);
}
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
}
}

View File

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class BerTaggedObjectParser
: Asn1TaggedObjectParser
{
private bool _constructed;
private int _tagNumber;
private Asn1StreamParser _parser;
[Obsolete]
internal BerTaggedObjectParser(
int baseTag,
int tagNumber,
Stream contentStream)
: this((baseTag & Asn1Tags.Constructed) != 0, tagNumber, new Asn1StreamParser(contentStream))
{
}
internal BerTaggedObjectParser(
bool constructed,
int tagNumber,
Asn1StreamParser parser)
{
_constructed = constructed;
_tagNumber = tagNumber;
_parser = parser;
}
public bool IsConstructed
{
get { return _constructed; }
}
public int TagNo
{
get { return _tagNumber; }
}
public IAsn1Convertible GetObjectParser(
int tag,
bool isExplicit)
{
if (isExplicit)
{
if (!_constructed)
throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
return _parser.ReadObject();
}
return _parser.ReadImplicit(_constructed, tag);
}
public Asn1Object ToAsn1Object()
{
try
{
return _parser.ReadTaggedObject(_constructed, _tagNumber);
}
catch (IOException e)
{
throw new Asn1ParsingException(e.Message);
}
}
}
}

View File

@ -0,0 +1,113 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util.io;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
internal class ConstructedOctetStream
: BaseInputStream
{
private readonly Asn1StreamParser _parser;
private bool _first = true;
private Stream _currentStream;
internal ConstructedOctetStream(
Asn1StreamParser parser)
{
_parser = parser;
}
public override int Read(byte[] buffer, int offset, int count)
{
if (_currentStream == null)
{
if (!_first)
return 0;
Asn1OctetStringParser next = GetNextParser();
if (next == null)
return 0;
_first = false;
_currentStream = next.GetOctetStream();
}
int totalRead = 0;
for (; ; )
{
int numRead = _currentStream.Read(buffer, offset + totalRead, count - totalRead);
if (numRead > 0)
{
totalRead += numRead;
if (totalRead == count)
return totalRead;
}
else
{
Asn1OctetStringParser next = GetNextParser();
if (next == null)
{
_currentStream = null;
return totalRead;
}
_currentStream = next.GetOctetStream();
}
}
}
public override int ReadByte()
{
if (_currentStream == null)
{
if (!_first)
return 0;
Asn1OctetStringParser next = GetNextParser();
if (next == null)
return 0;
_first = false;
_currentStream = next.GetOctetStream();
}
for (; ; )
{
int b = _currentStream.ReadByte();
if (b >= 0)
return b;
Asn1OctetStringParser next = GetNextParser();
if (next == null)
{
_currentStream = null;
return -1;
}
_currentStream = next.GetOctetStream();
}
}
private Asn1OctetStringParser GetNextParser()
{
IAsn1Convertible asn1Obj = _parser.ReadObject();
if (asn1Obj == null)
return null;
if (asn1Obj is Asn1OctetStringParser)
return (Asn1OctetStringParser)asn1Obj;
throw new IOException("unknown object encountered: " + Platform.GetTypeName(asn1Obj));
}
}
}

View File

@ -0,0 +1,114 @@
using BrowserPass.BouncyCastle.util.io;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
class DefiniteLengthInputStream
: LimitedInputStream
{
private static readonly byte[] EmptyBytes = new byte[0];
private readonly int _originalLength;
private int _remaining;
internal DefiniteLengthInputStream(Stream inStream, int length, int limit)
: base(inStream, limit)
{
if (length < 0)
throw new ArgumentException("negative lengths not allowed", "length");
this._originalLength = length;
this._remaining = length;
if (length == 0)
{
SetParentEofDetect(true);
}
}
internal int Remaining
{
get { return _remaining; }
}
public override int ReadByte()
{
if (_remaining == 0)
return -1;
int b = _in.ReadByte();
if (b < 0)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
if (--_remaining == 0)
{
SetParentEofDetect(true);
}
return b;
}
public override int Read(
byte[] buf,
int off,
int len)
{
if (_remaining == 0)
return 0;
int toRead = System.Math.Min(len, _remaining);
int numRead = _in.Read(buf, off, toRead);
if (numRead < 1)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
if ((_remaining -= numRead) == 0)
{
SetParentEofDetect(true);
}
return numRead;
}
internal void ReadAllIntoByteArray(byte[] buf)
{
if (_remaining != buf.Length)
throw new ArgumentException("buffer length not right for data");
if (_remaining == 0)
return;
// make sure it's safe to do this!
int limit = Limit;
if (_remaining >= limit)
throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
if ((_remaining -= Streams.ReadFully(_in, buf)) != 0)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
SetParentEofDetect(true);
}
internal byte[] ToArray()
{
if (_remaining == 0)
return EmptyBytes;
// make sure it's safe to do this!
int limit = Limit;
if (_remaining >= limit)
throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
byte[] bytes = new byte[_remaining];
if ((_remaining -= Streams.ReadFully(_in, bytes)) != 0)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
SetParentEofDetect(true);
return bytes;
}
}
}

View File

@ -0,0 +1,229 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Base class for an application specific object
*/
public class DerApplicationSpecific
: Asn1Object
{
private readonly bool isConstructed;
private readonly int tag;
private readonly byte[] octets;
internal DerApplicationSpecific(
bool isConstructed,
int tag,
byte[] octets)
{
this.isConstructed = isConstructed;
this.tag = tag;
this.octets = octets;
}
public DerApplicationSpecific(
int tag,
byte[] octets)
: this(false, tag, octets)
{
}
public DerApplicationSpecific(
int tag,
Asn1Encodable obj)
: this(true, tag, obj)
{
}
public DerApplicationSpecific(
bool isExplicit,
int tag,
Asn1Encodable obj)
{
Asn1Object asn1Obj = obj.ToAsn1Object();
byte[] data = asn1Obj.GetDerEncoded();
this.isConstructed = Asn1TaggedObject.IsConstructed(isExplicit, asn1Obj);
this.tag = tag;
if (isExplicit)
{
this.octets = data;
}
else
{
int lenBytes = GetLengthOfHeader(data);
byte[] tmp = new byte[data.Length - lenBytes];
Array.Copy(data, lenBytes, tmp, 0, tmp.Length);
this.octets = tmp;
}
}
public DerApplicationSpecific(
int tagNo,
Asn1EncodableVector vec)
{
this.tag = tagNo;
this.isConstructed = true;
MemoryStream bOut = new MemoryStream();
for (int i = 0; i != vec.Count; i++)
{
try
{
byte[] bs = vec[i].GetDerEncoded();
bOut.Write(bs, 0, bs.Length);
}
catch (IOException e)
{
throw new InvalidOperationException("malformed object", e);
}
}
this.octets = bOut.ToArray();
}
private int GetLengthOfHeader(
byte[] data)
{
int length = data[1]; // TODO: assumes 1 byte tag
if (length == 0x80)
{
return 2; // indefinite-length encoding
}
if (length > 127)
{
int size = length & 0x7f;
// Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
if (size > 4)
{
throw new InvalidOperationException("DER length more than 4 bytes: " + size);
}
return size + 2;
}
return 2;
}
public bool IsConstructed()
{
return isConstructed;
}
public byte[] GetContents()
{
return octets;
}
public int ApplicationTag
{
get { return tag; }
}
/**
* Return the enclosed object assuming explicit tagging.
*
* @return the resulting object
* @throws IOException if reconstruction fails.
*/
public Asn1Object GetObject()
{
return FromByteArray(GetContents());
}
/**
* Return the enclosed object assuming implicit tagging.
*
* @param derTagNo the type tag that should be applied to the object's contents.
* @return the resulting object
* @throws IOException if reconstruction fails.
*/
public Asn1Object GetObject(
int derTagNo)
{
if (derTagNo >= 0x1f)
throw new IOException("unsupported tag number");
byte[] orig = this.GetEncoded();
byte[] tmp = ReplaceTagNumber(derTagNo, orig);
if ((orig[0] & Asn1Tags.Constructed) != 0)
{
tmp[0] |= Asn1Tags.Constructed;
}
return FromByteArray(tmp);
}
internal override void Encode(
DerOutputStream derOut)
{
int classBits = Asn1Tags.Application;
if (isConstructed)
{
classBits |= Asn1Tags.Constructed;
}
derOut.WriteEncoded(classBits, tag, octets);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerApplicationSpecific other = asn1Object as DerApplicationSpecific;
if (other == null)
return false;
return this.isConstructed == other.isConstructed
&& this.tag == other.tag
&& Arrays.AreEqual(this.octets, other.octets);
}
protected override int Asn1GetHashCode()
{
return isConstructed.GetHashCode() ^ tag.GetHashCode() ^ Arrays.GetHashCode(octets);
}
private byte[] ReplaceTagNumber(
int newTag,
byte[] input)
{
int tagNo = input[0] & 0x1f;
int index = 1;
// with tagged object tag number is bottom 5 bits, or stored at the start of the content
if (tagNo == 0x1f)
{
int b = input[index++];
// X.690-0207 8.1.2.4.2
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
if ((b & 0x7f) == 0) // Note: -1 will pass
throw new IOException("corrupted stream - invalid high tag number found");
while ((b & 0x80) != 0)
{
b = input[index++];
}
}
int remaining = input.Length - index;
byte[] tmp = new byte[1 + remaining];
tmp[0] = (byte)newTag;
Array.Copy(input, index, tmp, 1, remaining);
return tmp;
}
}
}

View File

@ -0,0 +1,277 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.math;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerBitString
: DerStringBase
{
private static readonly char[] table
= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
protected readonly byte[] mData;
protected readonly int mPadBits;
/**
* return a Bit string from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerBitString GetInstance(
object obj)
{
if (obj == null || obj is DerBitString)
{
return (DerBitString)obj;
}
if (obj is byte[])
{
try
{
return (DerBitString)FromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new ArgumentException("encoding error in GetInstance: " + e.ToString());
}
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a Bit string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerBitString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerBitString)
{
return GetInstance(o);
}
return FromAsn1Octets(((Asn1OctetString)o).GetOctets());
}
/**
* @param data the octets making up the bit string.
* @param padBits the number of extra bits at the end of the string.
*/
public DerBitString(
byte[] data,
int padBits)
{
if (data == null)
throw new ArgumentNullException("data");
if (padBits < 0 || padBits > 7)
throw new ArgumentException("must be in the range 0 to 7", "padBits");
if (data.Length == 0 && padBits != 0)
throw new ArgumentException("if 'data' is empty, 'padBits' must be 0");
this.mData = Arrays.Clone(data);
this.mPadBits = padBits;
}
public DerBitString(
byte[] data)
: this(data, 0)
{
}
public DerBitString(
int namedBits)
{
if (namedBits == 0)
{
this.mData = new byte[0];
this.mPadBits = 0;
return;
}
int bits = BigInteger.BitLen(namedBits);
int bytes = (bits + 7) / 8;
Debug.Assert(0 < bytes && bytes <= 4);
byte[] data = new byte[bytes];
--bytes;
for (int i = 0; i < bytes; i++)
{
data[i] = (byte)namedBits;
namedBits >>= 8;
}
Debug.Assert((namedBits & 0xFF) != 0);
data[bytes] = (byte)namedBits;
int padBits = 0;
while ((namedBits & (1 << padBits)) == 0)
{
++padBits;
}
Debug.Assert(padBits < 8);
this.mData = data;
this.mPadBits = padBits;
}
public DerBitString(
Asn1Encodable obj)
: this(obj.GetDerEncoded())
{
}
/**
* Return the octets contained in this BIT STRING, checking that this BIT STRING really
* does represent an octet aligned string. Only use this method when the standard you are
* following dictates that the BIT STRING will be octet aligned.
*
* @return a copy of the octet aligned data.
*/
public virtual byte[] GetOctets()
{
if (mPadBits != 0)
throw new InvalidOperationException("attempt to get non-octet aligned data from BIT STRING");
return Arrays.Clone(mData);
}
public virtual byte[] GetBytes()
{
byte[] data = Arrays.Clone(mData);
// DER requires pad bits be zero
if (mPadBits > 0)
{
data[data.Length - 1] &= (byte)(0xFF << mPadBits);
}
return data;
}
public virtual int PadBits
{
get { return mPadBits; }
}
/**
* @return the value of the bit string as an int (truncating if necessary)
*/
public virtual int IntValue
{
get
{
int value = 0, length = System.Math.Min(4, mData.Length);
for (int i = 0; i < length; ++i)
{
value |= (int)mData[i] << (8 * i);
}
if (mPadBits > 0 && length == mData.Length)
{
int mask = (1 << mPadBits) - 1;
value &= ~(mask << (8 * (length - 1)));
}
return value;
}
}
internal override void Encode(
DerOutputStream derOut)
{
if (mPadBits > 0)
{
int last = mData[mData.Length - 1];
int mask = (1 << mPadBits) - 1;
int unusedBits = last & mask;
if (unusedBits != 0)
{
byte[] contents = Arrays.Prepend(mData, (byte)mPadBits);
/*
* X.690-0207 11.2.1: Each unused bit in the final octet of the encoding of a bit string value shall be set to zero.
*/
contents[contents.Length - 1] = (byte)(last ^ unusedBits);
derOut.WriteEncoded(Asn1Tags.BitString, contents);
return;
}
}
derOut.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData);
}
protected override int Asn1GetHashCode()
{
return mPadBits.GetHashCode() ^ Arrays.GetHashCode(mData);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerBitString other = asn1Object as DerBitString;
if (other == null)
return false;
return this.mPadBits == other.mPadBits
&& Arrays.AreEqual(this.mData, other.mData);
}
public override string GetString()
{
StringBuilder buffer = new StringBuilder("#");
byte[] str = GetDerEncoded();
for (int i = 0; i != str.Length; i++)
{
uint ubyte = str[i];
buffer.Append(table[(ubyte >> 4) & 0xf]);
buffer.Append(table[str[i] & 0xf]);
}
return buffer.ToString();
}
internal static DerBitString FromAsn1Octets(byte[] octets)
{
if (octets.Length < 1)
throw new ArgumentException("truncated BIT STRING detected", "octets");
int padBits = octets[0];
byte[] data = Arrays.CopyOfRange(octets, 1, octets.Length);
if (padBits > 0 && padBits < 8 && data.Length > 0)
{
int last = data[data.Length - 1];
int mask = (1 << padBits) - 1;
if ((last & mask) != 0)
{
return new BerBitString(data, padBits);
}
}
return new DerBitString(data, padBits);
}
}
}

View File

@ -0,0 +1,132 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der BMPString object.
*/
public class DerBmpString
: DerStringBase
{
private readonly string str;
/**
* return a BMP string from the given object.
*
* @param obj the object we want converted.
* @exception ArgumentException if the object cannot be converted.
*/
public static DerBmpString GetInstance(
object obj)
{
if (obj == null || obj is DerBmpString)
{
return (DerBmpString)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a BMP string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerBmpString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerBmpString)
{
return GetInstance(o);
}
return new DerBmpString(Asn1OctetString.GetInstance(o).GetOctets());
}
/**
* basic constructor - byte encoded string.
*/
[Obsolete("Will become internal")]
public DerBmpString(byte[] str)
{
if (str == null)
throw new ArgumentNullException("str");
int byteLen = str.Length;
if (0 != (byteLen & 1))
throw new ArgumentException("malformed BMPString encoding encountered", "str");
int charLen = byteLen / 2;
char[] cs = new char[charLen];
for (int i = 0; i != charLen; i++)
{
cs[i] = (char)((str[2 * i] << 8) | (str[2 * i + 1] & 0xff));
}
this.str = new string(cs);
}
internal DerBmpString(char[] str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = new string(str);
}
/**
* basic constructor
*/
public DerBmpString(string str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
return str;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerBmpString other = asn1Object as DerBmpString;
if (other == null)
return false;
return this.str.Equals(other.str);
}
internal override void Encode(
DerOutputStream derOut)
{
char[] c = str.ToCharArray();
byte[] b = new byte[c.Length * 2];
for (int i = 0; i != c.Length; i++)
{
b[2 * i] = (byte)(c[i] >> 8);
b[2 * i + 1] = (byte)c[i];
}
derOut.WriteEncoded(Asn1Tags.BmpString, b);
}
}
}

View File

@ -0,0 +1,127 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerBoolean
: Asn1Object
{
private readonly byte value;
public static readonly DerBoolean False = new DerBoolean(false);
public static readonly DerBoolean True = new DerBoolean(true);
/**
* return a bool from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerBoolean GetInstance(
object obj)
{
if (obj == null || obj is DerBoolean)
{
return (DerBoolean)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a DerBoolean from the passed in bool.
*/
public static DerBoolean GetInstance(
bool value)
{
return value ? True : False;
}
/**
* return a Boolean from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerBoolean GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerBoolean)
{
return GetInstance(o);
}
return FromOctetString(((Asn1OctetString)o).GetOctets());
}
public DerBoolean(
byte[] val)
{
if (val.Length != 1)
throw new ArgumentException("byte value should have 1 byte in it", "val");
// TODO Are there any constraints on the possible byte values?
this.value = val[0];
}
private DerBoolean(
bool value)
{
this.value = value ? (byte)0xff : (byte)0;
}
public bool IsTrue
{
get { return value != 0; }
}
internal override void Encode(
DerOutputStream derOut)
{
// TODO Should we make sure the byte value is one of '0' or '0xff' here?
derOut.WriteEncoded(Asn1Tags.Boolean, new byte[] { value });
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerBoolean other = asn1Object as DerBoolean;
if (other == null)
return false;
return IsTrue == other.IsTrue;
}
protected override int Asn1GetHashCode()
{
return IsTrue.GetHashCode();
}
public override string ToString()
{
return IsTrue ? "TRUE" : "FALSE";
}
internal static DerBoolean FromOctetString(byte[] value)
{
if (value.Length != 1)
{
throw new ArgumentException("BOOLEAN value should have 1 byte in it", "value");
}
byte b = value[0];
return b == 0 ? False : b == 0xFF ? True : new DerBoolean(value);
}
}
}

View File

@ -0,0 +1,159 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.math;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerEnumerated
: Asn1Object
{
private readonly byte[] bytes;
private readonly int start;
/**
* return an integer from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerEnumerated GetInstance(
object obj)
{
if (obj == null || obj is DerEnumerated)
{
return (DerEnumerated)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an Enumerated from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerEnumerated GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerEnumerated)
{
return GetInstance(o);
}
return FromOctetString(((Asn1OctetString)o).GetOctets());
}
public DerEnumerated(int val)
{
if (val < 0)
throw new ArgumentException("enumerated must be non-negative", "val");
this.bytes = BigInteger.ValueOf(val).ToByteArray();
this.start = 0;
}
public DerEnumerated(long val)
{
if (val < 0L)
throw new ArgumentException("enumerated must be non-negative", "val");
this.bytes = BigInteger.ValueOf(val).ToByteArray();
this.start = 0;
}
public DerEnumerated(BigInteger val)
{
if (val.SignValue < 0)
throw new ArgumentException("enumerated must be non-negative", "val");
this.bytes = val.ToByteArray();
this.start = 0;
}
public DerEnumerated(byte[] bytes)
{
if (DerInteger.IsMalformed(bytes))
throw new ArgumentException("malformed enumerated", "bytes");
if (0 != (bytes[0] & 0x80))
throw new ArgumentException("enumerated must be non-negative", "bytes");
this.bytes = Arrays.Clone(bytes);
this.start = DerInteger.SignBytesToSkip(bytes);
}
public BigInteger Value
{
get { return new BigInteger(bytes); }
}
public bool HasValue(BigInteger x)
{
return null != x
// Fast check to avoid allocation
&& DerInteger.IntValue(bytes, start, DerInteger.SignExtSigned) == x.IntValue
&& Value.Equals(x);
}
public int IntValueExact
{
get
{
int count = bytes.Length - start;
if (count > 4)
throw new ArithmeticException("ASN.1 Enumerated out of int range");
return DerInteger.IntValue(bytes, start, DerInteger.SignExtSigned);
}
}
internal override void Encode(DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.Enumerated, bytes);
}
protected override bool Asn1Equals(Asn1Object asn1Object)
{
DerEnumerated other = asn1Object as DerEnumerated;
if (other == null)
return false;
return Arrays.AreEqual(this.bytes, other.bytes);
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(bytes);
}
private static readonly DerEnumerated[] cache = new DerEnumerated[12];
internal static DerEnumerated FromOctetString(byte[] enc)
{
if (enc.Length > 1)
return new DerEnumerated(enc);
if (enc.Length == 0)
throw new ArgumentException("ENUMERATED has zero length", "enc");
int value = enc[0];
if (value >= cache.Length)
return new DerEnumerated(enc);
DerEnumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
cache[value] = possibleMatch = new DerEnumerated(enc);
}
return possibleMatch;
}
}
}

View File

@ -0,0 +1,205 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Class representing the DER-type External
*/
public class DerExternal
: Asn1Object
{
private DerObjectIdentifier directReference;
private DerInteger indirectReference;
private Asn1Object dataValueDescriptor;
private int encoding;
private Asn1Object externalContent;
public DerExternal(
Asn1EncodableVector vector)
{
int offset = 0;
Asn1Object enc = GetObjFromVector(vector, offset);
if (enc is DerObjectIdentifier)
{
directReference = (DerObjectIdentifier)enc;
offset++;
enc = GetObjFromVector(vector, offset);
}
if (enc is DerInteger)
{
indirectReference = (DerInteger)enc;
offset++;
enc = GetObjFromVector(vector, offset);
}
if (!(enc is Asn1TaggedObject))
{
dataValueDescriptor = enc;
offset++;
enc = GetObjFromVector(vector, offset);
}
if (vector.Count != offset + 1)
throw new ArgumentException("input vector too large", "vector");
if (!(enc is Asn1TaggedObject))
throw new ArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External", "vector");
Asn1TaggedObject obj = (Asn1TaggedObject)enc;
// Use property accessor to include check on value
Encoding = obj.TagNo;
if (encoding < 0 || encoding > 2)
throw new InvalidOperationException("invalid encoding value");
externalContent = obj.GetObject();
}
/**
* Creates a new instance of DerExternal
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, DerTaggedObject externalData)
: this(directReference, indirectReference, dataValueDescriptor, externalData.TagNo, externalData.ToAsn1Object())
{
}
/**
* Creates a new instance of DerExternal.
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, int encoding, Asn1Object externalData)
{
DirectReference = directReference;
IndirectReference = indirectReference;
DataValueDescriptor = dataValueDescriptor;
Encoding = encoding;
ExternalContent = externalData.ToAsn1Object();
}
internal override void Encode(DerOutputStream derOut)
{
MemoryStream ms = new MemoryStream();
WriteEncodable(ms, directReference);
WriteEncodable(ms, indirectReference);
WriteEncodable(ms, dataValueDescriptor);
WriteEncodable(ms, new DerTaggedObject(Asn1Tags.External, externalContent));
derOut.WriteEncoded(Asn1Tags.Constructed, Asn1Tags.External, ms.ToArray());
}
protected override int Asn1GetHashCode()
{
int ret = externalContent.GetHashCode();
if (directReference != null)
{
ret ^= directReference.GetHashCode();
}
if (indirectReference != null)
{
ret ^= indirectReference.GetHashCode();
}
if (dataValueDescriptor != null)
{
ret ^= dataValueDescriptor.GetHashCode();
}
return ret;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
if (this == asn1Object)
return true;
DerExternal other = asn1Object as DerExternal;
if (other == null)
return false;
return Platform.Equals(directReference, other.directReference)
&& Platform.Equals(indirectReference, other.indirectReference)
&& Platform.Equals(dataValueDescriptor, other.dataValueDescriptor)
&& externalContent.Equals(other.externalContent);
}
public Asn1Object DataValueDescriptor
{
get { return dataValueDescriptor; }
set { this.dataValueDescriptor = value; }
}
public DerObjectIdentifier DirectReference
{
get { return directReference; }
set { this.directReference = value; }
}
/**
* The encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
*/
public int Encoding
{
get
{
return encoding;
}
set
{
if (encoding < 0 || encoding > 2)
throw new InvalidOperationException("invalid encoding value: " + encoding);
this.encoding = value;
}
}
public Asn1Object ExternalContent
{
get { return externalContent; }
set { this.externalContent = value; }
}
public DerInteger IndirectReference
{
get { return indirectReference; }
set { this.indirectReference = value; }
}
private static Asn1Object GetObjFromVector(Asn1EncodableVector v, int index)
{
if (v.Count <= index)
throw new ArgumentException("too few objects in input vector", "v");
return v[index].ToAsn1Object();
}
private static void WriteEncodable(MemoryStream ms, Asn1Encodable e)
{
if (e != null)
{
byte[] bs = e.GetDerEncoded();
ms.Write(bs, 0, bs.Length);
}
}
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerExternalParser
: Asn1Encodable
{
private readonly Asn1StreamParser _parser;
public DerExternalParser(Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public override Asn1Object ToAsn1Object()
{
return new DerExternal(_parser.ReadVector());
}
}
}

View File

@ -0,0 +1,84 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerGeneralString
: DerStringBase
{
private readonly string str;
public static DerGeneralString GetInstance(
object obj)
{
if (obj == null || obj is DerGeneralString)
{
return (DerGeneralString)obj;
}
throw new ArgumentException("illegal object in GetInstance: "
+ Platform.GetTypeName(obj));
}
public static DerGeneralString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerGeneralString)
{
return GetInstance(o);
}
return new DerGeneralString(((Asn1OctetString)o).GetOctets());
}
public DerGeneralString(
byte[] str)
: this(Strings.FromAsciiByteArray(str))
{
}
public DerGeneralString(
string str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
return str;
}
public byte[] GetOctets()
{
return Strings.ToAsciiByteArray(str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.GeneralString, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerGeneralString other = asn1Object as DerGeneralString;
if (other == null)
return false;
return this.str.Equals(other.str);
}
}
}

View File

@ -0,0 +1,323 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Generalized time object.
*/
public class DerGeneralizedTime
: Asn1Object
{
private readonly string time;
/**
* return a generalized time from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerGeneralizedTime GetInstance(
object obj)
{
if (obj == null || obj is DerGeneralizedTime)
{
return (DerGeneralizedTime)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* return a Generalized Time object from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerGeneralizedTime GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerGeneralizedTime)
{
return GetInstance(o);
}
return new DerGeneralizedTime(((Asn1OctetString)o).GetOctets());
}
/**
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
* for local time, or Z+-HHMM on the end, for difference between local
* time and UTC time. The fractional second amount f must consist of at
* least one number with trailing zeroes removed.
*
* @param time the time string.
* @exception ArgumentException if string is an illegal format.
*/
public DerGeneralizedTime(
string time)
{
this.time = time;
try
{
ToDateTime();
}
catch (FormatException e)
{
throw new ArgumentException("invalid date string: " + e.Message);
}
}
/**
* base constructor from a local time object
*/
public DerGeneralizedTime(
DateTime time)
{
#if PORTABLE
this.time = time.ToUniversalTime().ToString(@"yyyyMMddHHmmss\Z");
#else
this.time = time.ToString(@"yyyyMMddHHmmss\Z");
#endif
}
internal DerGeneralizedTime(
byte[] bytes)
{
//
// explicitly convert to characters
//
this.time = Strings.FromAsciiByteArray(bytes);
}
/**
* Return the time.
* @return The time string as it appeared in the encoded object.
*/
public string TimeString
{
get { return time; }
}
/**
* return the time - always in the form of
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
* </pre>
* To read in the time and Get a date which is compatible with our local
* time zone.</p>
*/
public string GetTime()
{
//
// standardise the format.
//
if (time[time.Length - 1] == 'Z')
{
return time.Substring(0, time.Length - 1) + "GMT+00:00";
}
else
{
int signPos = time.Length - 5;
char sign = time[signPos];
if (sign == '-' || sign == '+')
{
return time.Substring(0, signPos)
+ "GMT"
+ time.Substring(signPos, 3)
+ ":"
+ time.Substring(signPos + 3);
}
else
{
signPos = time.Length - 3;
sign = time[signPos];
if (sign == '-' || sign == '+')
{
return time.Substring(0, signPos)
+ "GMT"
+ time.Substring(signPos)
+ ":00";
}
}
}
return time + CalculateGmtOffset();
}
private string CalculateGmtOffset()
{
char sign = '+';
DateTime time = ToDateTime();
#if SILVERLIGHT || PORTABLE
long offset = time.Ticks - time.ToUniversalTime().Ticks;
if (offset < 0)
{
sign = '-';
offset = -offset;
}
int hours = (int)(offset / TimeSpan.TicksPerHour);
int minutes = (int)(offset / TimeSpan.TicksPerMinute) % 60;
#else
// Note: GetUtcOffset incorporates Daylight Savings offset
TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(time);
if (offset.CompareTo(TimeSpan.Zero) < 0)
{
sign = '-';
offset = offset.Duration();
}
int hours = offset.Hours;
int minutes = offset.Minutes;
#endif
return "GMT" + sign + Convert(hours) + ":" + Convert(minutes);
}
private static string Convert(
int time)
{
if (time < 10)
{
return "0" + time;
}
return time.ToString();
}
public DateTime ToDateTime()
{
string formatStr;
string d = time;
bool makeUniversal = false;
if (Platform.EndsWith(d, "Z"))
{
if (HasFractionalSeconds)
{
int fCount = d.Length - d.IndexOf('.') - 2;
formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z";
}
else
{
formatStr = @"yyyyMMddHHmmss\Z";
}
}
else if (time.IndexOf('-') > 0 || time.IndexOf('+') > 0)
{
d = GetTime();
makeUniversal = true;
if (HasFractionalSeconds)
{
int fCount = Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.');
formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz";
}
else
{
formatStr = @"yyyyMMddHHmmss'GMT'zzz";
}
}
else
{
if (HasFractionalSeconds)
{
int fCount = d.Length - 1 - d.IndexOf('.');
formatStr = @"yyyyMMddHHmmss." + FString(fCount);
}
else
{
formatStr = @"yyyyMMddHHmmss";
}
// TODO?
// dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
}
return ParseDateString(d, formatStr, makeUniversal);
}
private string FString(
int count)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; ++i)
{
sb.Append('f');
}
return sb.ToString();
}
private DateTime ParseDateString(string s, string format, bool makeUniversal)
{
/*
* NOTE: DateTime.Kind and DateTimeStyles.AssumeUniversal not available in .NET 1.1
*/
DateTimeStyles style = DateTimeStyles.None;
if (Platform.EndsWith(format, "Z"))
{
try
{
style = (DateTimeStyles)Enums.GetEnumValue(typeof(DateTimeStyles), "AssumeUniversal");
}
catch (Exception)
{
}
style |= DateTimeStyles.AdjustToUniversal;
}
DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, style);
return makeUniversal ? dt.ToUniversalTime() : dt;
}
private bool HasFractionalSeconds
{
get { return time.IndexOf('.') == 14; }
}
private byte[] GetOctets()
{
return Strings.ToAsciiByteArray(time);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.GeneralizedTime, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerGeneralizedTime other = asn1Object as DerGeneralizedTime;
if (other == null)
return false;
return this.time.Equals(other.time);
}
protected override int Asn1GetHashCode()
{
return time.GetHashCode();
}
}
}

View File

@ -0,0 +1,107 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerGraphicString
: DerStringBase
{
private readonly byte[] mString;
/**
* return a Graphic String from the passed in object
*
* @param obj a DerGraphicString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DerGraphicString instance, or null.
*/
public static DerGraphicString GetInstance(object obj)
{
if (obj == null || obj is DerGraphicString)
{
return (DerGraphicString)obj;
}
if (obj is byte[])
{
try
{
return (DerGraphicString)FromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj");
}
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* return a Graphic String from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DerGraphicString instance, or null.
*/
public static DerGraphicString GetInstance(Asn1TaggedObject obj, bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerGraphicString)
{
return GetInstance(o);
}
return new DerGraphicString(((Asn1OctetString)o).GetOctets());
}
/**
* basic constructor - with bytes.
* @param string the byte encoding of the characters making up the string.
*/
public DerGraphicString(byte[] encoding)
{
this.mString = Arrays.Clone(encoding);
}
public override string GetString()
{
return Strings.FromByteArray(mString);
}
public byte[] GetOctets()
{
return Arrays.Clone(mString);
}
internal override void Encode(DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.GraphicString, mString);
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(mString);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerGraphicString other = asn1Object as DerGraphicString;
if (other == null)
return false;
return Arrays.AreEqual(mString, other.mString);
}
}
}

View File

@ -0,0 +1,148 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der IA5String object - this is an ascii string.
*/
public class DerIA5String
: DerStringBase
{
private readonly string str;
/**
* return a IA5 string from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerIA5String GetInstance(
object obj)
{
if (obj == null || obj is DerIA5String)
{
return (DerIA5String)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an IA5 string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerIA5String GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerIA5String)
{
return GetInstance(o);
}
return new DerIA5String(((Asn1OctetString)o).GetOctets());
}
/**
* basic constructor - with bytes.
*/
public DerIA5String(
byte[] str)
: this(Strings.FromAsciiByteArray(str), false)
{
}
/**
* basic constructor - without validation.
*/
public DerIA5String(
string str)
: this(str, false)
{
}
/**
* Constructor with optional validation.
*
* @param string the base string to wrap.
* @param validate whether or not to check the string.
* @throws ArgumentException if validate is true and the string
* contains characters that should not be in an IA5String.
*/
public DerIA5String(
string str,
bool validate)
{
if (str == null)
throw new ArgumentNullException("str");
if (validate && !IsIA5String(str))
throw new ArgumentException("string contains illegal characters", "str");
this.str = str;
}
public override string GetString()
{
return str;
}
public byte[] GetOctets()
{
return Strings.ToAsciiByteArray(str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.IA5String, GetOctets());
}
protected override int Asn1GetHashCode()
{
return this.str.GetHashCode();
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerIA5String other = asn1Object as DerIA5String;
if (other == null)
return false;
return this.str.Equals(other.str);
}
/**
* return true if the passed in String can be represented without
* loss as an IA5String, false otherwise.
*
* @return true if in printable set, false otherwise.
*/
public static bool IsIA5String(
string str)
{
foreach (char ch in str)
{
if (ch > 0x007f)
{
return false;
}
}
return true;
}
}
}

View File

@ -0,0 +1,243 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.math;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerInteger
: Asn1Object
{
public const string AllowUnsafeProperty = "Org.BouncyCastle.Asn1.AllowUnsafeInteger";
internal static bool AllowUnsafe()
{
string allowUnsafeValue = Platform.GetEnvironmentVariable(AllowUnsafeProperty);
return allowUnsafeValue != null && Platform.EqualsIgnoreCase("true", allowUnsafeValue);
}
internal const int SignExtSigned = -1;
internal const int SignExtUnsigned = 0xFF;
private readonly byte[] bytes;
private readonly int start;
/**
* return an integer from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerInteger GetInstance(
object obj)
{
if (obj == null || obj is DerInteger)
{
return (DerInteger)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an Integer from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param isExplicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerInteger GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
if (obj == null)
throw new ArgumentNullException("obj");
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerInteger)
{
return GetInstance(o);
}
return new DerInteger(Asn1OctetString.GetInstance(o).GetOctets());
}
public DerInteger(int value)
{
this.bytes = BigInteger.ValueOf(value).ToByteArray();
this.start = 0;
}
public DerInteger(long value)
{
this.bytes = BigInteger.ValueOf(value).ToByteArray();
this.start = 0;
}
public DerInteger(BigInteger value)
{
if (value == null)
throw new ArgumentNullException("value");
this.bytes = value.ToByteArray();
this.start = 0;
}
public DerInteger(byte[] bytes)
: this(bytes, true)
{
}
internal DerInteger(byte[] bytes, bool clone)
{
if (IsMalformed(bytes))
throw new ArgumentException("malformed integer", "bytes");
this.bytes = clone ? Arrays.Clone(bytes) : bytes;
this.start = SignBytesToSkip(bytes);
}
/**
* in some cases positive values Get crammed into a space,
* that's not quite big enough...
*/
public BigInteger PositiveValue
{
get { return new BigInteger(1, bytes); }
}
public BigInteger Value
{
get { return new BigInteger(bytes); }
}
public bool HasValue(BigInteger x)
{
return null != x
// Fast check to avoid allocation
&& IntValue(bytes, start, SignExtSigned) == x.IntValue
&& Value.Equals(x);
}
public int IntPositiveValueExact
{
get
{
int count = bytes.Length - start;
if (count > 4 || (count == 4 && 0 != (bytes[start] & 0x80)))
throw new ArithmeticException("ASN.1 Integer out of positive int range");
return IntValue(bytes, start, SignExtUnsigned);
}
}
public int IntValueExact
{
get
{
int count = bytes.Length - start;
if (count > 4)
throw new ArithmeticException("ASN.1 Integer out of int range");
return IntValue(bytes, start, SignExtSigned);
}
}
public long LongValueExact
{
get
{
int count = bytes.Length - start;
if (count > 8)
throw new ArithmeticException("ASN.1 Integer out of long range");
return LongValue(bytes, start, SignExtSigned);
}
}
internal override void Encode(DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.Integer, bytes);
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(bytes);
}
protected override bool Asn1Equals(Asn1Object asn1Object)
{
DerInteger other = asn1Object as DerInteger;
if (other == null)
return false;
return Arrays.AreEqual(this.bytes, other.bytes);
}
public override string ToString()
{
return Value.ToString();
}
internal static int IntValue(byte[] bytes, int start, int signExt)
{
int length = bytes.Length;
int pos = System.Math.Max(start, length - 4);
int val = (sbyte)bytes[pos] & signExt;
while (++pos < length)
{
val = (val << 8) | bytes[pos];
}
return val;
}
internal static long LongValue(byte[] bytes, int start, int signExt)
{
int length = bytes.Length;
int pos = System.Math.Max(start, length - 8);
long val = (sbyte)bytes[pos] & signExt;
while (++pos < length)
{
val = (val << 8) | bytes[pos];
}
return val;
}
/**
* Apply the correct validation for an INTEGER primitive following the BER rules.
*
* @param bytes The raw encoding of the integer.
* @return true if the (in)put fails this validation.
*/
internal static bool IsMalformed(byte[] bytes)
{
switch (bytes.Length)
{
case 0:
return true;
case 1:
return false;
default:
return (sbyte)bytes[0] == ((sbyte)bytes[1] >> 7) && !AllowUnsafe();
}
}
internal static int SignBytesToSkip(byte[] bytes)
{
int pos = 0, last = bytes.Length - 1;
while (pos < last
&& (sbyte)bytes[pos] == ((sbyte)bytes[pos + 1] >> 7))
{
++pos;
}
return pos;
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* A Null object.
*/
public class DerNull
: Asn1Null
{
public static readonly DerNull Instance = new DerNull(0);
byte[] zeroBytes = new byte[0];
[Obsolete("Use static Instance object")]
public DerNull()
{
}
protected internal DerNull(int dummy)
{
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.Null, zeroBytes);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
return asn1Object is DerNull;
}
protected override int Asn1GetHashCode()
{
return -1;
}
}
}

View File

@ -0,0 +1,141 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
*/
public class DerNumericString
: DerStringBase
{
private readonly string str;
/**
* return a Numeric string from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerNumericString GetInstance(
object obj)
{
if (obj == null || obj is DerNumericString)
{
return (DerNumericString)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an Numeric string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerNumericString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerNumericString)
{
return GetInstance(o);
}
return new DerNumericString(Asn1OctetString.GetInstance(o).GetOctets());
}
/**
* basic constructor - with bytes.
*/
public DerNumericString(
byte[] str)
: this(Strings.FromAsciiByteArray(str), false)
{
}
/**
* basic constructor - without validation..
*/
public DerNumericString(
string str)
: this(str, false)
{
}
/**
* Constructor with optional validation.
*
* @param string the base string to wrap.
* @param validate whether or not to check the string.
* @throws ArgumentException if validate is true and the string
* contains characters that should not be in a NumericString.
*/
public DerNumericString(
string str,
bool validate)
{
if (str == null)
throw new ArgumentNullException("str");
if (validate && !IsNumericString(str))
throw new ArgumentException("string contains illegal characters", "str");
this.str = str;
}
public override string GetString()
{
return str;
}
public byte[] GetOctets()
{
return Strings.ToAsciiByteArray(str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.NumericString, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerNumericString other = asn1Object as DerNumericString;
if (other == null)
return false;
return this.str.Equals(other.str);
}
/**
* Return true if the string can be represented as a NumericString ('0'..'9', ' ')
*
* @param str string to validate.
* @return true if numeric, fale otherwise.
*/
public static bool IsNumericString(
string str)
{
foreach (char ch in str)
{
if (ch > 0x007f || (ch != ' ' && !char.IsDigit(ch)))
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,365 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.math;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerObjectIdentifier
: Asn1Object
{
private readonly string identifier;
private byte[] body = null;
/**
* return an Oid from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerObjectIdentifier GetInstance(object obj)
{
if (obj == null || obj is DerObjectIdentifier)
return (DerObjectIdentifier)obj;
if (obj is Asn1Encodable)
{
Asn1Object asn1Obj = ((Asn1Encodable)obj).ToAsn1Object();
if (asn1Obj is DerObjectIdentifier)
return (DerObjectIdentifier)asn1Obj;
}
if (obj is byte[])
return FromOctetString((byte[])obj);
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* return an object Identifier from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerObjectIdentifier GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
Asn1Object o = obj.GetObject();
if (explicitly || o is DerObjectIdentifier)
{
return GetInstance(o);
}
return FromOctetString(Asn1OctetString.GetInstance(o).GetOctets());
}
public DerObjectIdentifier(
string identifier)
{
if (identifier == null)
throw new ArgumentNullException("identifier");
if (!IsValidIdentifier(identifier))
throw new FormatException("string " + identifier + " not an OID");
this.identifier = identifier;
}
internal DerObjectIdentifier(DerObjectIdentifier oid, string branchID)
{
if (!IsValidBranchID(branchID, 0))
throw new ArgumentException("string " + branchID + " not a valid OID branch", "branchID");
this.identifier = oid.Id + "." + branchID;
}
// TODO Change to ID?
public string Id
{
get { return identifier; }
}
public virtual DerObjectIdentifier Branch(string branchID)
{
return new DerObjectIdentifier(this, branchID);
}
/**
* Return true if this oid is an extension of the passed in branch, stem.
* @param stem the arc or branch that is a possible parent.
* @return true if the branch is on the passed in stem, false otherwise.
*/
public virtual bool On(DerObjectIdentifier stem)
{
string id = Id, stemId = stem.Id;
return id.Length > stemId.Length && id[stemId.Length] == '.' && Platform.StartsWith(id, stemId);
}
internal DerObjectIdentifier(byte[] bytes)
{
this.identifier = MakeOidStringFromBytes(bytes);
this.body = Arrays.Clone(bytes);
}
private void WriteField(
Stream outputStream,
long fieldValue)
{
byte[] result = new byte[9];
int pos = 8;
result[pos] = (byte)(fieldValue & 0x7f);
while (fieldValue >= (1L << 7))
{
fieldValue >>= 7;
result[--pos] = (byte)((fieldValue & 0x7f) | 0x80);
}
outputStream.Write(result, pos, 9 - pos);
}
private void WriteField(
Stream outputStream,
BigInteger fieldValue)
{
int byteCount = (fieldValue.BitLength + 6) / 7;
if (byteCount == 0)
{
outputStream.WriteByte(0);
}
else
{
BigInteger tmpValue = fieldValue;
byte[] tmp = new byte[byteCount];
for (int i = byteCount - 1; i >= 0; i--)
{
tmp[i] = (byte)((tmpValue.IntValue & 0x7f) | 0x80);
tmpValue = tmpValue.ShiftRight(7);
}
tmp[byteCount - 1] &= 0x7f;
outputStream.Write(tmp, 0, tmp.Length);
}
}
private void DoOutput(MemoryStream bOut)
{
OidTokenizer tok = new OidTokenizer(identifier);
string token = tok.NextToken();
int first = int.Parse(token) * 40;
token = tok.NextToken();
if (token.Length <= 18)
{
WriteField(bOut, first + Int64.Parse(token));
}
else
{
WriteField(bOut, new BigInteger(token).Add(BigInteger.ValueOf(first)));
}
while (tok.HasMoreTokens)
{
token = tok.NextToken();
if (token.Length <= 18)
{
WriteField(bOut, Int64.Parse(token));
}
else
{
WriteField(bOut, new BigInteger(token));
}
}
}
internal byte[] GetBody()
{
lock (this)
{
if (body == null)
{
MemoryStream bOut = new MemoryStream();
DoOutput(bOut);
body = bOut.ToArray();
}
}
return body;
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.ObjectIdentifier, GetBody());
}
protected override int Asn1GetHashCode()
{
return identifier.GetHashCode();
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerObjectIdentifier other = asn1Object as DerObjectIdentifier;
if (other == null)
return false;
return this.identifier.Equals(other.identifier);
}
public override string ToString()
{
return identifier;
}
private static bool IsValidBranchID(string branchID, int start)
{
int digitCount = 0;
int pos = branchID.Length;
while (--pos >= start)
{
char ch = branchID[pos];
if (ch == '.')
{
if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0'))
return false;
digitCount = 0;
}
else if ('0' <= ch && ch <= '9')
{
++digitCount;
}
else
{
return false;
}
}
if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0'))
return false;
return true;
}
private static bool IsValidIdentifier(string identifier)
{
if (identifier.Length < 3 || identifier[1] != '.')
return false;
char first = identifier[0];
if (first < '0' || first > '2')
return false;
return IsValidBranchID(identifier, 2);
}
private const long LONG_LIMIT = (long.MaxValue >> 7) - 0x7f;
private static string MakeOidStringFromBytes(
byte[] bytes)
{
StringBuilder objId = new StringBuilder();
long value = 0;
BigInteger bigValue = null;
bool first = true;
for (int i = 0; i != bytes.Length; i++)
{
int b = bytes[i];
if (value <= LONG_LIMIT)
{
value += (b & 0x7f);
if ((b & 0x80) == 0) // end of number reached
{
if (first)
{
if (value < 40)
{
objId.Append('0');
}
else if (value < 80)
{
objId.Append('1');
value -= 40;
}
else
{
objId.Append('2');
value -= 80;
}
first = false;
}
objId.Append('.');
objId.Append(value);
value = 0;
}
else
{
value <<= 7;
}
}
else
{
if (bigValue == null)
{
bigValue = BigInteger.ValueOf(value);
}
bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7f));
if ((b & 0x80) == 0)
{
if (first)
{
objId.Append('2');
bigValue = bigValue.Subtract(BigInteger.ValueOf(80));
first = false;
}
objId.Append('.');
objId.Append(bigValue);
bigValue = null;
value = 0;
}
else
{
bigValue = bigValue.ShiftLeft(7);
}
}
}
return objId.ToString();
}
private static readonly DerObjectIdentifier[] cache = new DerObjectIdentifier[1024];
internal static DerObjectIdentifier FromOctetString(byte[] enc)
{
int hashCode = Arrays.GetHashCode(enc);
int first = hashCode & 1023;
lock (cache)
{
DerObjectIdentifier entry = cache[first];
if (entry != null && Arrays.AreEqual(enc, entry.GetBody()))
{
return entry;
}
return cache[first] = new DerObjectIdentifier(enc);
}
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerOctetString
: Asn1OctetString
{
/// <param name="str">The octets making up the octet string.</param>
public DerOctetString(
byte[] str)
: base(str)
{
}
public DerOctetString(IAsn1Convertible obj)
: this(obj.ToAsn1Object())
{
}
public DerOctetString(Asn1Encodable obj)
: base(obj.GetEncoded(Asn1Encodable.Der))
{
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.OctetString, str);
}
internal static void Encode(
DerOutputStream derOut,
byte[] bytes,
int offset,
int length)
{
derOut.WriteEncoded(Asn1Tags.OctetString, bytes, offset, length);
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerOctetStringParser
: Asn1OctetStringParser
{
private readonly DefiniteLengthInputStream stream;
internal DerOctetStringParser(
DefiniteLengthInputStream stream)
{
this.stream = stream;
}
public Stream GetOctetStream()
{
return stream;
}
public Asn1Object ToAsn1Object()
{
try
{
return new DerOctetString(stream.ToArray());
}
catch (IOException e)
{
throw new InvalidOperationException("IOException converting stream to byte array: " + e.Message, e);
}
}
}
}

View File

@ -0,0 +1,174 @@
using BrowserPass.BouncyCastle.asn1.util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerOutputStream
: FilterStream
{
public DerOutputStream(Stream os)
: base(os)
{
}
private void WriteLength(
int length)
{
if (length > 127)
{
int size = 1;
uint val = (uint)length;
while ((val >>= 8) != 0)
{
size++;
}
WriteByte((byte)(size | 0x80));
for (int i = (size - 1) * 8; i >= 0; i -= 8)
{
WriteByte((byte)(length >> i));
}
}
else
{
WriteByte((byte)length);
}
}
internal void WriteEncoded(
int tag,
byte[] bytes)
{
WriteByte((byte)tag);
WriteLength(bytes.Length);
Write(bytes, 0, bytes.Length);
}
internal void WriteEncoded(
int tag,
byte first,
byte[] bytes)
{
WriteByte((byte)tag);
WriteLength(bytes.Length + 1);
WriteByte(first);
Write(bytes, 0, bytes.Length);
}
internal void WriteEncoded(
int tag,
byte[] bytes,
int offset,
int length)
{
WriteByte((byte)tag);
WriteLength(length);
Write(bytes, offset, length);
}
internal void WriteTag(
int flags,
int tagNo)
{
if (tagNo < 31)
{
WriteByte((byte)(flags | tagNo));
}
else
{
WriteByte((byte)(flags | 0x1f));
if (tagNo < 128)
{
WriteByte((byte)tagNo);
}
else
{
byte[] stack = new byte[5];
int pos = stack.Length;
stack[--pos] = (byte)(tagNo & 0x7F);
do
{
tagNo >>= 7;
stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
}
while (tagNo > 127);
Write(stack, pos, stack.Length - pos);
}
}
}
internal void WriteEncoded(
int flags,
int tagNo,
byte[] bytes)
{
WriteTag(flags, tagNo);
WriteLength(bytes.Length);
Write(bytes, 0, bytes.Length);
}
protected void WriteNull()
{
WriteByte(Asn1Tags.Null);
WriteByte(0x00);
}
[Obsolete("Use version taking an Asn1Encodable arg instead")]
public virtual void WriteObject(
object obj)
{
if (obj == null)
{
WriteNull();
}
else if (obj is Asn1Object)
{
((Asn1Object)obj).Encode(this);
}
else if (obj is Asn1Encodable)
{
((Asn1Encodable)obj).ToAsn1Object().Encode(this);
}
else
{
throw new IOException("object not Asn1Object");
}
}
public virtual void WriteObject(
Asn1Encodable obj)
{
if (obj == null)
{
WriteNull();
}
else
{
obj.ToAsn1Object().Encode(this);
}
}
public virtual void WriteObject(
Asn1Object obj)
{
if (obj == null)
{
WriteNull();
}
else
{
obj.Encode(this);
}
}
}
}

View File

@ -0,0 +1,166 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der PrintableString object.
*/
public class DerPrintableString
: DerStringBase
{
private readonly string str;
/**
* return a printable string from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerPrintableString GetInstance(
object obj)
{
if (obj == null || obj is DerPrintableString)
{
return (DerPrintableString)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a Printable string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerPrintableString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerPrintableString)
{
return GetInstance(o);
}
return new DerPrintableString(Asn1OctetString.GetInstance(o).GetOctets());
}
/**
* basic constructor - byte encoded string.
*/
public DerPrintableString(
byte[] str)
: this(Strings.FromAsciiByteArray(str), false)
{
}
/**
* basic constructor - this does not validate the string
*/
public DerPrintableString(
string str)
: this(str, false)
{
}
/**
* Constructor with optional validation.
*
* @param string the base string to wrap.
* @param validate whether or not to check the string.
* @throws ArgumentException if validate is true and the string
* contains characters that should not be in a PrintableString.
*/
public DerPrintableString(
string str,
bool validate)
{
if (str == null)
throw new ArgumentNullException("str");
if (validate && !IsPrintableString(str))
throw new ArgumentException("string contains illegal characters", "str");
this.str = str;
}
public override string GetString()
{
return str;
}
public byte[] GetOctets()
{
return Strings.ToAsciiByteArray(str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.PrintableString, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerPrintableString other = asn1Object as DerPrintableString;
if (other == null)
return false;
return this.str.Equals(other.str);
}
/**
* return true if the passed in String can be represented without
* loss as a PrintableString, false otherwise.
*
* @return true if in printable set, false otherwise.
*/
public static bool IsPrintableString(
string str)
{
foreach (char ch in str)
{
if (ch > 0x007f)
return false;
if (char.IsLetterOrDigit(ch))
continue;
// if (char.IsPunctuation(ch))
// continue;
switch (ch)
{
case ' ':
case '\'':
case '(':
case ')':
case '+':
case '-':
case '.':
case ':':
case '=':
case '?':
case '/':
case ',':
continue;
}
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,76 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerSequence
: Asn1Sequence
{
public static readonly DerSequence Empty = new DerSequence();
public static DerSequence FromVector(Asn1EncodableVector elementVector)
{
return elementVector.Count < 1 ? Empty : new DerSequence(elementVector);
}
/**
* create an empty sequence
*/
public DerSequence()
: base()
{
}
/**
* create a sequence containing one object
*/
public DerSequence(Asn1Encodable element)
: base(element)
{
}
public DerSequence(params Asn1Encodable[] elements)
: base(elements)
{
}
/**
* create a sequence containing a vector of objects.
*/
public DerSequence(Asn1EncodableVector elementVector)
: base(elementVector)
{
}
/*
* A note on the implementation:
* <p>
* As Der requires the constructed, definite-length model to
* be used for structured types, this varies slightly from the
* ASN.1 descriptions given. Rather than just outputing Sequence,
* we also have to specify Constructed, and the objects length.
*/
internal override void Encode(DerOutputStream derOut)
{
// TODO Intermediate buffer could be avoided if we could calculate expected length
MemoryStream bOut = new MemoryStream();
DerOutputStream dOut = new DerOutputStream(bOut);
foreach (Asn1Encodable obj in this)
{
dOut.WriteObject(obj);
}
Platform.Dispose(dOut);
byte[] bytes = bOut.ToArray();
derOut.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, bytes);
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerSequenceParser
: Asn1SequenceParser
{
private readonly Asn1StreamParser _parser;
internal DerSequenceParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new DerSequence(_parser.ReadVector());
}
}
}

View File

@ -0,0 +1,94 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* A Der encoded set object
*/
public class DerSet
: Asn1Set
{
public static readonly DerSet Empty = new DerSet();
public static DerSet FromVector(Asn1EncodableVector elementVector)
{
return elementVector.Count < 1 ? Empty : new DerSet(elementVector);
}
internal static DerSet FromVector(Asn1EncodableVector elementVector, bool needsSorting)
{
return elementVector.Count < 1 ? Empty : new DerSet(elementVector, needsSorting);
}
/**
* create an empty set
*/
public DerSet()
: base()
{
}
/**
* @param obj - a single object that makes up the set.
*/
public DerSet(Asn1Encodable element)
: base(element)
{
}
public DerSet(params Asn1Encodable[] elements)
: base(elements)
{
Sort();
}
/**
* @param v - a vector of objects making up the set.
*/
public DerSet(Asn1EncodableVector elementVector)
: this(elementVector, true)
{
}
internal DerSet(Asn1EncodableVector elementVector, bool needsSorting)
: base(elementVector)
{
if (needsSorting)
{
Sort();
}
}
/*
* A note on the implementation:
* <p>
* As Der requires the constructed, definite-length model to
* be used for structured types, this varies slightly from the
* ASN.1 descriptions given. Rather than just outputing Set,
* we also have to specify Constructed, and the objects length.
*/
internal override void Encode(DerOutputStream derOut)
{
// TODO Intermediate buffer could be avoided if we could calculate expected length
MemoryStream bOut = new MemoryStream();
DerOutputStream dOut = new DerOutputStream(bOut);
foreach (Asn1Encodable obj in this)
{
dOut.WriteObject(obj);
}
Platform.Dispose(dOut);
byte[] bytes = bOut.ToArray();
derOut.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, bytes);
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerSetParser
: Asn1SetParser
{
private readonly Asn1StreamParser _parser;
internal DerSetParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new DerSet(_parser.ReadVector(), false);
}
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public abstract class DerStringBase
: Asn1Object, IAsn1String
{
protected DerStringBase()
{
}
public abstract string GetString();
public override string ToString()
{
return GetString();
}
protected override int Asn1GetHashCode()
{
return GetString().GetHashCode();
}
}
}

View File

@ -0,0 +1,106 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der T61String (also the teletex string) - 8-bit characters
*/
public class DerT61String
: DerStringBase
{
private readonly string str;
/**
* return a T61 string from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerT61String GetInstance(
object obj)
{
if (obj == null || obj is DerT61String)
{
return (DerT61String)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an T61 string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerT61String GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerT61String)
{
return GetInstance(o);
}
return new DerT61String(Asn1OctetString.GetInstance(o).GetOctets());
}
/**
* basic constructor - with bytes.
*/
public DerT61String(
byte[] str)
: this(Strings.FromByteArray(str))
{
}
/**
* basic constructor - with string.
*/
public DerT61String(
string str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
return str;
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.T61String, GetOctets());
}
public byte[] GetOctets()
{
return Strings.ToByteArray(str);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerT61String other = asn1Object as DerT61String;
if (other == null)
return false;
return this.str.Equals(other.str);
}
}
}

View File

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* DER TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
* rules (as with sequences).
*/
public class DerTaggedObject
: Asn1TaggedObject
{
/**
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
public DerTaggedObject(
int tagNo,
Asn1Encodable obj)
: base(tagNo, obj)
{
}
/**
* @param explicitly true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
public DerTaggedObject(
bool explicitly,
int tagNo,
Asn1Encodable obj)
: base(explicitly, tagNo, obj)
{
}
/**
* create an implicitly tagged object that contains a zero
* length sequence.
*/
public DerTaggedObject(
int tagNo)
: base(false, tagNo, DerSequence.Empty)
{
}
internal override void Encode(
DerOutputStream derOut)
{
if (!IsEmpty())
{
byte[] bytes = obj.GetDerEncoded();
if (explicitly)
{
derOut.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, bytes);
}
else
{
//
// need to mark constructed types... (preserve Constructed tag)
//
int flags = (bytes[0] & Asn1Tags.Constructed) | Asn1Tags.Tagged;
derOut.WriteTag(flags, tagNo);
derOut.Write(bytes, 1, bytes.Length - 1);
}
}
else
{
derOut.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, new byte[0]);
}
}
}
}

View File

@ -0,0 +1,109 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der UniversalString object.
*/
public class DerUniversalString
: DerStringBase
{
private static readonly char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private readonly byte[] str;
/**
* return a Universal string from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerUniversalString GetInstance(
object obj)
{
if (obj == null || obj is DerUniversalString)
{
return (DerUniversalString)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a Universal string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerUniversalString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerUniversalString)
{
return GetInstance(o);
}
return new DerUniversalString(Asn1OctetString.GetInstance(o).GetOctets());
}
/**
* basic constructor - byte encoded string.
*/
public DerUniversalString(
byte[] str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
StringBuilder buffer = new StringBuilder("#");
byte[] enc = GetDerEncoded();
for (int i = 0; i != enc.Length; i++)
{
uint ubyte = enc[i];
buffer.Append(table[(ubyte >> 4) & 0xf]);
buffer.Append(table[enc[i] & 0xf]);
}
return buffer.ToString();
}
public byte[] GetOctets()
{
return (byte[])str.Clone();
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.UniversalString, this.str);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerUniversalString other = asn1Object as DerUniversalString;
if (other == null)
return false;
// return this.GetString().Equals(other.GetString());
return Arrays.AreEqual(this.str, other.str);
}
}
}

View File

@ -0,0 +1,270 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* UTC time object.
*/
public class DerUtcTime
: Asn1Object
{
private readonly string time;
/**
* return an UTC Time from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerUtcTime GetInstance(
object obj)
{
if (obj == null || obj is DerUtcTime)
{
return (DerUtcTime)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an UTC Time from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerUtcTime GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerUtcTime)
{
return GetInstance(o);
}
return new DerUtcTime(((Asn1OctetString)o).GetOctets());
}
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
* what you want to use, otherwise we'll try to deal with whatever Gets read from
* the input stream... (this is why the input format is different from the GetTime()
* method output).
* <p>
* @param time the time string.</p>
*/
public DerUtcTime(
string time)
{
if (time == null)
throw new ArgumentNullException("time");
this.time = time;
try
{
ToDateTime();
}
catch (FormatException e)
{
throw new ArgumentException("invalid date string: " + e.Message);
}
}
/**
* base constructor from a DateTime object
*/
public DerUtcTime(
DateTime time)
{
#if PORTABLE
this.time = time.ToUniversalTime().ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z";
#else
this.time = time.ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z";
#endif
}
internal DerUtcTime(
byte[] bytes)
{
//
// explicitly convert to characters
//
this.time = Strings.FromAsciiByteArray(bytes);
}
// public DateTime ToDateTime()
// {
// string tm = this.AdjustedTimeString;
//
// return new DateTime(
// Int16.Parse(tm.Substring(0, 4)),
// Int16.Parse(tm.Substring(4, 2)),
// Int16.Parse(tm.Substring(6, 2)),
// Int16.Parse(tm.Substring(8, 2)),
// Int16.Parse(tm.Substring(10, 2)),
// Int16.Parse(tm.Substring(12, 2)));
// }
/**
* return the time as a date based on whatever a 2 digit year will return. For
* standardised processing use ToAdjustedDateTime().
*
* @return the resulting date
* @exception ParseException if the date string cannot be parsed.
*/
public DateTime ToDateTime()
{
return ParseDateString(TimeString, @"yyMMddHHmmss'GMT'zzz");
}
/**
* return the time as an adjusted date
* in the range of 1950 - 2049.
*
* @return a date in the range of 1950 to 2049.
* @exception ParseException if the date string cannot be parsed.
*/
public DateTime ToAdjustedDateTime()
{
return ParseDateString(AdjustedTimeString, @"yyyyMMddHHmmss'GMT'zzz");
}
private DateTime ParseDateString(
string dateStr,
string formatStr)
{
DateTime dt = DateTime.ParseExact(
dateStr,
formatStr,
DateTimeFormatInfo.InvariantInfo);
return dt.ToUniversalTime();
}
/**
* return the time - always in the form of
* YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
* </pre>
* To read in the time and Get a date which is compatible with our local
* time zone.</p>
* <p>
* <b>Note:</b> In some cases, due to the local date processing, this
* may lead to unexpected results. If you want to stick the normal
* convention of 1950 to 2049 use the GetAdjustedTime() method.</p>
*/
public string TimeString
{
get
{
//
// standardise the format.
//
if (time.IndexOf('-') < 0 && time.IndexOf('+') < 0)
{
if (time.Length == 11)
{
return time.Substring(0, 10) + "00GMT+00:00";
}
else
{
return time.Substring(0, 12) + "GMT+00:00";
}
}
else
{
int index = time.IndexOf('-');
if (index < 0)
{
index = time.IndexOf('+');
}
string d = time;
if (index == time.Length - 3)
{
d += "00";
}
if (index == 10)
{
return d.Substring(0, 10) + "00GMT" + d.Substring(10, 3) + ":" + d.Substring(13, 2);
}
else
{
return d.Substring(0, 12) + "GMT" + d.Substring(12, 3) + ":" + d.Substring(15, 2);
}
}
}
}
[Obsolete("Use 'AdjustedTimeString' property instead")]
public string AdjustedTime
{
get { return AdjustedTimeString; }
}
/// <summary>
/// Return a time string as an adjusted date with a 4 digit year.
/// This goes in the range of 1950 - 2049.
/// </summary>
public string AdjustedTimeString
{
get
{
string d = TimeString;
string c = d[0] < '5' ? "20" : "19";
return c + d;
}
}
private byte[] GetOctets()
{
return Strings.ToAsciiByteArray(time);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.UtcTime, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerUtcTime other = asn1Object as DerUtcTime;
if (other == null)
return false;
return this.time.Equals(other.time);
}
protected override int Asn1GetHashCode()
{
return time.GetHashCode();
}
public override string ToString()
{
return time;
}
}
}

View File

@ -0,0 +1,100 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der UTF8String object.
*/
public class DerUtf8String
: DerStringBase
{
private readonly string str;
/**
* return an UTF8 string from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerUtf8String GetInstance(
object obj)
{
if (obj == null || obj is DerUtf8String)
{
return (DerUtf8String)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an UTF8 string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerUtf8String GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerUtf8String)
{
return GetInstance(o);
}
return new DerUtf8String(Asn1OctetString.GetInstance(o).GetOctets());
}
/**
* basic constructor - byte encoded string.
*/
public DerUtf8String(
byte[] str)
: this(Encoding.UTF8.GetString(str, 0, str.Length))
{
}
/**
* basic constructor
*/
public DerUtf8String(
string str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
return str;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerUtf8String other = asn1Object as DerUtf8String;
if (other == null)
return false;
return this.str.Equals(other.str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.Utf8String, Encoding.UTF8.GetBytes(str));
}
}
}

View File

@ -0,0 +1,107 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public class DerVideotexString
: DerStringBase
{
private readonly byte[] mString;
/**
* return a Videotex String from the passed in object
*
* @param obj a DERVideotexString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERVideotexString instance, or null.
*/
public static DerVideotexString GetInstance(object obj)
{
if (obj == null || obj is DerVideotexString)
{
return (DerVideotexString)obj;
}
if (obj is byte[])
{
try
{
return (DerVideotexString)FromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj");
}
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* return a Videotex String from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERVideotexString instance, or null.
*/
public static DerVideotexString GetInstance(Asn1TaggedObject obj, bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerVideotexString)
{
return GetInstance(o);
}
return new DerVideotexString(((Asn1OctetString)o).GetOctets());
}
/**
* basic constructor - with bytes.
* @param string the byte encoding of the characters making up the string.
*/
public DerVideotexString(byte[] encoding)
{
this.mString = Arrays.Clone(encoding);
}
public override string GetString()
{
return Strings.FromByteArray(mString);
}
public byte[] GetOctets()
{
return Arrays.Clone(mString);
}
internal override void Encode(DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.VideotexString, mString);
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(mString);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerVideotexString other = asn1Object as DerVideotexString;
if (other == null)
return false;
return Arrays.AreEqual(mString, other.mString);
}
}
}

View File

@ -0,0 +1,114 @@
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Der VisibleString object.
*/
public class DerVisibleString
: DerStringBase
{
private readonly string str;
/**
* return a Visible string from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerVisibleString GetInstance(
object obj)
{
if (obj == null || obj is DerVisibleString)
{
return (DerVisibleString)obj;
}
if (obj is Asn1OctetString)
{
return new DerVisibleString(((Asn1OctetString)obj).GetOctets());
}
if (obj is Asn1TaggedObject)
{
return GetInstance(((Asn1TaggedObject)obj).GetObject());
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a Visible string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerVisibleString GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(obj.GetObject());
}
/**
* basic constructor - byte encoded string.
*/
public DerVisibleString(
byte[] str)
: this(Strings.FromAsciiByteArray(str))
{
}
/**
* basic constructor
*/
public DerVisibleString(
string str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
return str;
}
public byte[] GetOctets()
{
return Strings.ToAsciiByteArray(str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.VisibleString, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerVisibleString other = asn1Object as DerVisibleString;
if (other == null)
return false;
return this.str.Equals(other.str);
}
protected override int Asn1GetHashCode()
{
return this.str.GetHashCode();
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
public interface IAsn1ApplicationSpecificParser
: IAsn1Convertible
{
IAsn1Convertible ReadObject();
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* Marker interface for CHOICE objects - if you implement this in a roll-your-own
* object, any attempt to tag the object implicitly will convert the tag to an
* explicit one as the encoding rules require.
* <p>
* If you use this interface your class should also implement the getInstance
* pattern which takes a tag object and the tagging mode used.
* </p>
*/
public interface IAsn1Choice
{
// marker interface
}
}

View File

@ -0,0 +1,7 @@
namespace BrowserPass.BouncyCastle.asn1
{
public interface IAsn1Convertible
{
Asn1Object ToAsn1Object();
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* basic interface for Der string objects.
*/
public interface IAsn1String
{
string GetString();
}
}

View File

@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
class IndefiniteLengthInputStream
: LimitedInputStream
{
private int _lookAhead;
private bool _eofOn00 = true;
internal IndefiniteLengthInputStream(
Stream inStream,
int limit)
: base(inStream, limit)
{
_lookAhead = RequireByte();
CheckForEof();
}
internal void SetEofOn00(
bool eofOn00)
{
_eofOn00 = eofOn00;
if (_eofOn00)
{
CheckForEof();
}
}
private bool CheckForEof()
{
if (_lookAhead == 0x00)
{
int extra = RequireByte();
if (extra != 0)
{
throw new IOException("malformed end-of-contents marker");
}
_lookAhead = -1;
SetParentEofDetect(true);
return true;
}
return _lookAhead < 0;
}
public override int Read(
byte[] buffer,
int offset,
int count)
{
// Only use this optimisation if we aren't checking for 00
if (_eofOn00 || count <= 1)
return base.Read(buffer, offset, count);
if (_lookAhead < 0)
return 0;
int numRead = _in.Read(buffer, offset + 1, count - 1);
if (numRead <= 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
buffer[offset] = (byte)_lookAhead;
_lookAhead = RequireByte();
return numRead + 1;
}
public override int ReadByte()
{
if (_eofOn00 && CheckForEof())
return -1;
int result = _lookAhead;
_lookAhead = RequireByte();
return result;
}
private int RequireByte()
{
int b = _in.ReadByte();
if (b < 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
return b;
}
}
}

View File

@ -0,0 +1,36 @@
using BrowserPass.BouncyCastle.util.io;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
internal abstract class LimitedInputStream
: BaseInputStream
{
protected readonly Stream _in;
private int _limit;
internal LimitedInputStream(Stream inStream, int limit)
{
this._in = inStream;
this._limit = limit;
}
internal virtual int Limit
{
get { return _limit; }
}
protected virtual void SetParentEofDetect(bool on)
{
if (_in is IndefiniteLengthInputStream)
{
((IndefiniteLengthInputStream)_in).SetEofOn00(on);
}
}
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1
{
/**
* class for breaking up an Oid into it's component tokens, ala
* java.util.StringTokenizer. We need this class as some of the
* lightweight Java environment don't support classes like
* StringTokenizer.
*/
public class OidTokenizer
{
private string oid;
private int index;
public OidTokenizer(
string oid)
{
this.oid = oid;
}
public bool HasMoreTokens
{
get { return index != -1; }
}
public string NextToken()
{
if (index == -1)
{
return null;
}
int end = oid.IndexOf('.', index);
if (end == -1)
{
string lastToken = oid.Substring(index);
index = -1;
return lastToken;
}
string nextToken = oid.Substring(index, end - index);
index = end + 1;
return nextToken;
}
}
}

View File

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.cryptopro
{
public abstract class CryptoProObjectIdentifiers
{
// GOST Algorithms OBJECT IDENTIFIERS :
// { iso(1) member-body(2) ru(643) rans(2) cryptopro(2)}
public const string GostID = "1.2.643.2.2";
public static readonly DerObjectIdentifier GostR3411 = new DerObjectIdentifier(GostID + ".9");
public static readonly DerObjectIdentifier GostR3411Hmac = new DerObjectIdentifier(GostID + ".10");
public static readonly DerObjectIdentifier GostR28147Cbc = new DerObjectIdentifier(GostID + ".21");
public static readonly DerObjectIdentifier ID_Gost28147_89_CryptoPro_A_ParamSet = new DerObjectIdentifier(GostID + ".31.1");
public static readonly DerObjectIdentifier GostR3410x94 = new DerObjectIdentifier(GostID + ".20");
public static readonly DerObjectIdentifier GostR3410x2001 = new DerObjectIdentifier(GostID + ".19");
public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x94 = new DerObjectIdentifier(GostID + ".4");
public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x2001 = new DerObjectIdentifier(GostID + ".3");
// { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) hashes(30) }
public static readonly DerObjectIdentifier GostR3411x94CryptoProParamSet = new DerObjectIdentifier(GostID + ".30.1");
// { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) signs(32) }
public static readonly DerObjectIdentifier GostR3410x94CryptoProA = new DerObjectIdentifier(GostID + ".32.2");
public static readonly DerObjectIdentifier GostR3410x94CryptoProB = new DerObjectIdentifier(GostID + ".32.3");
public static readonly DerObjectIdentifier GostR3410x94CryptoProC = new DerObjectIdentifier(GostID + ".32.4");
public static readonly DerObjectIdentifier GostR3410x94CryptoProD = new DerObjectIdentifier(GostID + ".32.5");
// { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) exchanges(33) }
public static readonly DerObjectIdentifier GostR3410x94CryptoProXchA = new DerObjectIdentifier(GostID + ".33.1");
public static readonly DerObjectIdentifier GostR3410x94CryptoProXchB = new DerObjectIdentifier(GostID + ".33.2");
public static readonly DerObjectIdentifier GostR3410x94CryptoProXchC = new DerObjectIdentifier(GostID + ".33.3");
//{ iso(1) member-body(2)ru(643) rans(2) cryptopro(2) ecc-signs(35) }
public static readonly DerObjectIdentifier GostR3410x2001CryptoProA = new DerObjectIdentifier(GostID + ".35.1");
public static readonly DerObjectIdentifier GostR3410x2001CryptoProB = new DerObjectIdentifier(GostID + ".35.2");
public static readonly DerObjectIdentifier GostR3410x2001CryptoProC = new DerObjectIdentifier(GostID + ".35.3");
// { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) ecc-exchanges(36) }
public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchA = new DerObjectIdentifier(GostID + ".36.0");
public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchB = new DerObjectIdentifier(GostID + ".36.1");
public static readonly DerObjectIdentifier GostElSgDH3410Default = new DerObjectIdentifier(GostID + ".36.0");
public static readonly DerObjectIdentifier GostElSgDH3410x1 = new DerObjectIdentifier(GostID + ".36.1");
}
}

View File

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.gm
{
public abstract class GMObjectIdentifiers
{
public static readonly DerObjectIdentifier sm_scheme = new DerObjectIdentifier("1.2.156.10197.1");
public static readonly DerObjectIdentifier sm6_ecb = sm_scheme.Branch("101.1");
public static readonly DerObjectIdentifier sm6_cbc = sm_scheme.Branch("101.2");
public static readonly DerObjectIdentifier sm6_ofb128 = sm_scheme.Branch("101.3");
public static readonly DerObjectIdentifier sm6_cfb128 = sm_scheme.Branch("101.4");
public static readonly DerObjectIdentifier sm1_ecb = sm_scheme.Branch("102.1");
public static readonly DerObjectIdentifier sm1_cbc = sm_scheme.Branch("102.2");
public static readonly DerObjectIdentifier sm1_ofb128 = sm_scheme.Branch("102.3");
public static readonly DerObjectIdentifier sm1_cfb128 = sm_scheme.Branch("102.4");
public static readonly DerObjectIdentifier sm1_cfb1 = sm_scheme.Branch("102.5");
public static readonly DerObjectIdentifier sm1_cfb8 = sm_scheme.Branch("102.6");
public static readonly DerObjectIdentifier ssf33_ecb = sm_scheme.Branch("103.1");
public static readonly DerObjectIdentifier ssf33_cbc = sm_scheme.Branch("103.2");
public static readonly DerObjectIdentifier ssf33_ofb128 = sm_scheme.Branch("103.3");
public static readonly DerObjectIdentifier ssf33_cfb128 = sm_scheme.Branch("103.4");
public static readonly DerObjectIdentifier ssf33_cfb1 = sm_scheme.Branch("103.5");
public static readonly DerObjectIdentifier ssf33_cfb8 = sm_scheme.Branch("103.6");
public static readonly DerObjectIdentifier sms4_ecb = sm_scheme.Branch("104.1");
public static readonly DerObjectIdentifier sms4_cbc = sm_scheme.Branch("104.2");
public static readonly DerObjectIdentifier sms4_ofb128 = sm_scheme.Branch("104.3");
public static readonly DerObjectIdentifier sms4_cfb128 = sm_scheme.Branch("104.4");
public static readonly DerObjectIdentifier sms4_cfb1 = sm_scheme.Branch("104.5");
public static readonly DerObjectIdentifier sms4_cfb8 = sm_scheme.Branch("104.6");
public static readonly DerObjectIdentifier sms4_ctr = sm_scheme.Branch("104.7");
public static readonly DerObjectIdentifier sms4_gcm = sm_scheme.Branch("104.8");
public static readonly DerObjectIdentifier sms4_ccm = sm_scheme.Branch("104.9");
public static readonly DerObjectIdentifier sms4_xts = sm_scheme.Branch("104.10");
public static readonly DerObjectIdentifier sms4_wrap = sm_scheme.Branch("104.11");
public static readonly DerObjectIdentifier sms4_wrap_pad = sm_scheme.Branch("104.12");
public static readonly DerObjectIdentifier sms4_ocb = sm_scheme.Branch("104.100");
public static readonly DerObjectIdentifier sm5 = sm_scheme.Branch("201");
public static readonly DerObjectIdentifier sm2p256v1 = sm_scheme.Branch("301");
public static readonly DerObjectIdentifier sm2sign = sm_scheme.Branch("301.1");
public static readonly DerObjectIdentifier sm2exchange = sm_scheme.Branch("301.2");
public static readonly DerObjectIdentifier sm2encrypt = sm_scheme.Branch("301.3");
public static readonly DerObjectIdentifier wapip192v1 = sm_scheme.Branch("301.101");
public static readonly DerObjectIdentifier sm2encrypt_recommendedParameters = sm2encrypt.Branch("1");
public static readonly DerObjectIdentifier sm2encrypt_specifiedParameters = sm2encrypt.Branch("2");
public static readonly DerObjectIdentifier sm2encrypt_with_sm3 = sm2encrypt.Branch("2.1");
public static readonly DerObjectIdentifier sm2encrypt_with_sha1 = sm2encrypt.Branch("2.2");
public static readonly DerObjectIdentifier sm2encrypt_with_sha224 = sm2encrypt.Branch("2.3");
public static readonly DerObjectIdentifier sm2encrypt_with_sha256 = sm2encrypt.Branch("2.4");
public static readonly DerObjectIdentifier sm2encrypt_with_sha384 = sm2encrypt.Branch("2.5");
public static readonly DerObjectIdentifier sm2encrypt_with_sha512 = sm2encrypt.Branch("2.6");
public static readonly DerObjectIdentifier sm2encrypt_with_rmd160 = sm2encrypt.Branch("2.7");
public static readonly DerObjectIdentifier sm2encrypt_with_whirlpool = sm2encrypt.Branch("2.8");
public static readonly DerObjectIdentifier sm2encrypt_with_blake2b512 = sm2encrypt.Branch("2.9");
public static readonly DerObjectIdentifier sm2encrypt_with_blake2s256 = sm2encrypt.Branch("2.10");
public static readonly DerObjectIdentifier sm2encrypt_with_md5 = sm2encrypt.Branch("2.11");
public static readonly DerObjectIdentifier id_sm9PublicKey = sm_scheme.Branch("302");
public static readonly DerObjectIdentifier sm9sign = sm_scheme.Branch("302.1");
public static readonly DerObjectIdentifier sm9keyagreement = sm_scheme.Branch("302.2");
public static readonly DerObjectIdentifier sm9encrypt = sm_scheme.Branch("302.3");
public static readonly DerObjectIdentifier sm3 = sm_scheme.Branch("401");
public static readonly DerObjectIdentifier hmac_sm3 = sm3.Branch("2");
public static readonly DerObjectIdentifier sm2sign_with_sm3 = sm_scheme.Branch("501");
public static readonly DerObjectIdentifier sm2sign_with_sha1 = sm_scheme.Branch("502");
public static readonly DerObjectIdentifier sm2sign_with_sha256 = sm_scheme.Branch("503");
public static readonly DerObjectIdentifier sm2sign_with_sha512 = sm_scheme.Branch("504");
public static readonly DerObjectIdentifier sm2sign_with_sha224 = sm_scheme.Branch("505");
public static readonly DerObjectIdentifier sm2sign_with_sha384 = sm_scheme.Branch("506");
public static readonly DerObjectIdentifier sm2sign_with_rmd160 = sm_scheme.Branch("507");
public static readonly DerObjectIdentifier sm2sign_with_whirlpool = sm_scheme.Branch("520");
public static readonly DerObjectIdentifier sm2sign_with_blake2b512 = sm_scheme.Branch("521");
public static readonly DerObjectIdentifier sm2sign_with_blake2s256 = sm_scheme.Branch("522");
}
}

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.misc
{
public abstract class MiscObjectIdentifiers
{
//
// Netscape
// iso/itu(2) joint-assign(16) us(840) uscompany(1) Netscape(113730) cert-extensions(1) }
//
public static readonly DerObjectIdentifier Netscape = new DerObjectIdentifier("2.16.840.1.113730.1");
public static readonly DerObjectIdentifier NetscapeCertType = Netscape.Branch("1");
public static readonly DerObjectIdentifier NetscapeBaseUrl = Netscape.Branch("2");
public static readonly DerObjectIdentifier NetscapeRevocationUrl = Netscape.Branch("3");
public static readonly DerObjectIdentifier NetscapeCARevocationUrl = Netscape.Branch("4");
public static readonly DerObjectIdentifier NetscapeRenewalUrl = Netscape.Branch("7");
public static readonly DerObjectIdentifier NetscapeCAPolicyUrl = Netscape.Branch("8");
public static readonly DerObjectIdentifier NetscapeSslServerName = Netscape.Branch("12");
public static readonly DerObjectIdentifier NetscapeCertComment = Netscape.Branch("13");
//
// Verisign
// iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) }
//
public static readonly DerObjectIdentifier Verisign = new DerObjectIdentifier("2.16.840.1.113733.1");
//
// CZAG - country, zip, age, and gender
//
public static readonly DerObjectIdentifier VerisignCzagExtension = Verisign.Branch("6.3");
public static readonly DerObjectIdentifier VerisignPrivate_6_9 = Verisign.Branch("6.9");
public static readonly DerObjectIdentifier VerisignOnSiteJurisdictionHash = Verisign.Branch("6.11");
public static readonly DerObjectIdentifier VerisignBitString_6_13 = Verisign.Branch("6.13");
// D&B D-U-N-S number
public static readonly DerObjectIdentifier VerisignDnbDunsNumber = Verisign.Branch("6.15");
public static readonly DerObjectIdentifier VerisignIssStrongCrypto = Verisign.Branch("8.1");
//
// Novell
// iso/itu(2) country(16) us(840) organization(1) novell(113719)
//
public static readonly string Novell = "2.16.840.1.113719";
public static readonly DerObjectIdentifier NovellSecurityAttribs = new DerObjectIdentifier(Novell + ".1.9.4.1");
//
// Entrust
// iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7)
//
public static readonly string Entrust = "1.2.840.113533.7";
public static readonly DerObjectIdentifier EntrustVersionExtension = new DerObjectIdentifier(Entrust + ".65.0");
public static readonly DerObjectIdentifier cast5CBC = new DerObjectIdentifier(Entrust + ".66.10");
//
// HMAC-SHA1 hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
// dod(6) internet(1) security(5) mechanisms(5) 8 1 2 }
//
public static readonly DerObjectIdentifier HMAC_SHA1 = new DerObjectIdentifier("1.3.6.1.5.5.8.1.2");
//
// Ascom
//
public static readonly DerObjectIdentifier as_sys_sec_alg_ideaCBC = new DerObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2");
//
// Peter Gutmann's Cryptlib
//
public static readonly DerObjectIdentifier cryptlib = new DerObjectIdentifier("1.3.6.1.4.1.3029");
public static readonly DerObjectIdentifier cryptlib_algorithm = cryptlib.Branch("1");
public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_ECB = cryptlib_algorithm.Branch("1.1");
public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_CBC = cryptlib_algorithm.Branch("1.2");
public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_CFB = cryptlib_algorithm.Branch("1.3");
public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.Branch("1.4");
//
// Blake2b
//
public static readonly DerObjectIdentifier blake2 = new DerObjectIdentifier("1.3.6.1.4.1.1722.12.2");
public static readonly DerObjectIdentifier id_blake2b160 = blake2.Branch("1.5");
public static readonly DerObjectIdentifier id_blake2b256 = blake2.Branch("1.8");
public static readonly DerObjectIdentifier id_blake2b384 = blake2.Branch("1.12");
public static readonly DerObjectIdentifier id_blake2b512 = blake2.Branch("1.16");
public static readonly DerObjectIdentifier id_blake2s128 = blake2.Branch("2.4");
public static readonly DerObjectIdentifier id_blake2s160 = blake2.Branch("2.5");
public static readonly DerObjectIdentifier id_blake2s224 = blake2.Branch("2.7");
public static readonly DerObjectIdentifier id_blake2s256 = blake2.Branch("2.8");
//
// Scrypt
public static readonly DerObjectIdentifier id_scrypt = new DerObjectIdentifier("1.3.6.1.4.1.11591.4.11");
}
}

View File

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.nist
{
public sealed class NistObjectIdentifiers
{
private NistObjectIdentifiers()
{
}
//
// NIST
// iso/itu(2) joint-assign(16) us(840) organization(1) gov(101) csor(3)
//
// nistalgorithms(4)
//
public static readonly DerObjectIdentifier NistAlgorithm = new DerObjectIdentifier("2.16.840.1.101.3.4");
public static readonly DerObjectIdentifier HashAlgs = NistAlgorithm.Branch("2");
public static readonly DerObjectIdentifier IdSha256 = HashAlgs.Branch("1");
public static readonly DerObjectIdentifier IdSha384 = HashAlgs.Branch("2");
public static readonly DerObjectIdentifier IdSha512 = HashAlgs.Branch("3");
public static readonly DerObjectIdentifier IdSha224 = HashAlgs.Branch("4");
public static readonly DerObjectIdentifier IdSha512_224 = HashAlgs.Branch("5");
public static readonly DerObjectIdentifier IdSha512_256 = HashAlgs.Branch("6");
public static readonly DerObjectIdentifier IdSha3_224 = HashAlgs.Branch("7");
public static readonly DerObjectIdentifier IdSha3_256 = HashAlgs.Branch("8");
public static readonly DerObjectIdentifier IdSha3_384 = HashAlgs.Branch("9");
public static readonly DerObjectIdentifier IdSha3_512 = HashAlgs.Branch("10");
public static readonly DerObjectIdentifier IdShake128 = HashAlgs.Branch("11");
public static readonly DerObjectIdentifier IdShake256 = HashAlgs.Branch("12");
public static readonly DerObjectIdentifier IdHMacWithSha3_224 = HashAlgs.Branch("13");
public static readonly DerObjectIdentifier IdHMacWithSha3_256 = HashAlgs.Branch("14");
public static readonly DerObjectIdentifier IdHMacWithSha3_384 = HashAlgs.Branch("15");
public static readonly DerObjectIdentifier IdHMacWithSha3_512 = HashAlgs.Branch("16");
public static readonly DerObjectIdentifier IdShake128Len = HashAlgs.Branch("17");
public static readonly DerObjectIdentifier IdShake256Len = HashAlgs.Branch("18");
public static readonly DerObjectIdentifier IdKmacWithShake128 = HashAlgs.Branch("19");
public static readonly DerObjectIdentifier IdKmacWithShake256 = HashAlgs.Branch("20");
public static readonly DerObjectIdentifier Aes = new DerObjectIdentifier(NistAlgorithm + ".1");
public static readonly DerObjectIdentifier IdAes128Ecb = new DerObjectIdentifier(Aes + ".1");
public static readonly DerObjectIdentifier IdAes128Cbc = new DerObjectIdentifier(Aes + ".2");
public static readonly DerObjectIdentifier IdAes128Ofb = new DerObjectIdentifier(Aes + ".3");
public static readonly DerObjectIdentifier IdAes128Cfb = new DerObjectIdentifier(Aes + ".4");
public static readonly DerObjectIdentifier IdAes128Wrap = new DerObjectIdentifier(Aes + ".5");
public static readonly DerObjectIdentifier IdAes128Gcm = new DerObjectIdentifier(Aes + ".6");
public static readonly DerObjectIdentifier IdAes128Ccm = new DerObjectIdentifier(Aes + ".7");
public static readonly DerObjectIdentifier IdAes192Ecb = new DerObjectIdentifier(Aes + ".21");
public static readonly DerObjectIdentifier IdAes192Cbc = new DerObjectIdentifier(Aes + ".22");
public static readonly DerObjectIdentifier IdAes192Ofb = new DerObjectIdentifier(Aes + ".23");
public static readonly DerObjectIdentifier IdAes192Cfb = new DerObjectIdentifier(Aes + ".24");
public static readonly DerObjectIdentifier IdAes192Wrap = new DerObjectIdentifier(Aes + ".25");
public static readonly DerObjectIdentifier IdAes192Gcm = new DerObjectIdentifier(Aes + ".26");
public static readonly DerObjectIdentifier IdAes192Ccm = new DerObjectIdentifier(Aes + ".27");
public static readonly DerObjectIdentifier IdAes256Ecb = new DerObjectIdentifier(Aes + ".41");
public static readonly DerObjectIdentifier IdAes256Cbc = new DerObjectIdentifier(Aes + ".42");
public static readonly DerObjectIdentifier IdAes256Ofb = new DerObjectIdentifier(Aes + ".43");
public static readonly DerObjectIdentifier IdAes256Cfb = new DerObjectIdentifier(Aes + ".44");
public static readonly DerObjectIdentifier IdAes256Wrap = new DerObjectIdentifier(Aes + ".45");
public static readonly DerObjectIdentifier IdAes256Gcm = new DerObjectIdentifier(Aes + ".46");
public static readonly DerObjectIdentifier IdAes256Ccm = new DerObjectIdentifier(Aes + ".47");
//
// signatures
//
public static readonly DerObjectIdentifier IdDsaWithSha2 = new DerObjectIdentifier(NistAlgorithm + ".3");
public static readonly DerObjectIdentifier DsaWithSha224 = new DerObjectIdentifier(IdDsaWithSha2 + ".1");
public static readonly DerObjectIdentifier DsaWithSha256 = new DerObjectIdentifier(IdDsaWithSha2 + ".2");
public static readonly DerObjectIdentifier DsaWithSha384 = new DerObjectIdentifier(IdDsaWithSha2 + ".3");
public static readonly DerObjectIdentifier DsaWithSha512 = new DerObjectIdentifier(IdDsaWithSha2 + ".4");
/** 2.16.840.1.101.3.4.3.5 */
public static readonly DerObjectIdentifier IdDsaWithSha3_224 = new DerObjectIdentifier(IdDsaWithSha2 + ".5");
/** 2.16.840.1.101.3.4.3.6 */
public static readonly DerObjectIdentifier IdDsaWithSha3_256 = new DerObjectIdentifier(IdDsaWithSha2 + ".6");
/** 2.16.840.1.101.3.4.3.7 */
public static readonly DerObjectIdentifier IdDsaWithSha3_384 = new DerObjectIdentifier(IdDsaWithSha2 + ".7");
/** 2.16.840.1.101.3.4.3.8 */
public static readonly DerObjectIdentifier IdDsaWithSha3_512 = new DerObjectIdentifier(IdDsaWithSha2 + ".8");
// ECDSA with SHA-3
/** 2.16.840.1.101.3.4.3.9 */
public static readonly DerObjectIdentifier IdEcdsaWithSha3_224 = new DerObjectIdentifier(IdDsaWithSha2 + ".9");
/** 2.16.840.1.101.3.4.3.10 */
public static readonly DerObjectIdentifier IdEcdsaWithSha3_256 = new DerObjectIdentifier(IdDsaWithSha2 + ".10");
/** 2.16.840.1.101.3.4.3.11 */
public static readonly DerObjectIdentifier IdEcdsaWithSha3_384 = new DerObjectIdentifier(IdDsaWithSha2 + ".11");
/** 2.16.840.1.101.3.4.3.12 */
public static readonly DerObjectIdentifier IdEcdsaWithSha3_512 = new DerObjectIdentifier(IdDsaWithSha2 + ".12");
// RSA PKCS #1 v1.5 Signature with SHA-3 family.
/** 2.16.840.1.101.3.4.3.9 */
public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_224 = new DerObjectIdentifier(IdDsaWithSha2 + ".13");
/** 2.16.840.1.101.3.4.3.10 */
public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_256 = new DerObjectIdentifier(IdDsaWithSha2 + ".14");
/** 2.16.840.1.101.3.4.3.11 */
public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_384 = new DerObjectIdentifier(IdDsaWithSha2 + ".15");
/** 2.16.840.1.101.3.4.3.12 */
public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_512 = new DerObjectIdentifier(IdDsaWithSha2 + ".16");
}
}

View File

@ -0,0 +1,309 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.pkcs
{
public abstract class PkcsObjectIdentifiers
{
//
// pkcs-1 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
//
public const string Pkcs1 = "1.2.840.113549.1.1";
internal static readonly DerObjectIdentifier Pkcs1Oid = new DerObjectIdentifier(Pkcs1);
public static readonly DerObjectIdentifier RsaEncryption = Pkcs1Oid.Branch("1");
public static readonly DerObjectIdentifier MD2WithRsaEncryption = Pkcs1Oid.Branch("2");
public static readonly DerObjectIdentifier MD4WithRsaEncryption = Pkcs1Oid.Branch("3");
public static readonly DerObjectIdentifier MD5WithRsaEncryption = Pkcs1Oid.Branch("4");
public static readonly DerObjectIdentifier Sha1WithRsaEncryption = Pkcs1Oid.Branch("5");
public static readonly DerObjectIdentifier SrsaOaepEncryptionSet = Pkcs1Oid.Branch("6");
public static readonly DerObjectIdentifier IdRsaesOaep = Pkcs1Oid.Branch("7");
public static readonly DerObjectIdentifier IdMgf1 = Pkcs1Oid.Branch("8");
public static readonly DerObjectIdentifier IdPSpecified = Pkcs1Oid.Branch("9");
public static readonly DerObjectIdentifier IdRsassaPss = Pkcs1Oid.Branch("10");
public static readonly DerObjectIdentifier Sha256WithRsaEncryption = Pkcs1Oid.Branch("11");
public static readonly DerObjectIdentifier Sha384WithRsaEncryption = Pkcs1Oid.Branch("12");
public static readonly DerObjectIdentifier Sha512WithRsaEncryption = Pkcs1Oid.Branch("13");
public static readonly DerObjectIdentifier Sha224WithRsaEncryption = Pkcs1Oid.Branch("14");
/** PKCS#1: 1.2.840.113549.1.1.15 */
public static readonly DerObjectIdentifier Sha512_224WithRSAEncryption = Pkcs1Oid.Branch("15");
/** PKCS#1: 1.2.840.113549.1.1.16 */
public static readonly DerObjectIdentifier Sha512_256WithRSAEncryption = Pkcs1Oid.Branch("16");
//
// pkcs-3 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 }
//
public const string Pkcs3 = "1.2.840.113549.1.3";
public static readonly DerObjectIdentifier DhKeyAgreement = new DerObjectIdentifier(Pkcs3 + ".1");
//
// pkcs-5 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 }
//
public const string Pkcs5 = "1.2.840.113549.1.5";
public static readonly DerObjectIdentifier PbeWithMD2AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".1");
public static readonly DerObjectIdentifier PbeWithMD2AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".4");
public static readonly DerObjectIdentifier PbeWithMD5AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".3");
public static readonly DerObjectIdentifier PbeWithMD5AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".6");
public static readonly DerObjectIdentifier PbeWithSha1AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".10");
public static readonly DerObjectIdentifier PbeWithSha1AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".11");
public static readonly DerObjectIdentifier IdPbeS2 = new DerObjectIdentifier(Pkcs5 + ".13");
public static readonly DerObjectIdentifier IdPbkdf2 = new DerObjectIdentifier(Pkcs5 + ".12");
//
// encryptionAlgorithm OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) 3 }
//
public const string EncryptionAlgorithm = "1.2.840.113549.3";
public static readonly DerObjectIdentifier DesEde3Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".7");
public static readonly DerObjectIdentifier RC2Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".2");
public static readonly DerObjectIdentifier rc4 = new DerObjectIdentifier(EncryptionAlgorithm + ".4");
//
// object identifiers for digests
//
public const string DigestAlgorithm = "1.2.840.113549.2";
//
// md2 OBJECT IDENTIFIER ::=
// {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 2}
//
public static readonly DerObjectIdentifier MD2 = new DerObjectIdentifier(DigestAlgorithm + ".2");
//
// md4 OBJECT IDENTIFIER ::=
// {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 4}
//
public static readonly DerObjectIdentifier MD4 = new DerObjectIdentifier(DigestAlgorithm + ".4");
//
// md5 OBJECT IDENTIFIER ::=
// {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 5}
//
public static readonly DerObjectIdentifier MD5 = new DerObjectIdentifier(DigestAlgorithm + ".5");
public static readonly DerObjectIdentifier IdHmacWithSha1 = new DerObjectIdentifier(DigestAlgorithm + ".7");
public static readonly DerObjectIdentifier IdHmacWithSha224 = new DerObjectIdentifier(DigestAlgorithm + ".8");
public static readonly DerObjectIdentifier IdHmacWithSha256 = new DerObjectIdentifier(DigestAlgorithm + ".9");
public static readonly DerObjectIdentifier IdHmacWithSha384 = new DerObjectIdentifier(DigestAlgorithm + ".10");
public static readonly DerObjectIdentifier IdHmacWithSha512 = new DerObjectIdentifier(DigestAlgorithm + ".11");
//
// pkcs-7 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
//
public const string Pkcs7 = "1.2.840.113549.1.7";
public static readonly DerObjectIdentifier Data = new DerObjectIdentifier(Pkcs7 + ".1");
public static readonly DerObjectIdentifier SignedData = new DerObjectIdentifier(Pkcs7 + ".2");
public static readonly DerObjectIdentifier EnvelopedData = new DerObjectIdentifier(Pkcs7 + ".3");
public static readonly DerObjectIdentifier SignedAndEnvelopedData = new DerObjectIdentifier(Pkcs7 + ".4");
public static readonly DerObjectIdentifier DigestedData = new DerObjectIdentifier(Pkcs7 + ".5");
public static readonly DerObjectIdentifier EncryptedData = new DerObjectIdentifier(Pkcs7 + ".6");
//
// pkcs-9 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
//
public const string Pkcs9 = "1.2.840.113549.1.9";
public static readonly DerObjectIdentifier Pkcs9AtEmailAddress = new DerObjectIdentifier(Pkcs9 + ".1");
public static readonly DerObjectIdentifier Pkcs9AtUnstructuredName = new DerObjectIdentifier(Pkcs9 + ".2");
public static readonly DerObjectIdentifier Pkcs9AtContentType = new DerObjectIdentifier(Pkcs9 + ".3");
public static readonly DerObjectIdentifier Pkcs9AtMessageDigest = new DerObjectIdentifier(Pkcs9 + ".4");
public static readonly DerObjectIdentifier Pkcs9AtSigningTime = new DerObjectIdentifier(Pkcs9 + ".5");
public static readonly DerObjectIdentifier Pkcs9AtCounterSignature = new DerObjectIdentifier(Pkcs9 + ".6");
public static readonly DerObjectIdentifier Pkcs9AtChallengePassword = new DerObjectIdentifier(Pkcs9 + ".7");
public static readonly DerObjectIdentifier Pkcs9AtUnstructuredAddress = new DerObjectIdentifier(Pkcs9 + ".8");
public static readonly DerObjectIdentifier Pkcs9AtExtendedCertificateAttributes = new DerObjectIdentifier(Pkcs9 + ".9");
public static readonly DerObjectIdentifier Pkcs9AtSigningDescription = new DerObjectIdentifier(Pkcs9 + ".13");
public static readonly DerObjectIdentifier Pkcs9AtExtensionRequest = new DerObjectIdentifier(Pkcs9 + ".14");
public static readonly DerObjectIdentifier Pkcs9AtSmimeCapabilities = new DerObjectIdentifier(Pkcs9 + ".15");
public static readonly DerObjectIdentifier IdSmime = new DerObjectIdentifier(Pkcs9 + ".16");
public static readonly DerObjectIdentifier Pkcs9AtFriendlyName = new DerObjectIdentifier(Pkcs9 + ".20");
public static readonly DerObjectIdentifier Pkcs9AtLocalKeyID = new DerObjectIdentifier(Pkcs9 + ".21");
[Obsolete("Use X509Certificate instead")]
public static readonly DerObjectIdentifier X509CertType = new DerObjectIdentifier(Pkcs9 + ".22.1");
public const string CertTypes = Pkcs9 + ".22";
public static readonly DerObjectIdentifier X509Certificate = new DerObjectIdentifier(CertTypes + ".1");
public static readonly DerObjectIdentifier SdsiCertificate = new DerObjectIdentifier(CertTypes + ".2");
public const string CrlTypes = Pkcs9 + ".23";
public static readonly DerObjectIdentifier X509Crl = new DerObjectIdentifier(CrlTypes + ".1");
public static readonly DerObjectIdentifier IdAlg = IdSmime.Branch("3");
public static readonly DerObjectIdentifier IdAlgEsdh = IdAlg.Branch("5");
public static readonly DerObjectIdentifier IdAlgCms3DesWrap = IdAlg.Branch("6");
public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = IdAlg.Branch("7");
public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9");
public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10");
/*
* <pre>
* -- RSA-KEM Key Transport Algorithm
*
* id-rsa-kem OID ::= {
* iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
* pkcs-9(9) smime(16) alg(3) 14
* }
* </pre>
*/
public static readonly DerObjectIdentifier IdRsaKem = IdAlg.Branch("14");
/**
* <pre>
* id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::=
* { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
* pkcs9(9) smime(16) alg(3) 18 }
*
* AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12))
* </pre>
*/
public static readonly DerObjectIdentifier IdAlgAeadChaCha20Poly1305 = IdAlg.Branch("18");
//
// SMIME capability sub oids.
//
public static readonly DerObjectIdentifier PreferSignedData = Pkcs9AtSmimeCapabilities.Branch("1");
public static readonly DerObjectIdentifier CannotDecryptAny = Pkcs9AtSmimeCapabilities.Branch("2");
public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = Pkcs9AtSmimeCapabilities.Branch("3");
//
// other SMIME attributes
//
public static readonly DerObjectIdentifier IdAAReceiptRequest = IdSmime.Branch("2.1");
//
// id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
// rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)}
//
public const string IdCT = "1.2.840.113549.1.9.16.1";
public static readonly DerObjectIdentifier IdCTAuthData = new DerObjectIdentifier(IdCT + ".2");
public static readonly DerObjectIdentifier IdCTTstInfo = new DerObjectIdentifier(IdCT + ".4");
public static readonly DerObjectIdentifier IdCTCompressedData = new DerObjectIdentifier(IdCT + ".9");
public static readonly DerObjectIdentifier IdCTAuthEnvelopedData = new DerObjectIdentifier(IdCT + ".23");
public static readonly DerObjectIdentifier IdCTTimestampedData = new DerObjectIdentifier(IdCT + ".31");
//
// id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
// rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)}
//
public const string IdCti = "1.2.840.113549.1.9.16.6";
public static readonly DerObjectIdentifier IdCtiEtsProofOfOrigin = new DerObjectIdentifier(IdCti + ".1");
public static readonly DerObjectIdentifier IdCtiEtsProofOfReceipt = new DerObjectIdentifier(IdCti + ".2");
public static readonly DerObjectIdentifier IdCtiEtsProofOfDelivery = new DerObjectIdentifier(IdCti + ".3");
public static readonly DerObjectIdentifier IdCtiEtsProofOfSender = new DerObjectIdentifier(IdCti + ".4");
public static readonly DerObjectIdentifier IdCtiEtsProofOfApproval = new DerObjectIdentifier(IdCti + ".5");
public static readonly DerObjectIdentifier IdCtiEtsProofOfCreation = new DerObjectIdentifier(IdCti + ".6");
//
// id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
// rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)}
//
public const string IdAA = "1.2.840.113549.1.9.16.2";
public static readonly DerObjectIdentifier IdAAOid = new DerObjectIdentifier(IdAA);
public static readonly DerObjectIdentifier IdAAContentHint = new DerObjectIdentifier(IdAA + ".4"); // See RFC 2634
public static readonly DerObjectIdentifier IdAAMsgSigDigest = new DerObjectIdentifier(IdAA + ".5");
public static readonly DerObjectIdentifier IdAAContentReference = new DerObjectIdentifier(IdAA + ".10");
/*
* id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}
*
*/
public static readonly DerObjectIdentifier IdAAEncrypKeyPref = new DerObjectIdentifier(IdAA + ".11");
public static readonly DerObjectIdentifier IdAASigningCertificate = new DerObjectIdentifier(IdAA + ".12");
public static readonly DerObjectIdentifier IdAASigningCertificateV2 = new DerObjectIdentifier(IdAA + ".47");
public static readonly DerObjectIdentifier IdAAContentIdentifier = new DerObjectIdentifier(IdAA + ".7"); // See RFC 2634
/*
* RFC 3126
*/
public static readonly DerObjectIdentifier IdAASignatureTimeStampToken = new DerObjectIdentifier(IdAA + ".14");
public static readonly DerObjectIdentifier IdAAEtsSigPolicyID = new DerObjectIdentifier(IdAA + ".15");
public static readonly DerObjectIdentifier IdAAEtsCommitmentType = new DerObjectIdentifier(IdAA + ".16");
public static readonly DerObjectIdentifier IdAAEtsSignerLocation = new DerObjectIdentifier(IdAA + ".17");
public static readonly DerObjectIdentifier IdAAEtsSignerAttr = new DerObjectIdentifier(IdAA + ".18");
public static readonly DerObjectIdentifier IdAAEtsOtherSigCert = new DerObjectIdentifier(IdAA + ".19");
public static readonly DerObjectIdentifier IdAAEtsContentTimestamp = new DerObjectIdentifier(IdAA + ".20");
public static readonly DerObjectIdentifier IdAAEtsCertificateRefs = new DerObjectIdentifier(IdAA + ".21");
public static readonly DerObjectIdentifier IdAAEtsRevocationRefs = new DerObjectIdentifier(IdAA + ".22");
public static readonly DerObjectIdentifier IdAAEtsCertValues = new DerObjectIdentifier(IdAA + ".23");
public static readonly DerObjectIdentifier IdAAEtsRevocationValues = new DerObjectIdentifier(IdAA + ".24");
public static readonly DerObjectIdentifier IdAAEtsEscTimeStamp = new DerObjectIdentifier(IdAA + ".25");
public static readonly DerObjectIdentifier IdAAEtsCertCrlTimestamp = new DerObjectIdentifier(IdAA + ".26");
public static readonly DerObjectIdentifier IdAAEtsArchiveTimestamp = new DerObjectIdentifier(IdAA + ".27");
/** PKCS#9: 1.2.840.113549.1.9.16.2.37 - <a href="https://tools.ietf.org/html/rfc4108#section-2.2.5">RFC 4108</a> */
public static readonly DerObjectIdentifier IdAADecryptKeyID = IdAAOid.Branch("37");
/** PKCS#9: 1.2.840.113549.1.9.16.2.38 - <a href="https://tools.ietf.org/html/rfc4108#section-2.2.6">RFC 4108</a> */
public static readonly DerObjectIdentifier IdAAImplCryptoAlgs = IdAAOid.Branch("38");
/** PKCS#9: 1.2.840.113549.1.9.16.2.54 <a href="https://tools.ietf.org/html/rfc7030">RFC7030</a>*/
public static readonly DerObjectIdentifier IdAAAsymmDecryptKeyID = IdAAOid.Branch("54");
/** PKCS#9: 1.2.840.113549.1.9.16.2.43 <a href="https://tools.ietf.org/html/rfc7030">RFC7030</a>*/
public static readonly DerObjectIdentifier IdAAImplCompressAlgs = IdAAOid.Branch("43");
/** PKCS#9: 1.2.840.113549.1.9.16.2.40 <a href="https://tools.ietf.org/html/rfc7030">RFC7030</a>*/
public static readonly DerObjectIdentifier IdAACommunityIdentifiers = IdAAOid.Branch("40");
[Obsolete("Use 'IdAAEtsSigPolicyID' instead")]
public static readonly DerObjectIdentifier IdAASigPolicyID = IdAAEtsSigPolicyID;
[Obsolete("Use 'IdAAEtsCommitmentType' instead")]
public static readonly DerObjectIdentifier IdAACommitmentType = IdAAEtsCommitmentType;
[Obsolete("Use 'IdAAEtsSignerLocation' instead")]
public static readonly DerObjectIdentifier IdAASignerLocation = IdAAEtsSignerLocation;
[Obsolete("Use 'IdAAEtsOtherSigCert' instead")]
public static readonly DerObjectIdentifier IdAAOtherSigCert = IdAAEtsOtherSigCert;
//
// id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
// rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)}
//
public const string IdSpq = "1.2.840.113549.1.9.16.5";
public static readonly DerObjectIdentifier IdSpqEtsUri = new DerObjectIdentifier(IdSpq + ".1");
public static readonly DerObjectIdentifier IdSpqEtsUNotice = new DerObjectIdentifier(IdSpq + ".2");
//
// pkcs-12 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 }
//
public const string Pkcs12 = "1.2.840.113549.1.12";
public const string BagTypes = Pkcs12 + ".10.1";
public static readonly DerObjectIdentifier KeyBag = new DerObjectIdentifier(BagTypes + ".1");
public static readonly DerObjectIdentifier Pkcs8ShroudedKeyBag = new DerObjectIdentifier(BagTypes + ".2");
public static readonly DerObjectIdentifier CertBag = new DerObjectIdentifier(BagTypes + ".3");
public static readonly DerObjectIdentifier CrlBag = new DerObjectIdentifier(BagTypes + ".4");
public static readonly DerObjectIdentifier SecretBag = new DerObjectIdentifier(BagTypes + ".5");
public static readonly DerObjectIdentifier SafeContentsBag = new DerObjectIdentifier(BagTypes + ".6");
public const string Pkcs12PbeIds = Pkcs12 + ".1";
public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".1");
public static readonly DerObjectIdentifier PbeWithShaAnd40BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".2");
public static readonly DerObjectIdentifier PbeWithShaAnd3KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".3");
public static readonly DerObjectIdentifier PbeWithShaAnd2KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".4");
public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".5");
public static readonly DerObjectIdentifier PbewithShaAnd40BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".6");
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.rosstandart
{
public abstract class RosstandartObjectIdentifiers
{
public static readonly DerObjectIdentifier rosstandart = new DerObjectIdentifier("1.2.643.7");
public static readonly DerObjectIdentifier id_tc26 = rosstandart.Branch("1");
public static readonly DerObjectIdentifier id_tc26_gost_3411_12_256 = id_tc26.Branch("1.2.2");
public static readonly DerObjectIdentifier id_tc26_gost_3411_12_512 = id_tc26.Branch("1.2.3");
public static readonly DerObjectIdentifier id_tc26_hmac_gost_3411_12_256 = id_tc26.Branch("1.4.1");
public static readonly DerObjectIdentifier id_tc26_hmac_gost_3411_12_512 = id_tc26.Branch("1.4.2");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_256 = id_tc26.Branch("1.1.1");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512 = id_tc26.Branch("1.1.2");
public static readonly DerObjectIdentifier id_tc26_signwithdigest_gost_3410_12_256 = id_tc26.Branch("1.3.2");
public static readonly DerObjectIdentifier id_tc26_signwithdigest_gost_3410_12_512 = id_tc26.Branch("1.3.3");
public static readonly DerObjectIdentifier id_tc26_agreement = id_tc26.Branch("1.6");
public static readonly DerObjectIdentifier id_tc26_agreement_gost_3410_12_256 = id_tc26_agreement.Branch("1");
public static readonly DerObjectIdentifier id_tc26_agreement_gost_3410_12_512 = id_tc26_agreement.Branch("2");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_256_paramSet = id_tc26.Branch("2.1.1");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_256_paramSetA = id_tc26_gost_3410_12_256_paramSet.Branch("1");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSet = id_tc26.Branch("2.1.2");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSetA = id_tc26_gost_3410_12_512_paramSet.Branch("1");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSetB = id_tc26_gost_3410_12_512_paramSet.Branch("2");
public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSetC = id_tc26_gost_3410_12_512_paramSet.Branch("3");
public static readonly DerObjectIdentifier id_tc26_gost_28147_param_Z = id_tc26.Branch("2.5.1.1");
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.teletrust
{
public sealed class TeleTrusTObjectIdentifiers
{
private TeleTrusTObjectIdentifiers()
{
}
public static readonly DerObjectIdentifier TeleTrusTAlgorithm = new DerObjectIdentifier("1.3.36.3");
public static readonly DerObjectIdentifier RipeMD160 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.1");
public static readonly DerObjectIdentifier RipeMD128 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.2");
public static readonly DerObjectIdentifier RipeMD256 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.3");
public static readonly DerObjectIdentifier TeleTrusTRsaSignatureAlgorithm = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.1");
public static readonly DerObjectIdentifier RsaSignatureWithRipeMD160 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".2");
public static readonly DerObjectIdentifier RsaSignatureWithRipeMD128 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".3");
public static readonly DerObjectIdentifier RsaSignatureWithRipeMD256 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".4");
public static readonly DerObjectIdentifier ECSign = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2");
public static readonly DerObjectIdentifier ECSignWithSha1 = new DerObjectIdentifier(ECSign + ".1");
public static readonly DerObjectIdentifier ECSignWithRipeMD160 = new DerObjectIdentifier(ECSign + ".2");
public static readonly DerObjectIdentifier EccBrainpool = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2.8");
public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier(EccBrainpool + ".1");
public static readonly DerObjectIdentifier VersionOne = new DerObjectIdentifier(EllipticCurve + ".1");
public static readonly DerObjectIdentifier BrainpoolP160R1 = new DerObjectIdentifier(VersionOne + ".1");
public static readonly DerObjectIdentifier BrainpoolP160T1 = new DerObjectIdentifier(VersionOne + ".2");
public static readonly DerObjectIdentifier BrainpoolP192R1 = new DerObjectIdentifier(VersionOne + ".3");
public static readonly DerObjectIdentifier BrainpoolP192T1 = new DerObjectIdentifier(VersionOne + ".4");
public static readonly DerObjectIdentifier BrainpoolP224R1 = new DerObjectIdentifier(VersionOne + ".5");
public static readonly DerObjectIdentifier BrainpoolP224T1 = new DerObjectIdentifier(VersionOne + ".6");
public static readonly DerObjectIdentifier BrainpoolP256R1 = new DerObjectIdentifier(VersionOne + ".7");
public static readonly DerObjectIdentifier BrainpoolP256T1 = new DerObjectIdentifier(VersionOne + ".8");
public static readonly DerObjectIdentifier BrainpoolP320R1 = new DerObjectIdentifier(VersionOne + ".9");
public static readonly DerObjectIdentifier BrainpoolP320T1 = new DerObjectIdentifier(VersionOne + ".10");
public static readonly DerObjectIdentifier BrainpoolP384R1 = new DerObjectIdentifier(VersionOne + ".11");
public static readonly DerObjectIdentifier BrainpoolP384T1 = new DerObjectIdentifier(VersionOne + ".12");
public static readonly DerObjectIdentifier BrainpoolP512R1 = new DerObjectIdentifier(VersionOne + ".13");
public static readonly DerObjectIdentifier BrainpoolP512T1 = new DerObjectIdentifier(VersionOne + ".14");
}
}

View File

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.ua
{
/**
* Ukrainian object identifiers
* <p>
* {iso(1) member-body(2) Ukraine(804) root(2) security(1) cryptography(1) pki(1)}
* <p>
* { ... pki-alg(1) pki-alg-sym(3) Dstu4145WithGost34311(1) PB(1)}
* <p>
* DSTU4145 in polynomial basis has 2 oids, one for little-endian representation and one for big-endian
*/
public abstract class UAObjectIdentifiers
{
/** Base OID: 1.2.804.2.1.1.1 */
public static readonly DerObjectIdentifier UaOid = new DerObjectIdentifier("1.2.804.2.1.1.1");
/** DSTU4145 Little Endian presentation. OID: 1.2.804.2.1.1.1.1.3.1.1 */
public static readonly DerObjectIdentifier dstu4145le = UaOid.Branch("1.3.1.1");
/** DSTU4145 Big Endian presentation. OID: 1.2.804.2.1.1.1.1.3.1.1.1 */
public static readonly DerObjectIdentifier dstu4145be = UaOid.Branch("1.3.1.1.1.1");
/** DSTU7564 256-bit digest presentation. */
public static readonly DerObjectIdentifier dstu7564digest_256 = UaOid.Branch("1.2.2.1");
/** DSTU7564 384-bit digest presentation. */
public static readonly DerObjectIdentifier dstu7564digest_384 = UaOid.Branch("1.2.2.2");
/** DSTU7564 512-bit digest presentation. */
public static readonly DerObjectIdentifier dstu7564digest_512 = UaOid.Branch("1.2.2.3");
/** DSTU7564 256-bit mac presentation. */
public static readonly DerObjectIdentifier dstu7564mac_256 = UaOid.Branch("1.2.2.4");
/** DSTU7564 384-bit mac presentation. */
public static readonly DerObjectIdentifier dstu7564mac_384 = UaOid.Branch("1.2.2.5");
/** DSTU7564 512-bit mac presentation. */
public static readonly DerObjectIdentifier dstu7564mac_512 = UaOid.Branch("1.2.2.6");
/** DSTU7624 in ECB mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ecb_128 = UaOid.Branch("1.1.3.1.1");
/** DSTU7624 in ECB mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ecb_256 = UaOid.Branch("1.1.3.1.2");
/** DSTU7624 in ECB mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ecb_512 = UaOid.Branch("1.1.3.1.3");
/** DSTU7624 in CTR mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ctr_128 = UaOid.Branch("1.1.3.2.1");
/** DSTU7624 in CTR mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ctr_256 = UaOid.Branch("1.1.3.2.2");
/** DSTU7624 in CTR mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ctr_512 = UaOid.Branch("1.1.3.2.3");
/** DSTU7624 in CFB mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cfb_128 = UaOid.Branch("1.1.3.3.1");
/** DSTU7624 in CFB mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cfb_256 = UaOid.Branch("1.1.3.3.2");
/** DSTU7624 in CFB mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cfb_512 = UaOid.Branch("1.1.3.3.3");
/** DSTU7624 in MAC mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cmac_128 = UaOid.Branch("1.1.3.4.1");
/** DSTU7624 in MAC mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cmac_256 = UaOid.Branch("1.1.3.4.2");
/** DSTU7624 in MAC mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cmac_512 = UaOid.Branch("1.1.3.4.3");
/** DSTU7624 in CBC mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cbc_128 = UaOid.Branch("1.1.3.5.1");
/** DSTU7624 in CBC mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cbc_256 = UaOid.Branch("1.1.3.5.2");
/** DSTU7624 in CBC mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624cbc_512 = UaOid.Branch("1.1.3.5.3");
/** DSTU7624 in OFB mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ofb_128 = UaOid.Branch("1.1.3.6.1");
/** DSTU7624 in OFB mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ofb_256 = UaOid.Branch("1.1.3.6.2");
/** DSTU7624 in OFB mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ofb_512 = UaOid.Branch("1.1.3.6.3");
/** DSTU7624 in GMAC (GCM witout encryption) mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624gmac_128 = UaOid.Branch("1.1.3.7.1");
/** DSTU7624 in GMAC (GCM witout encryption) mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624gmac_256 = UaOid.Branch("1.1.3.7.2");
/** DSTU7624 in GMAC (GCM witout encryption) mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624gmac_512 = UaOid.Branch("1.1.3.7.3");
/** DSTU7624 in CCM mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ccm_128 = UaOid.Branch("1.1.3.8.1");
/** DSTU7624 in CCM mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ccm_256 = UaOid.Branch("1.1.3.8.2");
/** DSTU7624 in CCM mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624ccm_512 = UaOid.Branch("1.1.3.8.3");
/** DSTU7624 in XTS mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624xts_128 = UaOid.Branch("1.1.3.9.1");
/** DSTU7624 in XTS mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624xts_256 = UaOid.Branch("1.1.3.9.2");
/** DSTU7624 in XTS mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624xts_512 = UaOid.Branch("1.1.3.9.3");
/** DSTU7624 in key wrap (KW) mode with 128 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624kw_128 = UaOid.Branch("1.1.3.10.1");
/** DSTU7624 in key wrap (KW) mode with 256 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624kw_256 = UaOid.Branch("1.1.3.10.2");
/** DSTU7624 in key wrap (KW) mode with 512 bit block/key presentation */
public static readonly DerObjectIdentifier dstu7624kw_512 = UaOid.Branch("1.1.3.10.3");
}
}

View File

@ -0,0 +1,86 @@
using BrowserPass.BouncyCastle.crypto.util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.asn1.util
{
[Obsolete("Use Org.BouncyCastle.Utilities.IO.FilterStream")]
public class FilterStream : Stream
{
[Obsolete("Use Org.BouncyCastle.Utilities.IO.FilterStream")]
public FilterStream(Stream s)
{
this.s = s;
}
public override bool CanRead
{
get { return s.CanRead; }
}
public override bool CanSeek
{
get { return s.CanSeek; }
}
public override bool CanWrite
{
get { return s.CanWrite; }
}
public override long Length
{
get { return s.Length; }
}
public override long Position
{
get { return s.Position; }
set { s.Position = value; }
}
#if PORTABLE
protected override void Dispose(bool disposing)
{
if (disposing)
{
Platform.Dispose(s);
}
base.Dispose(disposing);
}
#else
public override void Close()
{
Platform.Dispose(s);
base.Close();
}
#endif
public override void Flush()
{
s.Flush();
}
public override long Seek(long offset, SeekOrigin origin)
{
return s.Seek(offset, origin);
}
public override void SetLength(long value)
{
s.SetLength(value);
}
public override int Read(byte[] buffer, int offset, int count)
{
return s.Read(buffer, offset, count);
}
public override int ReadByte()
{
return s.ReadByte();
}
public override void Write(byte[] buffer, int offset, int count)
{
s.Write(buffer, offset, count);
}
public override void WriteByte(byte value)
{
s.WriteByte(value);
}
protected readonly Stream s;
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.crypto
{
internal class Check
{
internal static void DataLength(bool condition, string msg)
{
if (condition)
throw new DataLengthException(msg);
}
internal static void DataLength(byte[] buf, int off, int len, string msg)
{
if (off > (buf.Length - len))
throw new DataLengthException(msg);
}
internal static void OutputLength(byte[] buf, int off, int len, string msg)
{
if (off > (buf.Length - len))
throw new OutputLengthException(msg);
}
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.crypto
{
/// <remarks>Base interface for a symmetric key block cipher.</remarks>
public interface IBlockCipher
{
/// <summary>The name of the algorithm this cipher implements.</summary>
string AlgorithmName { get; }
/// <summary>Initialise the cipher.</summary>
/// <param name="forEncryption">Initialise for encryption if true, for decryption if false.</param>
/// <param name="parameters">The key or other data required by the cipher.</param>
void Init(bool forEncryption, ICipherParameters parameters);
/// <returns>The block size for this cipher, in bytes.</returns>
int GetBlockSize();
/// <summary>Indicates whether this cipher can handle partial blocks.</summary>
bool IsPartialBlockOkay { get; }
/// <summary>Process a block.</summary>
/// <param name="inBuf">The input buffer.</param>
/// <param name="inOff">The offset into <paramref>inBuf</paramref> that the input block begins.</param>
/// <param name="outBuf">The output buffer.</param>
/// <param name="outOff">The offset into <paramref>outBuf</paramref> to write the output block.</param>
/// <exception cref="DataLengthException">If input block is wrong size, or outBuf too small.</exception>
/// <returns>The number of bytes processed and produced.</returns>
int ProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff);
/// <summary>
/// Reset the cipher to the same state as it was after the last init (if there was one).
/// </summary>
void Reset();
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.crypto
{
/// <remarks>
/// With FIPS PUB 202 a new kind of message digest was announced which supported extendable output, or variable digest sizes.
/// This interface provides the extra method required to support variable output on a digest implementation.
/// </remarks>
public interface IXof
: IDigest
{
/// <summary>
/// Output the results of the final calculation for this digest to outLen number of bytes.
/// </summary>
/// <param name="output">output array to write the output bytes to.</param>
/// <param name="outOff">offset to start writing the bytes at.</param>
/// <param name="outLen">the number of output bytes requested.</param>
/// <returns>the number of bytes written</returns>
int DoFinal(byte[] output, int outOff, int outLen);
/// <summary>
/// Start outputting the results of the final calculation for this digest. Unlike DoFinal, this method
/// will continue producing output until the Xof is explicitly reset, or signals otherwise.
/// </summary>
/// <param name="output">output array to write the output bytes to.</param>
/// <param name="outOff">offset to start writing the bytes at.</param>
/// <param name="outLen">the number of output bytes requested.</param>
/// <returns>the number of bytes written</returns>
int DoOutput(byte[] output, int outOff, int outLen);
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.crypto
{
/**
* this exception is thrown whenever we find something we don't expect in a
* message.
*/
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class InvalidCipherTextException
: CryptoException
{
/**
* base constructor.
*/
public InvalidCipherTextException()
{
}
/**
* create a InvalidCipherTextException with the given message.
*
* @param message the message to be carried with the exception.
*/
public InvalidCipherTextException(
string message)
: base(message)
{
}
public InvalidCipherTextException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BrowserPass.BouncyCastle.crypto
{
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class OutputLengthException
: DataLengthException
{
public OutputLengthException()
{
}
public OutputLengthException(
string message)
: base(message)
{
}
public OutputLengthException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@ -0,0 +1,530 @@
using System;
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
namespace Org.BouncyCastle.Crypto.Digests
{
/* The BLAKE2 cryptographic hash function was designed by Jean-
Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and Christian
Winnerlein.
Reference Implementation and Description can be found at: https://blake2.net/
Internet Draft: https://tools.ietf.org/html/draft-saarinen-blake2-02
This implementation does not support the Tree Hashing Mode.
For unkeyed hashing, developers adapting BLAKE2 to ASN.1 - based
message formats SHOULD use the OID tree at x = 1.3.6.1.4.1.1722.12.2.
Algorithm | Target | Collision | Hash | Hash ASN.1 |
Identifier | Arch | Security | nn | OID Suffix |
---------------+--------+-----------+------+------------+
id-blake2b160 | 64-bit | 2**80 | 20 | x.1.20 |
id-blake2b256 | 64-bit | 2**128 | 32 | x.1.32 |
id-blake2b384 | 64-bit | 2**192 | 48 | x.1.48 |
id-blake2b512 | 64-bit | 2**256 | 64 | x.1.64 |
---------------+--------+-----------+------+------------+
*/
/**
* Implementation of the cryptographic hash function Blakbe2b.
* <p>
* Blake2b offers a built-in keying mechanism to be used directly
* for authentication ("Prefix-MAC") rather than a HMAC construction.
* <p>
* Blake2b offers a built-in support for a salt for randomized hashing
* and a personal string for defining a unique hash function for each application.
* <p>
* BLAKE2b is optimized for 64-bit platforms and produces digests of any size
* between 1 and 64 bytes.
*/
public class Blake2bDigest
: IDigest
{
// Blake2b Initialization Vector:
private static readonly ulong[] blake2b_IV =
// Produced from the square root of primes 2, 3, 5, 7, 11, 13, 17, 19.
// The same as SHA-512 IV.
{
0x6a09e667f3bcc908UL, 0xbb67ae8584caa73bUL, 0x3c6ef372fe94f82bUL,
0xa54ff53a5f1d36f1UL, 0x510e527fade682d1UL, 0x9b05688c2b3e6c1fUL,
0x1f83d9abfb41bd6bUL, 0x5be0cd19137e2179UL
};
// Message word permutations:
private static readonly byte[,] blake2b_sigma =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
};
private const int ROUNDS = 12; // to use for Catenas H'
private const int BLOCK_LENGTH_BYTES = 128;// bytes
// General parameters:
private int digestLength = 64; // 1- 64 bytes
private int keyLength = 0; // 0 - 64 bytes for keyed hashing for MAC
private byte[] salt = null;// new byte[16];
private byte[] personalization = null;// new byte[16];
// the key
private byte[] key = null;
// Tree hashing parameters:
// Because this class does not implement the Tree Hashing Mode,
// these parameters can be treated as constants (see init() function)
/*
* private int fanout = 1; // 0-255 private int depth = 1; // 1 - 255
* private int leafLength= 0; private long nodeOffset = 0L; private int
* nodeDepth = 0; private int innerHashLength = 0;
*/
// whenever this buffer overflows, it will be processed
// in the Compress() function.
// For performance issues, long messages will not use this buffer.
private byte[] buffer = null;// new byte[BLOCK_LENGTH_BYTES];
// Position of last inserted byte:
private int bufferPos = 0;// a value from 0 up to 128
private ulong[] internalState = new ulong[16]; // In the Blake2b paper it is
// called: v
private ulong[] chainValue = null; // state vector, in the Blake2b paper it
// is called: h
private ulong t0 = 0UL; // holds last significant bits, counter (counts bytes)
private ulong t1 = 0UL; // counter: Length up to 2^128 are supported
private ulong f0 = 0UL; // finalization flag, for last block: ~0L
// For Tree Hashing Mode, not used here:
// private long f1 = 0L; // finalization flag, for last node: ~0L
public Blake2bDigest()
: this(512)
{
}
public Blake2bDigest(Blake2bDigest digest)
{
this.bufferPos = digest.bufferPos;
this.buffer = Arrays.Clone(digest.buffer);
this.keyLength = digest.keyLength;
this.key = Arrays.Clone(digest.key);
this.digestLength = digest.digestLength;
this.chainValue = Arrays.Clone(digest.chainValue);
this.personalization = Arrays.Clone(digest.personalization);
this.salt = Arrays.Clone(digest.salt);
this.t0 = digest.t0;
this.t1 = digest.t1;
this.f0 = digest.f0;
}
/**
* Basic sized constructor - size in bits.
*
* @param digestSize size of the digest in bits
*/
public Blake2bDigest(int digestSize)
{
if (digestSize < 8 || digestSize > 512 || digestSize % 8 != 0)
throw new ArgumentException("BLAKE2b digest bit length must be a multiple of 8 and not greater than 512");
buffer = new byte[BLOCK_LENGTH_BYTES];
keyLength = 0;
this.digestLength = digestSize / 8;
Init();
}
/**
* Blake2b for authentication ("Prefix-MAC mode").
* After calling the doFinal() method, the key will
* remain to be used for further computations of
* this instance.
* The key can be overwritten using the clearKey() method.
*
* @param key A key up to 64 bytes or null
*/
public Blake2bDigest(byte[] key)
{
buffer = new byte[BLOCK_LENGTH_BYTES];
if (key != null)
{
this.key = new byte[key.Length];
Array.Copy(key, 0, this.key, 0, key.Length);
if (key.Length > 64)
throw new ArgumentException("Keys > 64 are not supported");
keyLength = key.Length;
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
digestLength = 64;
Init();
}
/**
* Blake2b with key, required digest length (in bytes), salt and personalization.
* After calling the doFinal() method, the key, the salt and the personal string
* will remain and might be used for further computations with this instance.
* The key can be overwritten using the clearKey() method, the salt (pepper)
* can be overwritten using the clearSalt() method.
*
* @param key A key up to 64 bytes or null
* @param digestLength from 1 up to 64 bytes
* @param salt 16 bytes or null
* @param personalization 16 bytes or null
*/
public Blake2bDigest(byte[] key, int digestLength, byte[] salt, byte[] personalization)
{
if (digestLength < 1 || digestLength > 64)
throw new ArgumentException("Invalid digest length (required: 1 - 64)");
this.digestLength = digestLength;
this.buffer = new byte[BLOCK_LENGTH_BYTES];
if (salt != null)
{
if (salt.Length != 16)
throw new ArgumentException("salt length must be exactly 16 bytes");
this.salt = new byte[16];
Array.Copy(salt, 0, this.salt, 0, salt.Length);
}
if (personalization != null)
{
if (personalization.Length != 16)
throw new ArgumentException("personalization length must be exactly 16 bytes");
this.personalization = new byte[16];
Array.Copy(personalization, 0, this.personalization, 0, personalization.Length);
}
if (key != null)
{
if (key.Length > 64)
throw new ArgumentException("Keys > 64 are not supported");
this.key = new byte[key.Length];
Array.Copy(key, 0, this.key, 0, key.Length);
keyLength = key.Length;
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
Init();
}
// initialize chainValue
private void Init()
{
if (chainValue == null)
{
chainValue = new ulong[8];
chainValue[0] = blake2b_IV[0] ^ (ulong)(digestLength | (keyLength << 8) | 0x1010000);
// 0x1010000 = ((fanout << 16) | (depth << 24) | (leafLength <<
// 32));
// with fanout = 1; depth = 0; leafLength = 0;
chainValue[1] = blake2b_IV[1];// ^ nodeOffset; with nodeOffset = 0;
chainValue[2] = blake2b_IV[2];// ^ ( nodeDepth | (innerHashLength << 8) );
// with nodeDepth = 0; innerHashLength = 0;
chainValue[3] = blake2b_IV[3];
chainValue[4] = blake2b_IV[4];
chainValue[5] = blake2b_IV[5];
if (salt != null)
{
chainValue[4] ^= Pack.LE_To_UInt64(salt, 0);
chainValue[5] ^= Pack.LE_To_UInt64(salt, 8);
}
chainValue[6] = blake2b_IV[6];
chainValue[7] = blake2b_IV[7];
if (personalization != null)
{
chainValue[6] ^= Pack.LE_To_UInt64(personalization, 0);
chainValue[7] ^= Pack.LE_To_UInt64(personalization, 8);
}
}
}
private void InitializeInternalState()
{
// initialize v:
Array.Copy(chainValue, 0, internalState, 0, chainValue.Length);
Array.Copy(blake2b_IV, 0, internalState, chainValue.Length, 4);
internalState[12] = t0 ^ blake2b_IV[4];
internalState[13] = t1 ^ blake2b_IV[5];
internalState[14] = f0 ^ blake2b_IV[6];
internalState[15] = blake2b_IV[7];// ^ f1 with f1 = 0
}
/**
* update the message digest with a single byte.
*
* @param b the input byte to be entered.
*/
public virtual void Update(byte b)
{
int remainingLength = 0; // left bytes of buffer
// process the buffer if full else add to buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength == 0)
{ // full buffer
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^64
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);// clear buffer
buffer[0] = b;
bufferPos = 1;
}
else
{
buffer[bufferPos] = b;
bufferPos++;
return;
}
}
/**
* update the message digest with a block of bytes.
*
* @param message the byte array containing the data.
* @param offset the offset into the byte array where the data starts.
* @param len the length of the data.
*/
public virtual void BlockUpdate(byte[] message, int offset, int len)
{
if (message == null || len == 0)
return;
int remainingLength = 0; // left bytes of buffer
if (bufferPos != 0)
{ // commenced, incomplete buffer
// complete the buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength < len)
{ // full buffer + at least 1 byte
Array.Copy(message, offset, buffer, bufferPos,
remainingLength);
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^64
t1++;
}
Compress(buffer, 0);
bufferPos = 0;
Array.Clear(buffer, 0, buffer.Length);// clear buffer
}
else
{
Array.Copy(message, offset, buffer, bufferPos, len);
bufferPos += len;
return;
}
}
// process blocks except last block (also if last block is full)
int messagePos;
int blockWiseLastPos = offset + len - BLOCK_LENGTH_BYTES;
for (messagePos = offset + remainingLength; messagePos < blockWiseLastPos; messagePos += BLOCK_LENGTH_BYTES)
{ // block wise 128 bytes
// without buffer:
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{
t1++;
}
Compress(message, messagePos);
}
// fill the buffer with left bytes, this might be a full block
Array.Copy(message, messagePos, buffer, 0, offset + len
- messagePos);
bufferPos += offset + len - messagePos;
}
/**
* close the digest, producing the final digest value. The doFinal
* call leaves the digest reset.
* Key, salt and personal string remain.
*
* @param out the array the digest is to be copied into.
* @param outOffset the offset into the out array the digest is to start at.
*/
public virtual int DoFinal(byte[] output, int outOffset)
{
f0 = 0xFFFFFFFFFFFFFFFFUL;
t0 += (ulong)bufferPos;
if (bufferPos > 0 && t0 == 0)
{
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null
Array.Clear(internalState, 0, internalState.Length);
for (int i = 0; i < chainValue.Length && (i * 8 < digestLength); i++)
{
byte[] bytes = Pack.UInt64_To_LE(chainValue[i]);
if (i * 8 < digestLength - 8)
{
Array.Copy(bytes, 0, output, outOffset + i * 8, 8);
}
else
{
Array.Copy(bytes, 0, output, outOffset + i * 8, digestLength - (i * 8));
}
}
Array.Clear(chainValue, 0, chainValue.Length);
Reset();
return digestLength;
}
/**
* Reset the digest back to it's initial state.
* The key, the salt and the personal string will
* remain for further computations.
*/
public virtual void Reset()
{
bufferPos = 0;
f0 = 0L;
t0 = 0L;
t1 = 0L;
chainValue = null;
Array.Clear(buffer, 0, buffer.Length);
if (key != null)
{
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
Init();
}
private void Compress(byte[] message, int messagePos)
{
InitializeInternalState();
ulong[] m = new ulong[16];
for (int j = 0; j < 16; j++)
{
m[j] = Pack.LE_To_UInt64(message, messagePos + j * 8);
}
for (int round = 0; round < ROUNDS; round++)
{
// G apply to columns of internalState:m[blake2b_sigma[round][2 * blockPos]] /+1
G(m[blake2b_sigma[round,0]], m[blake2b_sigma[round,1]], 0, 4, 8, 12);
G(m[blake2b_sigma[round,2]], m[blake2b_sigma[round,3]], 1, 5, 9, 13);
G(m[blake2b_sigma[round,4]], m[blake2b_sigma[round,5]], 2, 6, 10, 14);
G(m[blake2b_sigma[round,6]], m[blake2b_sigma[round,7]], 3, 7, 11, 15);
// G apply to diagonals of internalState:
G(m[blake2b_sigma[round,8]], m[blake2b_sigma[round,9]], 0, 5, 10, 15);
G(m[blake2b_sigma[round,10]], m[blake2b_sigma[round,11]], 1, 6, 11, 12);
G(m[blake2b_sigma[round,12]], m[blake2b_sigma[round,13]], 2, 7, 8, 13);
G(m[blake2b_sigma[round,14]], m[blake2b_sigma[round,15]], 3, 4, 9, 14);
}
// update chain values:
for (int offset = 0; offset < chainValue.Length; offset++)
{
chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8];
}
}
private void G(ulong m1, ulong m2, int posA, int posB, int posC, int posD)
{
internalState[posA] = internalState[posA] + internalState[posB] + m1;
internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 32);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE
internalState[posA] = internalState[posA] + internalState[posB] + m2;
internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 16);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE
}
private static ulong Rotr64(ulong x, int rot)
{
return x >> rot | x << -rot;
}
/**
* return the algorithm name
*
* @return the algorithm name
*/
public virtual string AlgorithmName
{
get { return "BLAKE2b"; }
}
/**
* return the size, in bytes, of the digest produced by this message digest.
*
* @return the size, in bytes, of the digest produced by this message digest.
*/
public virtual int GetDigestSize()
{
return digestLength;
}
/**
* Return the size in bytes of the internal buffer the digest applies it's compression
* function to.
*
* @return byte length of the digests internal buffer.
*/
public virtual int GetByteLength()
{
return BLOCK_LENGTH_BYTES;
}
/**
* Overwrite the key
* if it is no longer used (zeroization)
*/
public virtual void ClearKey()
{
if (key != null)
{
Array.Clear(key, 0, key.Length);
Array.Clear(buffer, 0, buffer.Length);
}
}
/**
* Overwrite the salt (pepper) if it
* is secret and no longer used (zeroization)
*/
public virtual void ClearSalt()
{
if (salt != null)
{
Array.Clear(salt, 0, salt.Length);
}
}
}
}

View File

@ -0,0 +1,550 @@
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
using System;
namespace Org.BouncyCastle.Crypto.Digests
{
/*
The BLAKE2 cryptographic hash function was designed by Jean-
Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and Christian
Winnerlein.
Reference Implementation and Description can be found at: https://blake2.net/
RFC: https://tools.ietf.org/html/rfc7693
This implementation does not support the Tree Hashing Mode.
For unkeyed hashing, developers adapting BLAKE2 to ASN.1 - based
message formats SHOULD use the OID tree at x = 1.3.6.1.4.1.1722.12.2.
Algorithm | Target | Collision | Hash | Hash ASN.1 |
Identifier | Arch | Security | nn | OID Suffix |
---------------+--------+-----------+------+------------+
id-blake2s128 | 32-bit | 2**64 | 16 | x.2.4 |
id-blake2s160 | 32-bit | 2**80 | 20 | x.2.5 |
id-blake2s224 | 32-bit | 2**112 | 28 | x.2.7 |
id-blake2s256 | 32-bit | 2**128 | 32 | x.2.8 |
---------------+--------+-----------+------+------------+
*/
/**
* Implementation of the cryptographic hash function BLAKE2s.
* <p/>
* BLAKE2s offers a built-in keying mechanism to be used directly
* for authentication ("Prefix-MAC") rather than a HMAC construction.
* <p/>
* BLAKE2s offers a built-in support for a salt for randomized hashing
* and a personal string for defining a unique hash function for each application.
* <p/>
* BLAKE2s is optimized for 32-bit platforms and produces digests of any size
* between 1 and 32 bytes.
*/
public class Blake2sDigest
: IDigest
{
/**
* BLAKE2s Initialization Vector
**/
private static readonly uint[] blake2s_IV =
// Produced from the square root of primes 2, 3, 5, 7, 11, 13, 17, 19.
// The same as SHA-256 IV.
{
0x6a09e667, 0xbb67ae85, 0x3c6ef372,
0xa54ff53a, 0x510e527f, 0x9b05688c,
0x1f83d9ab, 0x5be0cd19
};
/**
* Message word permutations
**/
private static readonly byte[,] blake2s_sigma =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }
};
private const int ROUNDS = 10; // to use for Catenas H'
private const int BLOCK_LENGTH_BYTES = 64;// bytes
// General parameters:
private int digestLength = 32; // 1- 32 bytes
private int keyLength = 0; // 0 - 32 bytes for keyed hashing for MAC
private byte[] salt = null;
private byte[] personalization = null;
private byte[] key = null;
// Tree hashing parameters:
// Because this class does not implement the Tree Hashing Mode,
// these parameters can be treated as constants (see Init() function)
/*
* private int fanout = 1; // 0-255
* private int depth = 1; // 1 - 255
* private int leafLength= 0;
* private long nodeOffset = 0L;
* private int nodeDepth = 0;
* private int innerHashLength = 0;
*/
/**
* Whenever this buffer overflows, it will be processed in the Compress()
* function. For performance issues, long messages will not use this buffer.
*/
private byte[] buffer = null;
/**
* Position of last inserted byte
**/
private int bufferPos = 0;// a value from 0 up to BLOCK_LENGTH_BYTES
/**
* Internal state, in the BLAKE2 paper it is called v
**/
private uint[] internalState = new uint[16];
/**
* State vector, in the BLAKE2 paper it is called h
**/
private uint[] chainValue = null;
// counter (counts bytes): Length up to 2^64 are supported
/**
* holds least significant bits of counter
**/
private uint t0 = 0;
/**
* holds most significant bits of counter
**/
private uint t1 = 0;
/**
* finalization flag, for last block: ~0
**/
private uint f0 = 0;
// For Tree Hashing Mode, not used here:
// private long f1 = 0L; // finalization flag, for last node: ~0L
/**
* BLAKE2s-256 for hashing.
*/
public Blake2sDigest()
: this(256)
{
}
public Blake2sDigest(Blake2sDigest digest)
{
this.bufferPos = digest.bufferPos;
this.buffer = Arrays.Clone(digest.buffer);
this.keyLength = digest.keyLength;
this.key = Arrays.Clone(digest.key);
this.digestLength = digest.digestLength;
this.chainValue = Arrays.Clone(digest.chainValue);
this.personalization = Arrays.Clone(digest.personalization);
}
/**
* BLAKE2s for hashing.
*
* @param digestBits the desired digest length in bits. Must be a multiple of 8 and less than 256.
*/
public Blake2sDigest(int digestBits)
{
if (digestBits < 8 || digestBits > 256 || digestBits % 8 != 0)
throw new ArgumentException("BLAKE2s digest bit length must be a multiple of 8 and not greater than 256");
buffer = new byte[BLOCK_LENGTH_BYTES];
keyLength = 0;
digestLength = digestBits / 8;
Init();
}
/**
* BLAKE2s for authentication ("Prefix-MAC mode").
* <p/>
* After calling the doFinal() method, the key will remain to be used for
* further computations of this instance. The key can be overwritten using
* the clearKey() method.
*
* @param key a key up to 32 bytes or null
*/
public Blake2sDigest(byte[] key)
{
buffer = new byte[BLOCK_LENGTH_BYTES];
if (key != null)
{
if (key.Length > 32)
throw new ArgumentException("Keys > 32 are not supported");
this.key = new byte[key.Length];
Array.Copy(key, 0, this.key, 0, key.Length);
keyLength = key.Length;
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
digestLength = 32;
Init();
}
/**
* BLAKE2s with key, required digest length, salt and personalization.
* <p/>
* After calling the doFinal() method, the key, the salt and the personal
* string will remain and might be used for further computations with this
* instance. The key can be overwritten using the clearKey() method, the
* salt (pepper) can be overwritten using the clearSalt() method.
*
* @param key a key up to 32 bytes or null
* @param digestBytes from 1 up to 32 bytes
* @param salt 8 bytes or null
* @param personalization 8 bytes or null
*/
public Blake2sDigest(byte[] key, int digestBytes, byte[] salt,
byte[] personalization)
{
if (digestBytes < 1 || digestBytes > 32)
throw new ArgumentException("Invalid digest length (required: 1 - 32)");
this.digestLength = digestBytes;
this.buffer = new byte[BLOCK_LENGTH_BYTES];
if (salt != null)
{
if (salt.Length != 8)
throw new ArgumentException("Salt length must be exactly 8 bytes");
this.salt = new byte[8];
Array.Copy(salt, 0, this.salt, 0, salt.Length);
}
if (personalization != null)
{
if (personalization.Length != 8)
throw new ArgumentException("Personalization length must be exactly 8 bytes");
this.personalization = new byte[8];
Array.Copy(personalization, 0, this.personalization, 0, personalization.Length);
}
if (key != null)
{
if (key.Length > 32)
throw new ArgumentException("Keys > 32 bytes are not supported");
this.key = new byte[key.Length];
Array.Copy(key, 0, this.key, 0, key.Length);
keyLength = key.Length;
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
Init();
}
// initialize chainValue
private void Init()
{
if (chainValue == null)
{
chainValue = new uint[8];
chainValue[0] = blake2s_IV[0] ^ (uint)(digestLength | (keyLength << 8) | 0x1010000);
// 0x1010000 = ((fanout << 16) | (depth << 24));
// with fanout = 1; depth = 0;
chainValue[1] = blake2s_IV[1];// ^ leafLength; with leafLength = 0;
chainValue[2] = blake2s_IV[2];// ^ nodeOffset; with nodeOffset = 0;
chainValue[3] = blake2s_IV[3];// ^ ( (nodeOffset << 32) | (nodeDepth << 16) | (innerHashLength << 24) );
// with nodeDepth = 0; innerHashLength = 0;
chainValue[4] = blake2s_IV[4];
chainValue[5] = blake2s_IV[5];
if (salt != null)
{
chainValue[4] ^= Pack.LE_To_UInt32(salt, 0);
chainValue[5] ^= Pack.LE_To_UInt32(salt, 4);
}
chainValue[6] = blake2s_IV[6];
chainValue[7] = blake2s_IV[7];
if (personalization != null)
{
chainValue[6] ^= Pack.LE_To_UInt32(personalization, 0);
chainValue[7] ^= Pack.LE_To_UInt32(personalization, 4);
}
}
}
private void InitializeInternalState()
{
// initialize v:
Array.Copy(chainValue, 0, internalState, 0, chainValue.Length);
Array.Copy(blake2s_IV, 0, internalState, chainValue.Length, 4);
internalState[12] = t0 ^ blake2s_IV[4];
internalState[13] = t1 ^ blake2s_IV[5];
internalState[14] = f0 ^ blake2s_IV[6];
internalState[15] = blake2s_IV[7];// ^ f1 with f1 = 0
}
/**
* Update the message digest with a single byte.
*
* @param b the input byte to be entered.
*/
public virtual void Update(byte b)
{
int remainingLength; // left bytes of buffer
// process the buffer if full else add to buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength == 0)
{ // full buffer
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^32
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);// clear buffer
buffer[0] = b;
bufferPos = 1;
}
else
{
buffer[bufferPos] = b;
bufferPos++;
}
}
/**
* Update the message digest with a block of bytes.
*
* @param message the byte array containing the data.
* @param offset the offset into the byte array where the data starts.
* @param len the length of the data.
*/
public virtual void BlockUpdate(byte[] message, int offset, int len)
{
if (message == null || len == 0)
return;
int remainingLength = 0; // left bytes of buffer
if (bufferPos != 0)
{ // commenced, incomplete buffer
// complete the buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength < len)
{ // full buffer + at least 1 byte
Array.Copy(message, offset, buffer, bufferPos, remainingLength);
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^32
t1++;
}
Compress(buffer, 0);
bufferPos = 0;
Array.Clear(buffer, 0, buffer.Length);// clear buffer
}
else
{
Array.Copy(message, offset, buffer, bufferPos, len);
bufferPos += len;
return;
}
}
// process blocks except last block (also if last block is full)
int messagePos;
int blockWiseLastPos = offset + len - BLOCK_LENGTH_BYTES;
for (messagePos = offset + remainingLength;
messagePos < blockWiseLastPos;
messagePos += BLOCK_LENGTH_BYTES)
{ // block wise 64 bytes
// without buffer:
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{
t1++;
}
Compress(message, messagePos);
}
// fill the buffer with left bytes, this might be a full block
Array.Copy(message, messagePos, buffer, 0, offset + len
- messagePos);
bufferPos += offset + len - messagePos;
}
/**
* Close the digest, producing the final digest value. The doFinal() call
* leaves the digest reset. Key, salt and personal string remain.
*
* @param out the array the digest is to be copied into.
* @param outOffset the offset into the out array the digest is to start at.
*/
public virtual int DoFinal(byte[] output, int outOffset)
{
f0 = 0xFFFFFFFFU;
t0 += (uint)bufferPos;
// bufferPos may be < 64, so (t0 == 0) does not work
// for 2^32 < message length > 2^32 - 63
if ((t0 < 0) && (bufferPos > -t0))
{
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null
Array.Clear(internalState, 0, internalState.Length);
for (int i = 0; i < chainValue.Length && (i * 4 < digestLength); i++)
{
byte[] bytes = Pack.UInt32_To_LE(chainValue[i]);
if (i * 4 < digestLength - 4)
{
Array.Copy(bytes, 0, output, outOffset + i * 4, 4);
}
else
{
Array.Copy(bytes, 0, output, outOffset + i * 4, digestLength - (i * 4));
}
}
Array.Clear(chainValue, 0, chainValue.Length);
Reset();
return digestLength;
}
/**
* Reset the digest back to its initial state. The key, the salt and the
* personal string will remain for further computations.
*/
public virtual void Reset()
{
bufferPos = 0;
f0 = 0;
t0 = 0;
t1 = 0;
chainValue = null;
Array.Clear(buffer, 0, buffer.Length);
if (key != null)
{
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
Init();
}
private void Compress(byte[] message, int messagePos)
{
InitializeInternalState();
uint[] m = new uint[16];
for (int j = 0; j < 16; j++)
{
m[j] = Pack.LE_To_UInt32(message, messagePos + j * 4);
}
for (int round = 0; round < ROUNDS; round++)
{
// G apply to columns of internalState:m[blake2s_sigma[round][2 *
// blockPos]] /+1
G(m[blake2s_sigma[round,0]], m[blake2s_sigma[round,1]], 0, 4, 8, 12);
G(m[blake2s_sigma[round,2]], m[blake2s_sigma[round,3]], 1, 5, 9, 13);
G(m[blake2s_sigma[round,4]], m[blake2s_sigma[round,5]], 2, 6, 10, 14);
G(m[blake2s_sigma[round,6]], m[blake2s_sigma[round,7]], 3, 7, 11, 15);
// G apply to diagonals of internalState:
G(m[blake2s_sigma[round,8]], m[blake2s_sigma[round,9]], 0, 5, 10, 15);
G(m[blake2s_sigma[round,10]], m[blake2s_sigma[round,11]], 1, 6, 11, 12);
G(m[blake2s_sigma[round,12]], m[blake2s_sigma[round,13]], 2, 7, 8, 13);
G(m[blake2s_sigma[round,14]], m[blake2s_sigma[round,15]], 3, 4, 9, 14);
}
// update chain values:
for (int offset = 0; offset < chainValue.Length; offset++)
{
chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8];
}
}
private void G(uint m1, uint m2, int posA, int posB, int posC, int posD)
{
internalState[posA] = internalState[posA] + internalState[posB] + m1;
internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 16);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 12);
internalState[posA] = internalState[posA] + internalState[posB] + m2;
internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 8);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 7);
}
private uint rotr32(uint x, int rot)
{
return x >> rot | x << -rot;
}
/**
* Return the algorithm name.
*
* @return the algorithm name
*/
public virtual string AlgorithmName
{
get { return "BLAKE2s"; }
}
/**
* Return the size in bytes of the digest produced by this message digest.
*
* @return the size in bytes of the digest produced by this message digest.
*/
public virtual int GetDigestSize()
{
return digestLength;
}
/**
* Return the size in bytes of the internal buffer the digest applies its
* compression function to.
*
* @return byte length of the digest's internal buffer.
*/
public virtual int GetByteLength()
{
return BLOCK_LENGTH_BYTES;
}
/**
* Overwrite the key if it is no longer used (zeroization).
*/
public virtual void ClearKey()
{
if (key != null)
{
Array.Clear(key, 0, key.Length);
Array.Clear(buffer, 0, buffer.Length);
}
}
/**
* Overwrite the salt (pepper) if it is secret and no longer used
* (zeroization).
*/
public virtual void ClearSalt()
{
if (salt != null)
{
Array.Clear(salt, 0, salt.Length);
}
}
}
}

View File

@ -0,0 +1,114 @@
using System;
using BrowserPass.BouncyCastle.crypto.util;
namespace Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Customizable SHAKE function.
/// </summary>
public class CShakeDigest : ShakeDigest
{
private static readonly byte[] padding = new byte[100];
private readonly byte[] diff;
/// <summary>
/// Base constructor
/// </summary>
/// <param name="bitLength">bit length of the underlying SHAKE function, 128 or 256.</param>
/// <param name="N">the function name string, note this is reserved for use by NIST. Avoid using it if not required.</param>
/// <param name="S">the customization string - available for local use.</param>
public CShakeDigest(int bitLength, byte[] N, byte[] S) : base(bitLength)
{
if ((N == null || N.Length == 0) && (S == null || S.Length == 0))
{
diff = null;
}
else
{
diff = Arrays.ConcatenateAll(XofUtilities.LeftEncode(rate / 8), encodeString(N), encodeString(S));
DiffPadAndAbsorb();
}
}
// bytepad in SP 800-185
private void DiffPadAndAbsorb()
{
int blockSize = rate / 8;
Absorb(diff, 0, diff.Length);
int delta = diff.Length % blockSize;
// only add padding if needed
if (delta != 0)
{
int required = blockSize - delta;
while (required > padding.Length)
{
Absorb(padding, 0, padding.Length);
required -= padding.Length;
}
Absorb(padding, 0, required);
}
}
private byte[] encodeString(byte[] str)
{
if (str == null || str.Length == 0)
{
return XofUtilities.LeftEncode(0);
}
return Arrays.Concatenate(XofUtilities.LeftEncode(str.Length * 8L), str);
}
public override string AlgorithmName
{
get { return "CSHAKE" + fixedOutputLength; }
}
public override int DoFinal(byte[] output, int outOff)
{
return DoFinal(output, outOff,GetDigestSize());
}
public override int DoFinal(byte[] output, int outOff, int outLen)
{
int length = DoOutput(output, outOff, outLen);
Reset();
return length;
}
public override int DoOutput(byte[] output, int outOff, int outLen)
{
if (diff != null)
{
if (!squeezing)
{
AbsorbBits(0x00, 2);
}
Squeeze(output, outOff, ((long)outLen) * 8);
return outLen;
}
else
{
return base.DoOutput(output, outOff, outLen);
}
}
public override void Reset()
{
base.Reset();
if (diff != null)
{
DiffPadAndAbsorb();
}
}
}
}

View File

@ -0,0 +1,526 @@
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
namespace Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of Ukrainian DSTU 7564 hash function
*/
public class Dstu7564Digest
: IDigest, IMemoable
{
private const int NB_512 = 8; //Number of 8-byte words in state for <=256-bit hash code.
private const int NB_1024 = 16; //Number of 8-byte words in state for <=512-bit hash code.
private const int NR_512 = 10; //Number of rounds for 512-bit state.
private const int NR_1024 = 14; //Number of rounds for 1024-bit state.
private int hashSize;
private int blockSize;
private int columns;
private int rounds;
private ulong[] state;
private ulong[] tempState1;
private ulong[] tempState2;
// TODO Guard against 'inputBlocks' overflow (2^64 blocks)
private ulong inputBlocks;
private int bufOff;
private byte[] buf;
public Dstu7564Digest(Dstu7564Digest digest)
{
CopyIn(digest);
}
private void CopyIn(Dstu7564Digest digest)
{
this.hashSize = digest.hashSize;
this.blockSize = digest.blockSize;
this.rounds = digest.rounds;
if (columns > 0 && columns == digest.columns)
{
Array.Copy(digest.state, 0, state, 0, columns);
Array.Copy(digest.buf, 0, buf, 0, blockSize);
}
else
{
this.columns = digest.columns;
this.state = Arrays.Clone(digest.state);
this.tempState1 = new ulong[columns];
this.tempState2 = new ulong[columns];
this.buf = Arrays.Clone(digest.buf);
}
this.inputBlocks = digest.inputBlocks;
this.bufOff = digest.bufOff;
}
public Dstu7564Digest(int hashSizeBits)
{
if (hashSizeBits == 256 || hashSizeBits == 384 || hashSizeBits == 512)
{
this.hashSize = hashSizeBits / 8;
}
else
{
throw new ArgumentException("Hash size is not recommended. Use 256/384/512 instead");
}
if (hashSizeBits > 256)
{
this.columns = NB_1024;
this.rounds = NR_1024;
}
else
{
this.columns = NB_512;
this.rounds = NR_512;
}
this.blockSize = columns << 3;
this.state = new ulong[columns];
this.state[0] = (ulong)blockSize;
this.tempState1 = new ulong[columns];
this.tempState2 = new ulong[columns];
this.buf = new byte[blockSize];
}
public virtual string AlgorithmName
{
get { return "DSTU7564"; }
}
public virtual int GetDigestSize()
{
return hashSize;
}
public virtual int GetByteLength()
{
return blockSize;
}
public virtual void Update(byte input)
{
buf[bufOff++] = input;
if (bufOff == blockSize)
{
ProcessBlock(buf, 0);
bufOff = 0;
++inputBlocks;
}
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
while (bufOff != 0 && length > 0)
{
Update(input[inOff++]);
--length;
}
if (length > 0)
{
while (length >= blockSize)
{
ProcessBlock(input, inOff);
inOff += blockSize;
length -= blockSize;
++inputBlocks;
}
while (length > 0)
{
Update(input[inOff++]);
--length;
}
}
}
public virtual int DoFinal(byte[] output, int outOff)
{
// Apply padding: terminator byte and 96-bit length field
{
int inputBytes = bufOff;
buf[bufOff++] = (byte)0x80;
int lenPos = blockSize - 12;
if (bufOff > lenPos)
{
while (bufOff < blockSize)
{
buf[bufOff++] = 0;
}
bufOff = 0;
ProcessBlock(buf, 0);
}
while (bufOff < lenPos)
{
buf[bufOff++] = 0;
}
ulong c = ((inputBlocks & 0xFFFFFFFFUL) * (ulong)blockSize + (uint)inputBytes) << 3;
Pack.UInt32_To_LE((uint)c, buf, bufOff);
bufOff += 4;
c >>= 32;
c += ((inputBlocks >> 32) * (ulong)blockSize) << 3;
Pack.UInt64_To_LE(c, buf, bufOff);
// bufOff += 8;
ProcessBlock(buf, 0);
}
{
Array.Copy(state, 0, tempState1, 0, columns);
P(tempState1);
for (int col = 0; col < columns; ++col)
{
state[col] ^= tempState1[col];
}
}
int neededColumns = hashSize / 8;
for (int col = columns - neededColumns; col < columns; ++col)
{
Pack.UInt64_To_LE(state[col], output, outOff);
outOff += 8;
}
Reset();
return hashSize;
}
public virtual void Reset()
{
Array.Clear(state, 0, state.Length);
state[0] = (ulong)blockSize;
inputBlocks = 0;
bufOff = 0;
}
protected virtual void ProcessBlock(byte[] input, int inOff)
{
int pos = inOff;
for (int col = 0; col < columns; ++col)
{
ulong word = Pack.LE_To_UInt64(input, pos);
pos += 8;
tempState1[col] = state[col] ^ word;
tempState2[col] = word;
}
P(tempState1);
Q(tempState2);
for (int col = 0; col < columns; ++col)
{
state[col] ^= tempState1[col] ^ tempState2[col];
}
}
private void P(ulong[] s)
{
for (int round = 0; round < rounds; ++round)
{
ulong rc = (ulong)round;
/* AddRoundConstants */
for (int col = 0; col < columns; ++col)
{
s[col] ^= rc;
rc += 0x10L;
}
ShiftRows(s);
SubBytes(s);
MixColumns(s);
}
}
private void Q(ulong[] s)
{
for (int round = 0; round < rounds; ++round)
{
/* AddRoundConstantsQ */
ulong rc = ((ulong)(((columns - 1) << 4) ^ round) << 56) | 0x00F0F0F0F0F0F0F3UL;
for (int col = 0; col < columns; ++col)
{
s[col] += rc;
rc -= 0x1000000000000000L;
}
ShiftRows(s);
SubBytes(s);
MixColumns(s);
}
}
private static ulong MixColumn(ulong c)
{
//// Calculate column multiplied by powers of 'x'
//ulong x0 = c;
//ulong x1 = ((x0 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x0 & 0x8080808080808080UL) >> 7) * 0x1DUL);
//ulong x2 = ((x1 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x1 & 0x8080808080808080UL) >> 7) * 0x1DUL);
//ulong x3 = ((x2 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x2 & 0x8080808080808080UL) >> 7) * 0x1DUL);
//// Calculate products with circulant matrix from (0x01, 0x01, 0x05, 0x01, 0x08, 0x06, 0x07, 0x04)
//ulong m0 = x0;
//ulong m1 = x0;
//ulong m2 = x0 ^ x2;
//ulong m3 = x0;
//ulong m4 = x3;
//ulong m5 = x1 ^ x2;
//ulong m6 = x0 ^ x1 ^ x2;
//ulong m7 = x2;
//// Assemble the rotated products
//return m0
// ^ Rotate(8, m1)
// ^ Rotate(16, m2)
// ^ Rotate(24, m3)
// ^ Rotate(32, m4)
// ^ Rotate(40, m5)
// ^ Rotate(48, m6)
// ^ Rotate(56, m7);
// Multiply elements by 'x'
ulong x1 = ((c & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((c & 0x8080808080808080UL) >> 7) * 0x1DUL);
ulong u, v;
u = Rotate(8, c) ^ c;
u ^= Rotate(16, u);
u ^= Rotate(48, c);
v = u ^ c ^ x1;
// Multiply elements by 'x^2'
v = ((v & 0x3F3F3F3F3F3F3F3FUL) << 2) ^ (((v & 0x8080808080808080UL) >> 6) * 0x1DUL) ^ (((v & 0x4040404040404040UL) >> 6) * 0x1DUL);
return u ^ Rotate(32, v) ^ Rotate(40, x1) ^ Rotate(48, x1);
}
private void MixColumns(ulong[] s)
{
for (int col = 0; col < columns; ++col)
{
s[col] = MixColumn(s[col]);
}
}
private static ulong Rotate(int n, ulong x)
{
return (x >> n) | (x << -n);
}
private void ShiftRows(ulong[] s)
{
switch (columns)
{
case NB_512:
{
ulong c0 = s[0], c1 = s[1], c2 = s[2], c3 = s[3];
ulong c4 = s[4], c5 = s[5], c6 = s[6], c7 = s[7];
ulong d;
d = (c0 ^ c4) & 0xFFFFFFFF00000000UL; c0 ^= d; c4 ^= d;
d = (c1 ^ c5) & 0x00FFFFFFFF000000UL; c1 ^= d; c5 ^= d;
d = (c2 ^ c6) & 0x0000FFFFFFFF0000UL; c2 ^= d; c6 ^= d;
d = (c3 ^ c7) & 0x000000FFFFFFFF00UL; c3 ^= d; c7 ^= d;
d = (c0 ^ c2) & 0xFFFF0000FFFF0000UL; c0 ^= d; c2 ^= d;
d = (c1 ^ c3) & 0x00FFFF0000FFFF00UL; c1 ^= d; c3 ^= d;
d = (c4 ^ c6) & 0xFFFF0000FFFF0000UL; c4 ^= d; c6 ^= d;
d = (c5 ^ c7) & 0x00FFFF0000FFFF00UL; c5 ^= d; c7 ^= d;
d = (c0 ^ c1) & 0xFF00FF00FF00FF00UL; c0 ^= d; c1 ^= d;
d = (c2 ^ c3) & 0xFF00FF00FF00FF00UL; c2 ^= d; c3 ^= d;
d = (c4 ^ c5) & 0xFF00FF00FF00FF00UL; c4 ^= d; c5 ^= d;
d = (c6 ^ c7) & 0xFF00FF00FF00FF00UL; c6 ^= d; c7 ^= d;
s[0] = c0; s[1] = c1; s[2] = c2; s[3] = c3;
s[4] = c4; s[5] = c5; s[6] = c6; s[7] = c7;
break;
}
case NB_1024:
{
ulong c00 = s[0], c01 = s[1], c02 = s[2], c03 = s[3];
ulong c04 = s[4], c05 = s[5], c06 = s[6], c07 = s[7];
ulong c08 = s[8], c09 = s[9], c10 = s[10], c11 = s[11];
ulong c12 = s[12], c13 = s[13], c14 = s[14], c15 = s[15];
ulong d;
// NOTE: Row 7 is shifted by 11
d = (c00 ^ c08) & 0xFF00000000000000UL; c00 ^= d; c08 ^= d;
d = (c01 ^ c09) & 0xFF00000000000000UL; c01 ^= d; c09 ^= d;
d = (c02 ^ c10) & 0xFFFF000000000000UL; c02 ^= d; c10 ^= d;
d = (c03 ^ c11) & 0xFFFFFF0000000000UL; c03 ^= d; c11 ^= d;
d = (c04 ^ c12) & 0xFFFFFFFF00000000UL; c04 ^= d; c12 ^= d;
d = (c05 ^ c13) & 0x00FFFFFFFF000000UL; c05 ^= d; c13 ^= d;
d = (c06 ^ c14) & 0x00FFFFFFFFFF0000UL; c06 ^= d; c14 ^= d;
d = (c07 ^ c15) & 0x00FFFFFFFFFFFF00UL; c07 ^= d; c15 ^= d;
d = (c00 ^ c04) & 0x00FFFFFF00000000UL; c00 ^= d; c04 ^= d;
d = (c01 ^ c05) & 0xFFFFFFFFFF000000UL; c01 ^= d; c05 ^= d;
d = (c02 ^ c06) & 0xFF00FFFFFFFF0000UL; c02 ^= d; c06 ^= d;
d = (c03 ^ c07) & 0xFF0000FFFFFFFF00UL; c03 ^= d; c07 ^= d;
d = (c08 ^ c12) & 0x00FFFFFF00000000UL; c08 ^= d; c12 ^= d;
d = (c09 ^ c13) & 0xFFFFFFFFFF000000UL; c09 ^= d; c13 ^= d;
d = (c10 ^ c14) & 0xFF00FFFFFFFF0000UL; c10 ^= d; c14 ^= d;
d = (c11 ^ c15) & 0xFF0000FFFFFFFF00UL; c11 ^= d; c15 ^= d;
d = (c00 ^ c02) & 0xFFFF0000FFFF0000UL; c00 ^= d; c02 ^= d;
d = (c01 ^ c03) & 0x00FFFF0000FFFF00UL; c01 ^= d; c03 ^= d;
d = (c04 ^ c06) & 0xFFFF0000FFFF0000UL; c04 ^= d; c06 ^= d;
d = (c05 ^ c07) & 0x00FFFF0000FFFF00UL; c05 ^= d; c07 ^= d;
d = (c08 ^ c10) & 0xFFFF0000FFFF0000UL; c08 ^= d; c10 ^= d;
d = (c09 ^ c11) & 0x00FFFF0000FFFF00UL; c09 ^= d; c11 ^= d;
d = (c12 ^ c14) & 0xFFFF0000FFFF0000UL; c12 ^= d; c14 ^= d;
d = (c13 ^ c15) & 0x00FFFF0000FFFF00UL; c13 ^= d; c15 ^= d;
d = (c00 ^ c01) & 0xFF00FF00FF00FF00UL; c00 ^= d; c01 ^= d;
d = (c02 ^ c03) & 0xFF00FF00FF00FF00UL; c02 ^= d; c03 ^= d;
d = (c04 ^ c05) & 0xFF00FF00FF00FF00UL; c04 ^= d; c05 ^= d;
d = (c06 ^ c07) & 0xFF00FF00FF00FF00UL; c06 ^= d; c07 ^= d;
d = (c08 ^ c09) & 0xFF00FF00FF00FF00UL; c08 ^= d; c09 ^= d;
d = (c10 ^ c11) & 0xFF00FF00FF00FF00UL; c10 ^= d; c11 ^= d;
d = (c12 ^ c13) & 0xFF00FF00FF00FF00UL; c12 ^= d; c13 ^= d;
d = (c14 ^ c15) & 0xFF00FF00FF00FF00UL; c14 ^= d; c15 ^= d;
s[0] = c00; s[1] = c01; s[2] = c02; s[3] = c03;
s[4] = c04; s[5] = c05; s[6] = c06; s[7] = c07;
s[8] = c08; s[9] = c09; s[10] = c10; s[11] = c11;
s[12] = c12; s[13] = c13; s[14] = c14; s[15] = c15;
break;
}
default:
{
throw new InvalidOperationException("unsupported state size: only 512/1024 are allowed");
}
}
}
private void SubBytes(ulong[] s)
{
for (int i = 0; i < columns; ++i)
{
ulong u = s[i];
uint lo = (uint)u, hi = (uint)(u >> 32);
byte t0 = S0[lo & 0xFF];
byte t1 = S1[(lo >> 8) & 0xFF];
byte t2 = S2[(lo >> 16) & 0xFF];
byte t3 = S3[lo >> 24];
lo = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24);
byte t4 = S0[hi & 0xFF];
byte t5 = S1[(hi >> 8) & 0xFF];
byte t6 = S2[(hi >> 16) & 0xFF];
byte t7 = S3[hi >> 24];
hi = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24);
s[i] = (ulong)lo | ((ulong)hi << 32);
}
}
private static readonly byte[] S0 = new byte[] {
0xa8, 0x43, 0x5f, 0x06, 0x6b, 0x75, 0x6c, 0x59, 0x71, 0xdf, 0x87, 0x95, 0x17, 0xf0, 0xd8, 0x09,
0x6d, 0xf3, 0x1d, 0xcb, 0xc9, 0x4d, 0x2c, 0xaf, 0x79, 0xe0, 0x97, 0xfd, 0x6f, 0x4b, 0x45, 0x39,
0x3e, 0xdd, 0xa3, 0x4f, 0xb4, 0xb6, 0x9a, 0x0e, 0x1f, 0xbf, 0x15, 0xe1, 0x49, 0xd2, 0x93, 0xc6,
0x92, 0x72, 0x9e, 0x61, 0xd1, 0x63, 0xfa, 0xee, 0xf4, 0x19, 0xd5, 0xad, 0x58, 0xa4, 0xbb, 0xa1,
0xdc, 0xf2, 0x83, 0x37, 0x42, 0xe4, 0x7a, 0x32, 0x9c, 0xcc, 0xab, 0x4a, 0x8f, 0x6e, 0x04, 0x27,
0x2e, 0xe7, 0xe2, 0x5a, 0x96, 0x16, 0x23, 0x2b, 0xc2, 0x65, 0x66, 0x0f, 0xbc, 0xa9, 0x47, 0x41,
0x34, 0x48, 0xfc, 0xb7, 0x6a, 0x88, 0xa5, 0x53, 0x86, 0xf9, 0x5b, 0xdb, 0x38, 0x7b, 0xc3, 0x1e,
0x22, 0x33, 0x24, 0x28, 0x36, 0xc7, 0xb2, 0x3b, 0x8e, 0x77, 0xba, 0xf5, 0x14, 0x9f, 0x08, 0x55,
0x9b, 0x4c, 0xfe, 0x60, 0x5c, 0xda, 0x18, 0x46, 0xcd, 0x7d, 0x21, 0xb0, 0x3f, 0x1b, 0x89, 0xff,
0xeb, 0x84, 0x69, 0x3a, 0x9d, 0xd7, 0xd3, 0x70, 0x67, 0x40, 0xb5, 0xde, 0x5d, 0x30, 0x91, 0xb1,
0x78, 0x11, 0x01, 0xe5, 0x00, 0x68, 0x98, 0xa0, 0xc5, 0x02, 0xa6, 0x74, 0x2d, 0x0b, 0xa2, 0x76,
0xb3, 0xbe, 0xce, 0xbd, 0xae, 0xe9, 0x8a, 0x31, 0x1c, 0xec, 0xf1, 0x99, 0x94, 0xaa, 0xf6, 0x26,
0x2f, 0xef, 0xe8, 0x8c, 0x35, 0x03, 0xd4, 0x7f, 0xfb, 0x05, 0xc1, 0x5e, 0x90, 0x20, 0x3d, 0x82,
0xf7, 0xea, 0x0a, 0x0d, 0x7e, 0xf8, 0x50, 0x1a, 0xc4, 0x07, 0x57, 0xb8, 0x3c, 0x62, 0xe3, 0xc8,
0xac, 0x52, 0x64, 0x10, 0xd0, 0xd9, 0x13, 0x0c, 0x12, 0x29, 0x51, 0xb9, 0xcf, 0xd6, 0x73, 0x8d,
0x81, 0x54, 0xc0, 0xed, 0x4e, 0x44, 0xa7, 0x2a, 0x85, 0x25, 0xe6, 0xca, 0x7c, 0x8b, 0x56, 0x80
};
private static readonly byte[] S1 = new byte[] {
0xce, 0xbb, 0xeb, 0x92, 0xea, 0xcb, 0x13, 0xc1, 0xe9, 0x3a, 0xd6, 0xb2, 0xd2, 0x90, 0x17, 0xf8,
0x42, 0x15, 0x56, 0xb4, 0x65, 0x1c, 0x88, 0x43, 0xc5, 0x5c, 0x36, 0xba, 0xf5, 0x57, 0x67, 0x8d,
0x31, 0xf6, 0x64, 0x58, 0x9e, 0xf4, 0x22, 0xaa, 0x75, 0x0f, 0x02, 0xb1, 0xdf, 0x6d, 0x73, 0x4d,
0x7c, 0x26, 0x2e, 0xf7, 0x08, 0x5d, 0x44, 0x3e, 0x9f, 0x14, 0xc8, 0xae, 0x54, 0x10, 0xd8, 0xbc,
0x1a, 0x6b, 0x69, 0xf3, 0xbd, 0x33, 0xab, 0xfa, 0xd1, 0x9b, 0x68, 0x4e, 0x16, 0x95, 0x91, 0xee,
0x4c, 0x63, 0x8e, 0x5b, 0xcc, 0x3c, 0x19, 0xa1, 0x81, 0x49, 0x7b, 0xd9, 0x6f, 0x37, 0x60, 0xca,
0xe7, 0x2b, 0x48, 0xfd, 0x96, 0x45, 0xfc, 0x41, 0x12, 0x0d, 0x79, 0xe5, 0x89, 0x8c, 0xe3, 0x20,
0x30, 0xdc, 0xb7, 0x6c, 0x4a, 0xb5, 0x3f, 0x97, 0xd4, 0x62, 0x2d, 0x06, 0xa4, 0xa5, 0x83, 0x5f,
0x2a, 0xda, 0xc9, 0x00, 0x7e, 0xa2, 0x55, 0xbf, 0x11, 0xd5, 0x9c, 0xcf, 0x0e, 0x0a, 0x3d, 0x51,
0x7d, 0x93, 0x1b, 0xfe, 0xc4, 0x47, 0x09, 0x86, 0x0b, 0x8f, 0x9d, 0x6a, 0x07, 0xb9, 0xb0, 0x98,
0x18, 0x32, 0x71, 0x4b, 0xef, 0x3b, 0x70, 0xa0, 0xe4, 0x40, 0xff, 0xc3, 0xa9, 0xe6, 0x78, 0xf9,
0x8b, 0x46, 0x80, 0x1e, 0x38, 0xe1, 0xb8, 0xa8, 0xe0, 0x0c, 0x23, 0x76, 0x1d, 0x25, 0x24, 0x05,
0xf1, 0x6e, 0x94, 0x28, 0x9a, 0x84, 0xe8, 0xa3, 0x4f, 0x77, 0xd3, 0x85, 0xe2, 0x52, 0xf2, 0x82,
0x50, 0x7a, 0x2f, 0x74, 0x53, 0xb3, 0x61, 0xaf, 0x39, 0x35, 0xde, 0xcd, 0x1f, 0x99, 0xac, 0xad,
0x72, 0x2c, 0xdd, 0xd0, 0x87, 0xbe, 0x5e, 0xa6, 0xec, 0x04, 0xc6, 0x03, 0x34, 0xfb, 0xdb, 0x59,
0xb6, 0xc2, 0x01, 0xf0, 0x5a, 0xed, 0xa7, 0x66, 0x21, 0x7f, 0x8a, 0x27, 0xc7, 0xc0, 0x29, 0xd7
};
private static readonly byte[] S2 = new byte[] {
0x93, 0xd9, 0x9a, 0xb5, 0x98, 0x22, 0x45, 0xfc, 0xba, 0x6a, 0xdf, 0x02, 0x9f, 0xdc, 0x51, 0x59,
0x4a, 0x17, 0x2b, 0xc2, 0x94, 0xf4, 0xbb, 0xa3, 0x62, 0xe4, 0x71, 0xd4, 0xcd, 0x70, 0x16, 0xe1,
0x49, 0x3c, 0xc0, 0xd8, 0x5c, 0x9b, 0xad, 0x85, 0x53, 0xa1, 0x7a, 0xc8, 0x2d, 0xe0, 0xd1, 0x72,
0xa6, 0x2c, 0xc4, 0xe3, 0x76, 0x78, 0xb7, 0xb4, 0x09, 0x3b, 0x0e, 0x41, 0x4c, 0xde, 0xb2, 0x90,
0x25, 0xa5, 0xd7, 0x03, 0x11, 0x00, 0xc3, 0x2e, 0x92, 0xef, 0x4e, 0x12, 0x9d, 0x7d, 0xcb, 0x35,
0x10, 0xd5, 0x4f, 0x9e, 0x4d, 0xa9, 0x55, 0xc6, 0xd0, 0x7b, 0x18, 0x97, 0xd3, 0x36, 0xe6, 0x48,
0x56, 0x81, 0x8f, 0x77, 0xcc, 0x9c, 0xb9, 0xe2, 0xac, 0xb8, 0x2f, 0x15, 0xa4, 0x7c, 0xda, 0x38,
0x1e, 0x0b, 0x05, 0xd6, 0x14, 0x6e, 0x6c, 0x7e, 0x66, 0xfd, 0xb1, 0xe5, 0x60, 0xaf, 0x5e, 0x33,
0x87, 0xc9, 0xf0, 0x5d, 0x6d, 0x3f, 0x88, 0x8d, 0xc7, 0xf7, 0x1d, 0xe9, 0xec, 0xed, 0x80, 0x29,
0x27, 0xcf, 0x99, 0xa8, 0x50, 0x0f, 0x37, 0x24, 0x28, 0x30, 0x95, 0xd2, 0x3e, 0x5b, 0x40, 0x83,
0xb3, 0x69, 0x57, 0x1f, 0x07, 0x1c, 0x8a, 0xbc, 0x20, 0xeb, 0xce, 0x8e, 0xab, 0xee, 0x31, 0xa2,
0x73, 0xf9, 0xca, 0x3a, 0x1a, 0xfb, 0x0d, 0xc1, 0xfe, 0xfa, 0xf2, 0x6f, 0xbd, 0x96, 0xdd, 0x43,
0x52, 0xb6, 0x08, 0xf3, 0xae, 0xbe, 0x19, 0x89, 0x32, 0x26, 0xb0, 0xea, 0x4b, 0x64, 0x84, 0x82,
0x6b, 0xf5, 0x79, 0xbf, 0x01, 0x5f, 0x75, 0x63, 0x1b, 0x23, 0x3d, 0x68, 0x2a, 0x65, 0xe8, 0x91,
0xf6, 0xff, 0x13, 0x58, 0xf1, 0x47, 0x0a, 0x7f, 0xc5, 0xa7, 0xe7, 0x61, 0x5a, 0x06, 0x46, 0x44,
0x42, 0x04, 0xa0, 0xdb, 0x39, 0x86, 0x54, 0xaa, 0x8c, 0x34, 0x21, 0x8b, 0xf8, 0x0c, 0x74, 0x67
};
private static readonly byte[] S3 = new byte[] {
0x68, 0x8d, 0xca, 0x4d, 0x73, 0x4b, 0x4e, 0x2a, 0xd4, 0x52, 0x26, 0xb3, 0x54, 0x1e, 0x19, 0x1f,
0x22, 0x03, 0x46, 0x3d, 0x2d, 0x4a, 0x53, 0x83, 0x13, 0x8a, 0xb7, 0xd5, 0x25, 0x79, 0xf5, 0xbd,
0x58, 0x2f, 0x0d, 0x02, 0xed, 0x51, 0x9e, 0x11, 0xf2, 0x3e, 0x55, 0x5e, 0xd1, 0x16, 0x3c, 0x66,
0x70, 0x5d, 0xf3, 0x45, 0x40, 0xcc, 0xe8, 0x94, 0x56, 0x08, 0xce, 0x1a, 0x3a, 0xd2, 0xe1, 0xdf,
0xb5, 0x38, 0x6e, 0x0e, 0xe5, 0xf4, 0xf9, 0x86, 0xe9, 0x4f, 0xd6, 0x85, 0x23, 0xcf, 0x32, 0x99,
0x31, 0x14, 0xae, 0xee, 0xc8, 0x48, 0xd3, 0x30, 0xa1, 0x92, 0x41, 0xb1, 0x18, 0xc4, 0x2c, 0x71,
0x72, 0x44, 0x15, 0xfd, 0x37, 0xbe, 0x5f, 0xaa, 0x9b, 0x88, 0xd8, 0xab, 0x89, 0x9c, 0xfa, 0x60,
0xea, 0xbc, 0x62, 0x0c, 0x24, 0xa6, 0xa8, 0xec, 0x67, 0x20, 0xdb, 0x7c, 0x28, 0xdd, 0xac, 0x5b,
0x34, 0x7e, 0x10, 0xf1, 0x7b, 0x8f, 0x63, 0xa0, 0x05, 0x9a, 0x43, 0x77, 0x21, 0xbf, 0x27, 0x09,
0xc3, 0x9f, 0xb6, 0xd7, 0x29, 0xc2, 0xeb, 0xc0, 0xa4, 0x8b, 0x8c, 0x1d, 0xfb, 0xff, 0xc1, 0xb2,
0x97, 0x2e, 0xf8, 0x65, 0xf6, 0x75, 0x07, 0x04, 0x49, 0x33, 0xe4, 0xd9, 0xb9, 0xd0, 0x42, 0xc7,
0x6c, 0x90, 0x00, 0x8e, 0x6f, 0x50, 0x01, 0xc5, 0xda, 0x47, 0x3f, 0xcd, 0x69, 0xa2, 0xe2, 0x7a,
0xa7, 0xc6, 0x93, 0x0f, 0x0a, 0x06, 0xe6, 0x2b, 0x96, 0xa3, 0x1c, 0xaf, 0x6a, 0x12, 0x84, 0x39,
0xe7, 0xb0, 0x82, 0xf7, 0xfe, 0x9d, 0x87, 0x5c, 0x81, 0x35, 0xde, 0xb4, 0xa5, 0xfc, 0x80, 0xef,
0xcb, 0xbb, 0x6b, 0x76, 0xba, 0x5a, 0x7d, 0x78, 0x0b, 0x95, 0xe3, 0xad, 0x74, 0x98, 0x3b, 0x36,
0x64, 0x6d, 0xdc, 0xf0, 0x59, 0xa9, 0x4c, 0x17, 0x7f, 0x91, 0xb8, 0xc9, 0x57, 0x1b, 0xe0, 0x61
};
public virtual IMemoable Copy()
{
return new Dstu7564Digest(this);
}
public virtual void Reset(IMemoable other)
{
Dstu7564Digest d = (Dstu7564Digest)other;
CopyIn(d);
}
}
}

View File

@ -0,0 +1,359 @@
using System;
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using BrowserPass.BouncyCastle.crypto;
using BrowserPass.BouncyCastle.crypto.parameters;
using BrowserPass.BouncyCastle.crypto.engines;
namespace Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of GOST R 34.11-94
*/
public class Gost3411Digest
: IDigest, IMemoable
{
private const int DIGEST_LENGTH = 32;
private byte[] H = new byte[32], L = new byte[32],
M = new byte[32], Sum = new byte[32];
private byte[][] C = MakeC();
private byte[] xBuf = new byte[32];
private int xBufOff;
private ulong byteCount;
private readonly IBlockCipher cipher = new Gost28147Engine();
private byte[] sBox;
private static byte[][] MakeC()
{
byte[][] c = new byte[4][];
for (int i = 0; i < 4; ++i)
{
c[i] = new byte[32];
}
return c;
}
/**
* Standard constructor
*/
public Gost3411Digest()
{
sBox = Gost28147Engine.GetSBox("D-A");
cipher.Init(true, new ParametersWithSBox(null, sBox));
Reset();
}
/**
* Constructor to allow use of a particular sbox with GOST28147
* @see GOST28147Engine#getSBox(String)
*/
public Gost3411Digest(byte[] sBoxParam)
{
sBox = Arrays.Clone(sBoxParam);
cipher.Init(true, new ParametersWithSBox(null, sBox));
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Gost3411Digest(Gost3411Digest t)
{
Reset(t);
}
public string AlgorithmName
{
get { return "Gost3411"; }
}
public int GetDigestSize()
{
return DIGEST_LENGTH;
}
public void Update(
byte input)
{
xBuf[xBufOff++] = input;
if (xBufOff == xBuf.Length)
{
sumByteArray(xBuf); // calc sum M
processBlock(xBuf, 0);
xBufOff = 0;
}
byteCount++;
}
public void BlockUpdate(
byte[] input,
int inOff,
int length)
{
while ((xBufOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
while (length > xBuf.Length)
{
Array.Copy(input, inOff, xBuf, 0, xBuf.Length);
sumByteArray(xBuf); // calc sum M
processBlock(xBuf, 0);
inOff += xBuf.Length;
length -= xBuf.Length;
byteCount += (uint)xBuf.Length;
}
// load in the remainder.
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
// (i + 1 + 4(k - 1)) = 8i + k i = 0-3, k = 1-8
private byte[] K = new byte[32];
private byte[] P(byte[] input)
{
int fourK = 0;
for(int k = 0; k < 8; k++)
{
K[fourK++] = input[k];
K[fourK++] = input[8 + k];
K[fourK++] = input[16 + k];
K[fourK++] = input[24 + k];
}
return K;
}
//A (x) = (x0 ^ x1) || x3 || x2 || x1
byte[] a = new byte[8];
private byte[] A(byte[] input)
{
for(int j=0; j<8; j++)
{
a[j]=(byte)(input[j] ^ input[j+8]);
}
Array.Copy(input, 8, input, 0, 24);
Array.Copy(a, 0, input, 24, 8);
return input;
}
//Encrypt function, ECB mode
private void E(byte[] key, byte[] s, int sOff, byte[] input, int inOff)
{
cipher.Init(true, new KeyParameter(key));
cipher.ProcessBlock(input, inOff, s, sOff);
}
// (in:) n16||..||n1 ==> (out:) n1^n2^n3^n4^n13^n16||n16||..||n2
internal short[] wS = new short[16], w_S = new short[16];
private void fw(byte[] input)
{
cpyBytesToShort(input, wS);
w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]);
Array.Copy(wS, 1, w_S, 0, 15);
cpyShortToBytes(w_S, input);
}
// block processing
internal byte[] S = new byte[32], U = new byte[32], V = new byte[32], W = new byte[32];
private void processBlock(byte[] input, int inOff)
{
Array.Copy(input, inOff, M, 0, 32);
//key step 1
// H = h3 || h2 || h1 || h0
// S = s3 || s2 || s1 || s0
H.CopyTo(U, 0);
M.CopyTo(V, 0);
for (int j=0; j<32; j++)
{
W[j] = (byte)(U[j]^V[j]);
}
// Encrypt gost28147-ECB
E(P(W), S, 0, H, 0); // s0 = EK0 [h0]
//keys step 2,3,4
for (int i=1; i<4; i++)
{
byte[] tmpA = A(U);
for (int j=0; j<32; j++)
{
U[j] = (byte)(tmpA[j] ^ C[i][j]);
}
V = A(A(V));
for (int j=0; j<32; j++)
{
W[j] = (byte)(U[j]^V[j]);
}
// Encrypt gost28147-ECB
E(P(W), S, i * 8, H, i * 8); // si = EKi [hi]
}
// x(M, H) = y61(H^y(M^y12(S)))
for(int n = 0; n < 12; n++)
{
fw(S);
}
for(int n = 0; n < 32; n++)
{
S[n] = (byte)(S[n] ^ M[n]);
}
fw(S);
for(int n = 0; n < 32; n++)
{
S[n] = (byte)(H[n] ^ S[n]);
}
for(int n = 0; n < 61; n++)
{
fw(S);
}
Array.Copy(S, 0, H, 0, H.Length);
}
private void finish()
{
ulong bitCount = byteCount * 8;
Pack.UInt64_To_LE(bitCount, L);
while (xBufOff != 0)
{
Update((byte)0);
}
processBlock(L, 0);
processBlock(Sum, 0);
}
public int DoFinal(
byte[] output,
int outOff)
{
finish();
H.CopyTo(output, outOff);
Reset();
return DIGEST_LENGTH;
}
/**
* reset the chaining variables to the IV values.
*/
private static readonly byte[] C2 = {
0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,
(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,
0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF,0x00,0x00,(byte)0xFF,
(byte)0xFF,0x00,0x00,0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF
};
public void Reset()
{
byteCount = 0;
xBufOff = 0;
Array.Clear(H, 0, H.Length);
Array.Clear(L, 0, L.Length);
Array.Clear(M, 0, M.Length);
Array.Clear(C[1], 0, C[1].Length); // real index C = +1 because index array with 0.
Array.Clear(C[3], 0, C[3].Length);
Array.Clear(Sum, 0, Sum.Length);
Array.Clear(xBuf, 0, xBuf.Length);
C2.CopyTo(C[2], 0);
}
// 256 bitsblock modul -> (Sum + a mod (2^256))
private void sumByteArray(
byte[] input)
{
int carry = 0;
for (int i = 0; i != Sum.Length; i++)
{
int sum = (Sum[i] & 0xff) + (input[i] & 0xff) + carry;
Sum[i] = (byte)sum;
carry = sum >> 8;
}
}
private static void cpyBytesToShort(byte[] S, short[] wS)
{
for(int i = 0; i < S.Length / 2; i++)
{
wS[i] = (short)(((S[i*2+1]<<8)&0xFF00)|(S[i*2]&0xFF));
}
}
private static void cpyShortToBytes(short[] wS, byte[] S)
{
for(int i=0; i<S.Length/2; i++)
{
S[i*2 + 1] = (byte)(wS[i] >> 8);
S[i*2] = (byte)wS[i];
}
}
public int GetByteLength()
{
return 32;
}
public IMemoable Copy()
{
return new Gost3411Digest(this);
}
public void Reset(IMemoable other)
{
Gost3411Digest t = (Gost3411Digest)other;
this.sBox = t.sBox;
cipher.Init(true, new ParametersWithSBox(null, sBox));
Reset();
Array.Copy(t.H, 0, this.H, 0, t.H.Length);
Array.Copy(t.L, 0, this.L, 0, t.L.Length);
Array.Copy(t.M, 0, this.M, 0, t.M.Length);
Array.Copy(t.Sum, 0, this.Sum, 0, t.Sum.Length);
Array.Copy(t.C[1], 0, this.C[1], 0, t.C[1].Length);
Array.Copy(t.C[2], 0, this.C[2], 0, t.C[2].Length);
Array.Copy(t.C[3], 0, this.C[3], 0, t.C[3].Length);
Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.Length);
this.xBufOff = t.xBufOff;
this.byteCount = t.byteCount;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
using BrowserPass.BouncyCastle.Crypto.Digests;
using BrowserPass.BouncyCastle.util;
using System;
namespace Org.BouncyCastle.Crypto.Digests
{
public class Gost3411_2012_256Digest : Gost3411_2012Digest
{
private readonly static byte[] IV = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
public override string AlgorithmName
{
get { return "GOST3411-2012-256"; }
}
public Gost3411_2012_256Digest() : base(IV)
{
}
public Gost3411_2012_256Digest(Gost3411_2012_256Digest other) : base(IV)
{
Reset(other);
}
public override int GetDigestSize()
{
return 32;
}
public override int DoFinal(byte[] output, int outOff)
{
byte[] result = new byte[64];
base.DoFinal(result, 0);
Array.Copy(result, 32, output, outOff, 32);
return 32;
}
public override IMemoable Copy()
{
return new Gost3411_2012_256Digest(this);
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.IO;
using System;
using System.IO;
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Diagnostics;
using BrowserPass.BouncyCastle.util.io;
namespace BrowserPass.BouncyCastle.Crypto.Digests
{
public class Gost3411_2012_512Digest:Gost3411_2012Digest
{
private readonly static byte[] IV = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
public override string AlgorithmName
{
get { return "GOST3411-2012-512"; }
}
public Gost3411_2012_512Digest():base(IV)
{
}
public Gost3411_2012_512Digest(Gost3411_2012_512Digest other) : base(IV)
{
Reset(other);
}
public override int GetDigestSize()
{
return 64;
}
public override IMemoable Copy()
{
return new Gost3411_2012_512Digest(this);
}
}
}

View File

@ -0,0 +1,138 @@
using System;
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Diagnostics;
namespace Org.BouncyCastle.Crypto.Digests
{
/**
* base implementation of MD4 family style digest as outlined in
* "Handbook of Applied Cryptography", pages 344 - 347.
*/
public abstract class GeneralDigest
: IDigest, IMemoable
{
private const int BYTE_LENGTH = 64;
private byte[] xBuf;
private int xBufOff;
private long byteCount;
internal GeneralDigest()
{
xBuf = new byte[4];
}
internal GeneralDigest(GeneralDigest t)
{
xBuf = new byte[t.xBuf.Length];
CopyIn(t);
}
protected void CopyIn(GeneralDigest t)
{
Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
xBufOff = t.xBufOff;
byteCount = t.byteCount;
}
public void Update(byte input)
{
xBuf[xBufOff++] = input;
if (xBufOff == xBuf.Length)
{
ProcessWord(xBuf, 0);
xBufOff = 0;
}
byteCount++;
}
public void BlockUpdate(
byte[] input,
int inOff,
int length)
{
length = System.Math.Max(0, length);
//
// fill the current word
//
int i = 0;
if (xBufOff != 0)
{
while (i < length)
{
xBuf[xBufOff++] = input[inOff + i++];
if (xBufOff == 4)
{
ProcessWord(xBuf, 0);
xBufOff = 0;
break;
}
}
}
//
// process whole words.
//
int limit = ((length - i) & ~3) + i;
for (; i < limit; i += 4)
{
ProcessWord(input, inOff + i);
}
//
// load in the remainder.
//
while (i < length)
{
xBuf[xBufOff++] = input[inOff + i++];
}
byteCount += length;
}
public void Finish()
{
long bitLength = (byteCount << 3);
//
// add the pad bytes.
//
Update((byte)128);
while (xBufOff != 0) Update((byte)0);
ProcessLength(bitLength);
ProcessBlock();
}
public virtual void Reset()
{
byteCount = 0;
xBufOff = 0;
Array.Clear(xBuf, 0, xBuf.Length);
}
public int GetByteLength()
{
return BYTE_LENGTH;
}
internal abstract void ProcessWord(byte[] input, int inOff);
internal abstract void ProcessLength(long bitLength);
internal abstract void ProcessBlock();
public abstract string AlgorithmName { get; }
public abstract int GetDigestSize();
public abstract int DoFinal(byte[] output, int outOff);
public abstract IMemoable Copy();
public abstract void Reset(IMemoable t);
}
}

View File

@ -0,0 +1,415 @@
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Diagnostics;
namespace Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Implementation of Keccak based on following KeccakNISTInterface.c from http://keccak.noekeon.org/
/// </summary>
/// <remarks>
/// Following the naming conventions used in the C source code to enable easy review of the implementation.
/// </remarks>
public class KeccakDigest
: IDigest, IMemoable
{
private static readonly ulong[] KeccakRoundConstants = new ulong[]{
0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808aUL, 0x8000000080008000UL,
0x000000000000808bUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL,
0x000000000000008aUL, 0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000aUL,
0x000000008000808bUL, 0x800000000000008bUL, 0x8000000000008089UL, 0x8000000000008003UL,
0x8000000000008002UL, 0x8000000000000080UL, 0x000000000000800aUL, 0x800000008000000aUL,
0x8000000080008081UL, 0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL
};
private ulong[] state = new ulong[25];
protected byte[] dataQueue = new byte[192];
protected int rate;
protected int bitsInQueue;
protected int fixedOutputLength;
protected bool squeezing;
public KeccakDigest()
: this(288)
{
}
public KeccakDigest(int bitLength)
{
Init(bitLength);
}
public KeccakDigest(KeccakDigest source)
{
CopyIn(source);
}
private void CopyIn(KeccakDigest source)
{
Array.Copy(source.state, 0, this.state, 0, source.state.Length);
Array.Copy(source.dataQueue, 0, this.dataQueue, 0, source.dataQueue.Length);
this.rate = source.rate;
this.bitsInQueue = source.bitsInQueue;
this.fixedOutputLength = source.fixedOutputLength;
this.squeezing = source.squeezing;
}
public virtual string AlgorithmName
{
get { return "Keccak-" + fixedOutputLength; }
}
public virtual int GetDigestSize()
{
return fixedOutputLength >> 3;
}
public virtual void Update(byte input)
{
Absorb(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int len)
{
Absorb(input, inOff, len);
}
public virtual int DoFinal(byte[] output, int outOff)
{
Squeeze(output, outOff, fixedOutputLength);
Reset();
return GetDigestSize();
}
/*
* TODO Possible API change to support partial-byte suffixes.
*/
protected virtual int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits)
{
if (partialBits > 0)
{
AbsorbBits(partialByte, partialBits);
}
Squeeze(output, outOff, fixedOutputLength);
Reset();
return GetDigestSize();
}
public virtual void Reset()
{
Init(fixedOutputLength);
}
/**
* Return the size of block that the compression function is applied to in bytes.
*
* @return internal byte length of a block.
*/
public virtual int GetByteLength()
{
return rate >> 3;
}
private void Init(int bitLength)
{
switch (bitLength)
{
case 128:
case 224:
case 256:
case 288:
case 384:
case 512:
InitSponge(1600 - (bitLength << 1));
break;
default:
throw new ArgumentException("must be one of 128, 224, 256, 288, 384, or 512.", "bitLength");
}
}
private void InitSponge(int rate)
{
if (rate <= 0 || rate >= 1600 || (rate & 63) != 0)
throw new InvalidOperationException("invalid rate value");
this.rate = rate;
Array.Clear(state, 0, state.Length);
Arrays.Fill(this.dataQueue, (byte)0);
this.bitsInQueue = 0;
this.squeezing = false;
this.fixedOutputLength = (1600 - rate) >> 1;
}
protected void Absorb(byte data)
{
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
dataQueue[bitsInQueue >> 3] = data;
if ((bitsInQueue += 8) == rate)
{
KeccakAbsorb(dataQueue, 0);
bitsInQueue = 0;
}
}
protected void Absorb(byte[] data, int off, int len)
{
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
int bytesInQueue = bitsInQueue >> 3;
int rateBytes = rate >> 3;
int available = rateBytes - bytesInQueue;
if (len < available)
{
Array.Copy(data, off, dataQueue, bytesInQueue, len);
this.bitsInQueue += len << 3;
return;
}
int count = 0;
if (bytesInQueue > 0)
{
Array.Copy(data, off, dataQueue, bytesInQueue, available);
count += available;
KeccakAbsorb(dataQueue, 0);
}
int remaining;
while ((remaining = (len - count)) >= rateBytes)
{
KeccakAbsorb(data, off + count);
count += rateBytes;
}
Array.Copy(data, off + count, dataQueue, 0, remaining);
this.bitsInQueue = remaining << 3;
}
protected void AbsorbBits(int data, int bits)
{
if (bits < 1 || bits > 7)
throw new ArgumentException("must be in the range 1 to 7", "bits");
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
int mask = (1 << bits) - 1;
dataQueue[bitsInQueue >> 3] = (byte)(data & mask);
// NOTE: After this, bitsInQueue is no longer a multiple of 8, so no more absorbs will work
bitsInQueue += bits;
}
private void PadAndSwitchToSqueezingPhase()
{
Debug.Assert(bitsInQueue < rate);
dataQueue[bitsInQueue >> 3] |= (byte)(1 << (bitsInQueue & 7));
if (++bitsInQueue == rate)
{
KeccakAbsorb(dataQueue, 0);
}
else
{
int full = bitsInQueue >> 6, partial = bitsInQueue & 63;
int off = 0;
for (int i = 0; i < full; ++i)
{
state[i] ^= Pack.LE_To_UInt64(dataQueue, off);
off += 8;
}
if (partial > 0)
{
ulong mask = (1UL << partial) - 1UL;
state[full] ^= Pack.LE_To_UInt64(dataQueue, off) & mask;
}
}
state[(rate - 1) >> 6] ^= (1UL << 63);
bitsInQueue = 0;
squeezing = true;
}
protected void Squeeze(byte[] output, int offset, long outputLength)
{
if (!squeezing)
{
PadAndSwitchToSqueezingPhase();
}
if ((outputLength & 7L) != 0L)
throw new InvalidOperationException("outputLength not a multiple of 8");
long i = 0;
while (i < outputLength)
{
if (bitsInQueue == 0)
{
KeccakExtract();
}
int partialBlock = (int)System.Math.Min((long)bitsInQueue, outputLength - i);
Array.Copy(dataQueue, (rate - bitsInQueue) >> 3, output, offset + (int)(i >> 3), partialBlock >> 3);
bitsInQueue -= partialBlock;
i += partialBlock;
}
}
private void KeccakAbsorb(byte[] data, int off)
{
int count = rate >> 6;
for (int i = 0; i < count; ++i)
{
state[i] ^= Pack.LE_To_UInt64(data, off);
off += 8;
}
KeccakPermutation();
}
private void KeccakExtract()
{
KeccakPermutation();
Pack.UInt64_To_LE(state, 0, rate >> 6, dataQueue, 0);
this.bitsInQueue = rate;
}
private void KeccakPermutation()
{
ulong[] A = state;
ulong a00 = A[ 0], a01 = A[ 1], a02 = A[ 2], a03 = A[ 3], a04 = A[ 4];
ulong a05 = A[ 5], a06 = A[ 6], a07 = A[ 7], a08 = A[ 8], a09 = A[ 9];
ulong a10 = A[10], a11 = A[11], a12 = A[12], a13 = A[13], a14 = A[14];
ulong a15 = A[15], a16 = A[16], a17 = A[17], a18 = A[18], a19 = A[19];
ulong a20 = A[20], a21 = A[21], a22 = A[22], a23 = A[23], a24 = A[24];
for (int i = 0; i < 24; i++)
{
// theta
ulong c0 = a00 ^ a05 ^ a10 ^ a15 ^ a20;
ulong c1 = a01 ^ a06 ^ a11 ^ a16 ^ a21;
ulong c2 = a02 ^ a07 ^ a12 ^ a17 ^ a22;
ulong c3 = a03 ^ a08 ^ a13 ^ a18 ^ a23;
ulong c4 = a04 ^ a09 ^ a14 ^ a19 ^ a24;
ulong d1 = (c1 << 1 | c1 >> -1) ^ c4;
ulong d2 = (c2 << 1 | c2 >> -1) ^ c0;
ulong d3 = (c3 << 1 | c3 >> -1) ^ c1;
ulong d4 = (c4 << 1 | c4 >> -1) ^ c2;
ulong d0 = (c0 << 1 | c0 >> -1) ^ c3;
a00 ^= d1; a05 ^= d1; a10 ^= d1; a15 ^= d1; a20 ^= d1;
a01 ^= d2; a06 ^= d2; a11 ^= d2; a16 ^= d2; a21 ^= d2;
a02 ^= d3; a07 ^= d3; a12 ^= d3; a17 ^= d3; a22 ^= d3;
a03 ^= d4; a08 ^= d4; a13 ^= d4; a18 ^= d4; a23 ^= d4;
a04 ^= d0; a09 ^= d0; a14 ^= d0; a19 ^= d0; a24 ^= d0;
// rho/pi
c1 = a01 << 1 | a01 >> 63;
a01 = a06 << 44 | a06 >> 20;
a06 = a09 << 20 | a09 >> 44;
a09 = a22 << 61 | a22 >> 3;
a22 = a14 << 39 | a14 >> 25;
a14 = a20 << 18 | a20 >> 46;
a20 = a02 << 62 | a02 >> 2;
a02 = a12 << 43 | a12 >> 21;
a12 = a13 << 25 | a13 >> 39;
a13 = a19 << 8 | a19 >> 56;
a19 = a23 << 56 | a23 >> 8;
a23 = a15 << 41 | a15 >> 23;
a15 = a04 << 27 | a04 >> 37;
a04 = a24 << 14 | a24 >> 50;
a24 = a21 << 2 | a21 >> 62;
a21 = a08 << 55 | a08 >> 9;
a08 = a16 << 45 | a16 >> 19;
a16 = a05 << 36 | a05 >> 28;
a05 = a03 << 28 | a03 >> 36;
a03 = a18 << 21 | a18 >> 43;
a18 = a17 << 15 | a17 >> 49;
a17 = a11 << 10 | a11 >> 54;
a11 = a07 << 6 | a07 >> 58;
a07 = a10 << 3 | a10 >> 61;
a10 = c1;
// chi
c0 = a00 ^ (~a01 & a02);
c1 = a01 ^ (~a02 & a03);
a02 ^= ~a03 & a04;
a03 ^= ~a04 & a00;
a04 ^= ~a00 & a01;
a00 = c0;
a01 = c1;
c0 = a05 ^ (~a06 & a07);
c1 = a06 ^ (~a07 & a08);
a07 ^= ~a08 & a09;
a08 ^= ~a09 & a05;
a09 ^= ~a05 & a06;
a05 = c0;
a06 = c1;
c0 = a10 ^ (~a11 & a12);
c1 = a11 ^ (~a12 & a13);
a12 ^= ~a13 & a14;
a13 ^= ~a14 & a10;
a14 ^= ~a10 & a11;
a10 = c0;
a11 = c1;
c0 = a15 ^ (~a16 & a17);
c1 = a16 ^ (~a17 & a18);
a17 ^= ~a18 & a19;
a18 ^= ~a19 & a15;
a19 ^= ~a15 & a16;
a15 = c0;
a16 = c1;
c0 = a20 ^ (~a21 & a22);
c1 = a21 ^ (~a22 & a23);
a22 ^= ~a23 & a24;
a23 ^= ~a24 & a20;
a24 ^= ~a20 & a21;
a20 = c0;
a21 = c1;
// iota
a00 ^= KeccakRoundConstants[i];
}
A[ 0] = a00; A[ 1] = a01; A[ 2] = a02; A[ 3] = a03; A[ 4] = a04;
A[ 5] = a05; A[ 6] = a06; A[ 7] = a07; A[ 8] = a08; A[ 9] = a09;
A[10] = a10; A[11] = a11; A[12] = a12; A[13] = a13; A[14] = a14;
A[15] = a15; A[16] = a16; A[17] = a17; A[18] = a18; A[19] = a19;
A[20] = a20; A[21] = a21; A[22] = a22; A[23] = a23; A[24] = a24;
}
public virtual IMemoable Copy()
{
return new KeccakDigest(this);
}
public virtual void Reset(IMemoable other)
{
CopyIn((KeccakDigest)other);
}
}
}

View File

@ -0,0 +1,361 @@
using System;
using System;
using System.IO;
using BrowserPass.BouncyCastle;
using BrowserPass.BouncyCastle.crypto.util;
using BrowserPass.BouncyCastle.util;
using System;
using System.Diagnostics;
using BrowserPass.BouncyCastle.util.io;
namespace BrowserPass.BouncyCastle.Crypto.Digests
{
/**
* Base class for SHA-384 and SHA-512.
*/
public abstract class LongDigest
: IDigest, IMemoable
{
private int MyByteLength = 128;
private byte[] xBuf;
private int xBufOff;
private long byteCount1;
private long byteCount2;
internal ulong H1, H2, H3, H4, H5, H6, H7, H8;
private ulong[] W = new ulong[80];
private int wOff;
/**
* Constructor for variable length word
*/
internal LongDigest()
{
xBuf = new byte[8];
Reset();
}
/**
* Copy constructor. We are using copy constructors in place
* of the object.Clone() interface as this interface is not
* supported by J2ME.
*/
internal LongDigest(
LongDigest t)
{
xBuf = new byte[t.xBuf.Length];
CopyIn(t);
}
protected void CopyIn(LongDigest t)
{
Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
xBufOff = t.xBufOff;
byteCount1 = t.byteCount1;
byteCount2 = t.byteCount2;
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
H6 = t.H6;
H7 = t.H7;
H8 = t.H8;
Array.Copy(t.W, 0, W, 0, t.W.Length);
wOff = t.wOff;
}
public void Update(
byte input)
{
xBuf[xBufOff++] = input;
if (xBufOff == xBuf.Length)
{
ProcessWord(xBuf, 0);
xBufOff = 0;
}
byteCount1++;
}
public void BlockUpdate(
byte[] input,
int inOff,
int length)
{
//
// fill the current word
//
while ((xBufOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
//
// process whole words.
//
while (length > xBuf.Length)
{
ProcessWord(input, inOff);
inOff += xBuf.Length;
length -= xBuf.Length;
byteCount1 += xBuf.Length;
}
//
// load in the remainder.
//
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
public void Finish()
{
AdjustByteCounts();
long lowBitLength = byteCount1 << 3;
long hiBitLength = byteCount2;
//
// add the pad bytes.
//
Update((byte)128);
while (xBufOff != 0)
{
Update((byte)0);
}
ProcessLength(lowBitLength, hiBitLength);
ProcessBlock();
}
public virtual void Reset()
{
byteCount1 = 0;
byteCount2 = 0;
xBufOff = 0;
for ( int i = 0; i < xBuf.Length; i++ )
{
xBuf[i] = 0;
}
wOff = 0;
Array.Clear(W, 0, W.Length);
}
internal void ProcessWord(
byte[] input,
int inOff)
{
W[wOff] = Pack.BE_To_UInt64(input, inOff);
if (++wOff == 16)
{
ProcessBlock();
}
}
/**
* adjust the byte counts so that byteCount2 represents the
* upper long (less 3 bits) word of the byte count.
*/
private void AdjustByteCounts()
{
if (byteCount1 > 0x1fffffffffffffffL)
{
byteCount2 += (long) ((ulong) byteCount1 >> 61);
byteCount1 &= 0x1fffffffffffffffL;
}
}
internal void ProcessLength(
long lowW,
long hiW)
{
if (wOff > 14)
{
ProcessBlock();
}
W[14] = (ulong)hiW;
W[15] = (ulong)lowW;
}
internal void ProcessBlock()
{
AdjustByteCounts();
//
// expand 16 word block into 80 word blocks.
//
for (int ti = 16; ti <= 79; ++ti)
{
W[ti] = Sigma1(W[ti - 2]) + W[ti - 7] + Sigma0(W[ti - 15]) + W[ti - 16];
}
//
// set up working variables.
//
ulong a = H1;
ulong b = H2;
ulong c = H3;
ulong d = H4;
ulong e = H5;
ulong f = H6;
ulong g = H7;
ulong h = H8;
int t = 0;
for(int i = 0; i < 10; i ++)
{
// t = 8 * i
h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++];
d += h;
h += Sum0(a) + Maj(a, b, c);
// t = 8 * i + 1
g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++];
c += g;
g += Sum0(h) + Maj(h, a, b);
// t = 8 * i + 2
f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++];
b += f;
f += Sum0(g) + Maj(g, h, a);
// t = 8 * i + 3
e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++];
a += e;
e += Sum0(f) + Maj(f, g, h);
// t = 8 * i + 4
d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++];
h += d;
d += Sum0(e) + Maj(e, f, g);
// t = 8 * i + 5
c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++];
g += c;
c += Sum0(d) + Maj(d, e, f);
// t = 8 * i + 6
b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++];
f += b;
b += Sum0(c) + Maj(c, d, e);
// t = 8 * i + 7
a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++];
e += a;
a += Sum0(b) + Maj(b, c, d);
}
H1 += a;
H2 += b;
H3 += c;
H4 += d;
H5 += e;
H6 += f;
H7 += g;
H8 += h;
//
// reset the offset and clean out the word buffer.
//
wOff = 0;
Array.Clear(W, 0, 16);
}
/* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */
private static ulong Ch(ulong x, ulong y, ulong z)
{
return (x & y) ^ (~x & z);
}
private static ulong Maj(ulong x, ulong y, ulong z)
{
return (x & y) ^ (x & z) ^ (y & z);
}
private static ulong Sum0(ulong x)
{
return ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39));
}
private static ulong Sum1(ulong x)
{
return ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41));
}
private static ulong Sigma0(ulong x)
{
return ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7);
}
private static ulong Sigma1(ulong x)
{
return ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6);
}
/* SHA-384 and SHA-512 Constants
* (represent the first 64 bits of the fractional parts of the
* cube roots of the first sixty-four prime numbers)
*/
internal static readonly ulong[] K =
{
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
};
public int GetByteLength()
{
return MyByteLength;
}
public abstract string AlgorithmName { get; }
public abstract int GetDigestSize();
public abstract int DoFinal(byte[] output, int outOff);
public abstract IMemoable Copy();
public abstract void Reset(IMemoable t);
}
}

Some files were not shown because too many files have changed in this diff Show More