BouncyCastle update.

git-svn-id: svn://svn.code.sf.net/p/itextsharp/code/trunk@18 820d3149-562b-4f88-9aa4-a8e61a3485cf
master
psoares33 2008-12-17 11:23:50 +00:00
parent c12d0aa854
commit f00f5ff42a
73 changed files with 16345 additions and 15168 deletions

View File

@ -1,7 +1,7 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
ProductVersion = "7.10.6030"
SchemaVersion = "2.0"
ProjectGuid = "{84C4FDD9-3ED7-453B-B9DA-B3ED52CB071C}"
>
@ -2517,6 +2517,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\asn1\IAsn1Choice.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\asn1\IAsn1Convertible.cs"
SubType = "Code"
@ -2897,6 +2902,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\asn1\esf\SignerAttribute.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\asn1\esf\SignerLocation.cs"
SubType = "Code"
@ -4122,6 +4132,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\bcpg\sig\EmbeddedSignature.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\bcpg\sig\Exportable.cs"
SubType = "Code"
@ -4727,6 +4742,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\crypto\engines\CamelliaLightEngine.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\crypto\engines\CamelliaWrapEngine.cs"
SubType = "Code"

View File

@ -1,177 +1,178 @@
using System;
using Org.BouncyCastle.Utilities;
namespace Org.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 int tagNo;
// internal bool empty;
internal bool explicitly = true;
internal Asn1Encodable obj;
static public Asn1TaggedObject GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
if (explicitly)
{
return (Asn1TaggedObject) 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: " + obj.GetType().FullName, "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)
{
this.explicitly = explicitly;
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;
}
}
}
using System;
using Org.BouncyCastle.Utilities;
namespace Org.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 int tagNo;
// internal bool empty;
internal bool explicitly = true;
internal Asn1Encodable obj;
static public Asn1TaggedObject GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
if (explicitly)
{
return (Asn1TaggedObject) 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: " + obj.GetType().FullName, "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

@ -1,86 +1,84 @@
using System;
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
class DefiniteLengthInputStream
: LimitedInputStream
{
private static readonly byte[] EmptyBytes = new byte[0];
private int _length;
internal DefiniteLengthInputStream(
Stream inStream,
int length)
: base(inStream)
{
if (length < 0)
throw new ArgumentException("negative lengths not allowed", "length");
this._length = length;
}
public override int ReadByte()
{
if (_length > 0)
{
int b = _in.ReadByte();
if (b < 0)
throw new EndOfStreamException();
--_length;
return b;
}
SetParentEofDetect(true);
return -1;
}
public override int Read(
byte[] buf,
int off,
int len)
{
if (_length > 0)
{
int toRead = System.Math.Min(len, _length);
int numRead = _in.Read(buf, off, toRead);
if (numRead < 1)
throw new EndOfStreamException();
_length -= numRead;
return numRead;
}
SetParentEofDetect(true);
return 0;
}
internal byte[] ToArray()
{
byte[] bytes;
if (_length > 0)
{
bytes = new byte[_length];
if (Streams.ReadFully(_in, bytes) < _length)
throw new EndOfStreamException();
_length = 0;
}
else
{
bytes = EmptyBytes;
}
SetParentEofDetect(true);
return bytes;
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
class DefiniteLengthInputStream
: LimitedInputStream
{
private static readonly byte[] EmptyBytes = new byte[0];
private int _length;
internal DefiniteLengthInputStream(
Stream inStream,
int length)
: base(inStream)
{
if (length < 0)
throw new ArgumentException("negative lengths not allowed", "length");
this._length = length;
if (length == 0)
{
SetParentEofDetect(true);
}
}
public override int ReadByte()
{
if (_length == 0)
return -1;
int b = _in.ReadByte();
if (b < 0)
throw new EndOfStreamException();
if (--_length == 0)
{
SetParentEofDetect(true);
}
return b;
}
public override int Read(
byte[] buf,
int off,
int len)
{
if (_length == 0)
return 0;
int toRead = System.Math.Min(len, _length);
int numRead = _in.Read(buf, off, toRead);
if (numRead < 1)
throw new EndOfStreamException();
if ((_length -= numRead) == 0)
{
SetParentEofDetect(true);
}
return numRead;
}
internal byte[] ToArray()
{
if (_length == 0)
return EmptyBytes;
byte[] bytes = new byte[_length];
if (Streams.ReadFully(_in, bytes) < _length)
throw new EndOfStreamException();
_length = 0;
SetParentEofDetect(true);
return bytes;
}
}
}

View File

@ -0,0 +1,17 @@
namespace Org.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

@ -1,95 +1,104 @@
using System.IO;
namespace Org.BouncyCastle.Asn1
{
class IndefiniteLengthInputStream
: LimitedInputStream
{
private int _b1;
private int _b2;
private bool _eofReached = false;
private bool _eofOn00 = true;
internal IndefiniteLengthInputStream(
Stream inStream)
: base(inStream)
{
_b1 = inStream.ReadByte();
_b2 = inStream.ReadByte();
_eofReached = (_b2 < 0);
}
internal void SetEofOn00(
bool eofOn00)
{
_eofOn00 = eofOn00;
}
internal bool CheckForEof()
{
if (_eofOn00 && (_b1 == 0x00 && _b2 == 0x00))
{
_eofReached = true;
SetParentEofDetect(true);
}
return _eofReached;
}
public override int Read(
byte[] buffer,
int offset,
int count)
{
// Only use this optimisation if we aren't checking for 00
if (_eofOn00 || count < 3)
return base.Read(buffer, offset, count);
if (_eofReached)
return 0;
int numRead = _in.Read(buffer, offset + 2, count - 2);
if (numRead <= 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
buffer[offset] = (byte)_b1;
buffer[offset + 1] = (byte)_b2;
_b1 = _in.ReadByte();
_b2 = _in.ReadByte();
if (_b2 < 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
return numRead + 2;
}
public override int ReadByte()
{
if (CheckForEof())
return -1;
int b = _in.ReadByte();
if (b < 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
int v = _b1;
_b1 = _b2;
_b2 = b;
return v;
}
}
}
using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
class IndefiniteLengthInputStream
: LimitedInputStream
{
private int _b1;
private int _b2;
private bool _eofReached = false;
private bool _eofOn00 = true;
internal IndefiniteLengthInputStream(
Stream inStream)
: base(inStream)
{
_b1 = inStream.ReadByte();
_b2 = inStream.ReadByte();
if (_b2 < 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
CheckForEof();
}
internal void SetEofOn00(
bool eofOn00)
{
_eofOn00 = eofOn00;
CheckForEof();
}
private bool CheckForEof()
{
if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00))
{
_eofReached = true;
SetParentEofDetect(true);
}
return _eofReached;
}
public override int Read(
byte[] buffer,
int offset,
int count)
{
// Only use this optimisation if we aren't checking for 00
if (_eofOn00 || count < 3)
return base.Read(buffer, offset, count);
if (_eofReached)
return 0;
int numRead = _in.Read(buffer, offset + 2, count - 2);
if (numRead <= 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
buffer[offset] = (byte)_b1;
buffer[offset + 1] = (byte)_b2;
_b1 = _in.ReadByte();
_b2 = _in.ReadByte();
if (_b2 < 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
return numRead + 2;
}
public override int ReadByte()
{
if (CheckForEof())
return -1;
int b = _in.ReadByte();
if (b < 0)
{
// Corrupted stream
throw new EndOfStreamException();
}
int v = _b1;
_b1 = _b2;
_b2 = b;
return v;
}
}
}

View File

@ -1,89 +1,88 @@
using System;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Esf
{
/// <remarks>
/// <code>
/// OtherHash ::= CHOICE {
/// sha1Hash OtherHashValue, -- This contains a SHA-1 hash
/// otherHash OtherHashAlgAndValue
/// }
///
/// OtherHashValue ::= OCTET STRING
/// </code>
/// </remarks>
public class OtherHash
: Asn1Encodable
//, Asn1Choice
{
private readonly Asn1OctetString sha1Hash;
private readonly OtherHashAlgAndValue otherHash;
public static OtherHash GetInstance(
object obj)
{
if (obj == null || obj is OtherHash)
return (OtherHash) obj;
if (obj is Asn1OctetString)
return new OtherHash((Asn1OctetString) obj);
return new OtherHash(
OtherHashAlgAndValue.GetInstance(obj));
}
public OtherHash(
byte[] sha1Hash)
{
if (sha1Hash == null)
throw new ArgumentNullException("sha1Hash");
this.sha1Hash = new DerOctetString(sha1Hash);
}
public OtherHash(
Asn1OctetString sha1Hash)
{
if (sha1Hash == null)
throw new ArgumentNullException("sha1Hash");
this.sha1Hash = sha1Hash;
}
public OtherHash(
OtherHashAlgAndValue otherHash)
{
if (otherHash == null)
throw new ArgumentNullException("otherHash");
this.otherHash = otherHash;
}
public AlgorithmIdentifier HashAlgorithm
{
get
{
return otherHash == null
? new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1)
: otherHash.HashAlgorithm;
}
}
public byte[] GetHashValue()
{
return otherHash == null
? sha1Hash.GetOctets()
: otherHash.GetHashValue();
}
public override Asn1Object ToAsn1Object()
{
return otherHash == null
? sha1Hash
: otherHash.ToAsn1Object();
}
}
}
using System;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Esf
{
/// <remarks>
/// <code>
/// OtherHash ::= CHOICE {
/// sha1Hash OtherHashValue, -- This contains a SHA-1 hash
/// otherHash OtherHashAlgAndValue
/// }
///
/// OtherHashValue ::= OCTET STRING
/// </code>
/// </remarks>
public class OtherHash
: Asn1Encodable, IAsn1Choice
{
private readonly Asn1OctetString sha1Hash;
private readonly OtherHashAlgAndValue otherHash;
public static OtherHash GetInstance(
object obj)
{
if (obj == null || obj is OtherHash)
return (OtherHash) obj;
if (obj is Asn1OctetString)
return new OtherHash((Asn1OctetString) obj);
return new OtherHash(
OtherHashAlgAndValue.GetInstance(obj));
}
public OtherHash(
byte[] sha1Hash)
{
if (sha1Hash == null)
throw new ArgumentNullException("sha1Hash");
this.sha1Hash = new DerOctetString(sha1Hash);
}
public OtherHash(
Asn1OctetString sha1Hash)
{
if (sha1Hash == null)
throw new ArgumentNullException("sha1Hash");
this.sha1Hash = sha1Hash;
}
public OtherHash(
OtherHashAlgAndValue otherHash)
{
if (otherHash == null)
throw new ArgumentNullException("otherHash");
this.otherHash = otherHash;
}
public AlgorithmIdentifier HashAlgorithm
{
get
{
return otherHash == null
? new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1)
: otherHash.HashAlgorithm;
}
}
public byte[] GetHashValue()
{
return otherHash == null
? sha1Hash.GetOctets()
: otherHash.GetHashValue();
}
public override Asn1Object ToAsn1Object()
{
return otherHash == null
? sha1Hash
: otherHash.ToAsn1Object();
}
}
}

View File

@ -1,65 +1,64 @@
using System;
namespace Org.BouncyCastle.Asn1.Esf
{
/// <remarks>
/// <code>
/// SignaturePolicyIdentifier ::= CHOICE {
/// SignaturePolicyId SignaturePolicyId,
/// SignaturePolicyImplied SignaturePolicyImplied
/// }
///
/// SignaturePolicyImplied ::= NULL
/// </code>
/// </remarks>
public class SignaturePolicyIdentifier
: Asn1Encodable
//, Asn1Choice
{
private readonly SignaturePolicyId sigPolicy;
public static SignaturePolicyIdentifier GetInstance(
object obj)
{
if (obj == null || obj is SignaturePolicyIdentifier)
return (SignaturePolicyIdentifier) obj;
if (obj is SignaturePolicyId)
return new SignaturePolicyIdentifier((SignaturePolicyId) obj);
if (obj is Asn1Null)
return new SignaturePolicyIdentifier();
throw new ArgumentException(
"Unknown object in 'SignaturePolicyIdentifier' factory: "
+ obj.GetType().Name,
"obj");
}
public SignaturePolicyIdentifier()
{
this.sigPolicy = null;
}
public SignaturePolicyIdentifier(
SignaturePolicyId signaturePolicyId)
{
if (signaturePolicyId == null)
throw new ArgumentNullException("signaturePolicyId");
this.sigPolicy = signaturePolicyId;
}
public SignaturePolicyId SignaturePolicyId
{
get { return sigPolicy; }
}
public override Asn1Object ToAsn1Object()
{
return sigPolicy == null
? DerNull.Instance
: sigPolicy.ToAsn1Object();
}
}
}
using System;
namespace Org.BouncyCastle.Asn1.Esf
{
/// <remarks>
/// <code>
/// SignaturePolicyIdentifier ::= CHOICE {
/// SignaturePolicyId SignaturePolicyId,
/// SignaturePolicyImplied SignaturePolicyImplied
/// }
///
/// SignaturePolicyImplied ::= NULL
/// </code>
/// </remarks>
public class SignaturePolicyIdentifier
: Asn1Encodable, IAsn1Choice
{
private readonly SignaturePolicyId sigPolicy;
public static SignaturePolicyIdentifier GetInstance(
object obj)
{
if (obj == null || obj is SignaturePolicyIdentifier)
return (SignaturePolicyIdentifier) obj;
if (obj is SignaturePolicyId)
return new SignaturePolicyIdentifier((SignaturePolicyId) obj);
if (obj is Asn1Null)
return new SignaturePolicyIdentifier();
throw new ArgumentException(
"Unknown object in 'SignaturePolicyIdentifier' factory: "
+ obj.GetType().Name,
"obj");
}
public SignaturePolicyIdentifier()
{
this.sigPolicy = null;
}
public SignaturePolicyIdentifier(
SignaturePolicyId signaturePolicyId)
{
if (signaturePolicyId == null)
throw new ArgumentNullException("signaturePolicyId");
this.sigPolicy = signaturePolicyId;
}
public SignaturePolicyId SignaturePolicyId
{
get { return sigPolicy; }
}
public override Asn1Object ToAsn1Object()
{
return sigPolicy == null
? DerNull.Instance
: sigPolicy.ToAsn1Object();
}
}
}

View File

@ -0,0 +1,96 @@
using System;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Esf
{
public class SignerAttribute
: Asn1Encodable
{
private Asn1Sequence claimedAttributes;
private AttributeCertificate certifiedAttributes;
public static SignerAttribute GetInstance(
object obj)
{
if (obj == null || obj is SignerAttribute)
return (SignerAttribute) obj;
if (obj is Asn1Sequence)
return new SignerAttribute(obj);
throw new ArgumentException(
"Unknown object in 'SignerAttribute' factory: "
+ obj.GetType().Name,
"obj");
}
private SignerAttribute(
object obj)
{
Asn1Sequence seq = (Asn1Sequence) obj;
DerTaggedObject taggedObject = (DerTaggedObject) seq[0];
if (taggedObject.TagNo == 0)
{
claimedAttributes = Asn1Sequence.GetInstance(taggedObject, true);
}
else if (taggedObject.TagNo == 1)
{
certifiedAttributes = AttributeCertificate.GetInstance(taggedObject);
}
else
{
throw new ArgumentException("illegal tag.", "obj");
}
}
public SignerAttribute(
Asn1Sequence claimedAttributes)
{
this.claimedAttributes = claimedAttributes;
}
public SignerAttribute(
AttributeCertificate certifiedAttributes)
{
this.certifiedAttributes = certifiedAttributes;
}
public virtual Asn1Sequence ClaimedAttributes
{
get { return claimedAttributes; }
}
public virtual AttributeCertificate CertifiedAttributes
{
get { return certifiedAttributes; }
}
/**
*
* <pre>
* SignerAttribute ::= SEQUENCE OF CHOICE {
* claimedAttributes [0] ClaimedAttributes,
* certifiedAttributes [1] CertifiedAttributes }
*
* ClaimedAttributes ::= SEQUENCE OF Attribute
* CertifiedAttributes ::= AttributeCertificate -- as defined in RFC 3281: see clause 4.1.
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector();
if (claimedAttributes != null)
{
v.Add(new DerTaggedObject(0, claimedAttributes));
}
else
{
v.Add(new DerTaggedObject(1, certifiedAttributes));
}
return new DerSequence(v);
}
}
}

View File

@ -1,138 +1,138 @@
using System;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.Ess
{
public class EssCertIDv2
: Asn1Encodable
{
private readonly AlgorithmIdentifier hashAlgorithm;
private readonly byte[] certHash;
private readonly IssuerSerial issuerSerial;
private static readonly AlgorithmIdentifier DefaultAlgID = new AlgorithmIdentifier(
NistObjectIdentifiers.IdSha256, DerNull.Instance);
public static EssCertIDv2 GetInstance(
object o)
{
if (o == null || o is EssCertIDv2)
return (EssCertIDv2) o;
if (o is Asn1Sequence)
return new EssCertIDv2((Asn1Sequence) o);
throw new ArgumentException(
"unknown object in 'EssCertIDv2' factory : "
+ o.GetType().Name + ".");
}
private EssCertIDv2(
Asn1Sequence seq)
{
if (seq.Count != 2 && seq.Count != 3)
throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
int count = 0;
if (seq[0] is Asn1OctetString)
{
// Default value
this.hashAlgorithm = DefaultAlgID;
}
else
{
this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[count++].ToAsn1Object());
}
this.certHash = Asn1OctetString.GetInstance(seq[count++].ToAsn1Object()).GetOctets();
if (seq.Count > count)
{
this.issuerSerial = IssuerSerial.GetInstance(
Asn1Sequence.GetInstance(seq[count].ToAsn1Object()));
}
}
public EssCertIDv2(
AlgorithmIdentifier algId,
byte[] certHash)
: this(algId, certHash, null)
{
}
public EssCertIDv2(
AlgorithmIdentifier algId,
byte[] certHash,
IssuerSerial issuerSerial)
{
if (algId == null)
{
// Default value
this.hashAlgorithm = DefaultAlgID;
}
else
{
this.hashAlgorithm = algId;
}
this.certHash = certHash;
this.issuerSerial = issuerSerial;
}
public AlgorithmIdentifier HashAlgorithm
{
get { return this.hashAlgorithm; }
}
public byte[] GetCertHash()
{
return Arrays.Clone(certHash);
}
public IssuerSerial IssuerSerial
{
get { return issuerSerial; }
}
/**
* <pre>
* EssCertIDv2 ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier
* DEFAULT {algorithm id-sha256 parameters NULL},
* certHash Hash,
* issuerSerial IssuerSerial OPTIONAL
* }
*
* Hash ::= OCTET STRING
*
* IssuerSerial ::= SEQUENCE {
* issuer GeneralNames,
* serialNumber CertificateSerialNumber
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector();
if (!hashAlgorithm.Equals(DefaultAlgID))
{
v.Add(hashAlgorithm);
}
v.Add(new DerOctetString(certHash).ToAsn1Object());
if (issuerSerial != null)
{
v.Add(issuerSerial);
}
return new DerSequence(v);
}
}
}
using System;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.Ess
{
public class EssCertIDv2
: Asn1Encodable
{
private readonly AlgorithmIdentifier hashAlgorithm;
private readonly byte[] certHash;
private readonly IssuerSerial issuerSerial;
private static readonly AlgorithmIdentifier DefaultAlgID = new AlgorithmIdentifier(
NistObjectIdentifiers.IdSha256);
public static EssCertIDv2 GetInstance(
object o)
{
if (o == null || o is EssCertIDv2)
return (EssCertIDv2) o;
if (o is Asn1Sequence)
return new EssCertIDv2((Asn1Sequence) o);
throw new ArgumentException(
"unknown object in 'EssCertIDv2' factory : "
+ o.GetType().Name + ".");
}
private EssCertIDv2(
Asn1Sequence seq)
{
if (seq.Count != 2 && seq.Count != 3)
throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
int count = 0;
if (seq[0] is Asn1OctetString)
{
// Default value
this.hashAlgorithm = DefaultAlgID;
}
else
{
this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[count++].ToAsn1Object());
}
this.certHash = Asn1OctetString.GetInstance(seq[count++].ToAsn1Object()).GetOctets();
if (seq.Count > count)
{
this.issuerSerial = IssuerSerial.GetInstance(
Asn1Sequence.GetInstance(seq[count].ToAsn1Object()));
}
}
public EssCertIDv2(
AlgorithmIdentifier algId,
byte[] certHash)
: this(algId, certHash, null)
{
}
public EssCertIDv2(
AlgorithmIdentifier algId,
byte[] certHash,
IssuerSerial issuerSerial)
{
if (algId == null)
{
// Default value
this.hashAlgorithm = DefaultAlgID;
}
else
{
this.hashAlgorithm = algId;
}
this.certHash = certHash;
this.issuerSerial = issuerSerial;
}
public AlgorithmIdentifier HashAlgorithm
{
get { return this.hashAlgorithm; }
}
public byte[] GetCertHash()
{
return Arrays.Clone(certHash);
}
public IssuerSerial IssuerSerial
{
get { return issuerSerial; }
}
/**
* <pre>
* EssCertIDv2 ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier
* DEFAULT {algorithm id-sha256},
* certHash Hash,
* issuerSerial IssuerSerial OPTIONAL
* }
*
* Hash ::= OCTET STRING
*
* IssuerSerial ::= SEQUENCE {
* issuer GeneralNames,
* serialNumber CertificateSerialNumber
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector();
if (!hashAlgorithm.Equals(DefaultAlgID))
{
v.Add(hashAlgorithm);
}
v.Add(new DerOctetString(certHash).ToAsn1Object());
if (issuerSerial != null)
{
v.Add(issuerSerial);
}
return new DerSequence(v);
}
}
}

View File

@ -1,187 +1,186 @@
using System;
using System.IO;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp
{
/**
* ISIS-MTT-Optional: The certificate requested by the client by inserting the
* RetrieveIfAllowed extension in the request, will be returned in this
* extension.
* <p/>
* ISIS-MTT-SigG: The signature act allows publishing certificates only then,
* when the certificate owner gives his isExplicit permission. Accordingly, there
* may be <EFBFBD>nondownloadable<EFBFBD> certificates, about which the responder must provide
* status information, but MUST NOT include them in the response. Clients may
* get therefore the following three kind of answers on a single request
* including the RetrieveIfAllowed extension:
* <ul>
* <li> a) the responder supports the extension and is allowed to publish the
* certificate: RequestedCertificate returned including the requested
* certificate</li>
* <li>b) the responder supports the extension but is NOT allowed to publish
* the certificate: RequestedCertificate returned including an empty OCTET
* STRING</li>
* <li>c) the responder does not support the extension: RequestedCertificate is
* not included in the response</li>
* </ul>
* Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If
* any of the OCTET STRING options is used, it MUST contain the DER encoding of
* the requested certificate.
* <p/>
* <pre>
* RequestedCertificate ::= CHOICE {
* Certificate Certificate,
* publicKeyCertificate [0] EXPLICIT OCTET STRING,
* attributeCertificate [1] EXPLICIT OCTET STRING
* }
* </pre>
*/
public class RequestedCertificate
: Asn1Encodable
//, ASN1Choice
{
public enum Choice
{
Certificate = -1,
PublicKeyCertificate = 0,
AttributeCertificate = 1
}
private readonly X509CertificateStructure cert;
private readonly byte[] publicKeyCert;
private readonly byte[] attributeCert;
public static RequestedCertificate GetInstance(
object obj)
{
if (obj == null || obj is RequestedCertificate)
{
return (RequestedCertificate) obj;
}
if (obj is Asn1Sequence)
{
return new RequestedCertificate(X509CertificateStructure.GetInstance(obj));
}
if (obj is Asn1TaggedObject)
{
return new RequestedCertificate((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static RequestedCertificate GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
if (!isExplicit)
throw new ArgumentException("choice item must be explicitly tagged");
return GetInstance(obj.GetObject());
}
private RequestedCertificate(
Asn1TaggedObject tagged)
{
switch ((Choice) tagged.TagNo)
{
case Choice.AttributeCertificate:
this.attributeCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
break;
case Choice.PublicKeyCertificate:
this.publicKeyCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
break;
default:
throw new ArgumentException("unknown tag number: " + tagged.TagNo);
}
}
/**
* Constructor from a given details.
* <p/>
* Only one parameter can be given. All other must be <code>null</code>.
*
* @param certificate Given as Certificate
*/
public RequestedCertificate(
X509CertificateStructure certificate)
{
this.cert = certificate;
}
public RequestedCertificate(
Choice type,
byte[] certificateOctets)
: this(new DerTaggedObject((int) type, new DerOctetString(certificateOctets)))
{
}
public Choice Type
{
get
{
if (cert != null)
return Choice.Certificate;
if (publicKeyCert != null)
return Choice.PublicKeyCertificate;
return Choice.AttributeCertificate;
}
}
public byte[] GetCertificateBytes()
{
if (cert != null)
{
try
{
return cert.GetEncoded();
}
catch (IOException e)
{
throw new InvalidOperationException("can't decode certificate: " + e);
}
}
if (publicKeyCert != null)
return publicKeyCert;
return attributeCert;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <p/>
* Returns:
* <p/>
* <pre>
* RequestedCertificate ::= CHOICE {
* Certificate Certificate,
* publicKeyCertificate [0] EXPLICIT OCTET STRING,
* attributeCertificate [1] EXPLICIT OCTET STRING
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
if (publicKeyCert != null)
{
return new DerTaggedObject(0, new DerOctetString(publicKeyCert));
}
if (attributeCert != null)
{
return new DerTaggedObject(1, new DerOctetString(attributeCert));
}
return cert.ToAsn1Object();
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp
{
/**
* ISIS-MTT-Optional: The certificate requested by the client by inserting the
* RetrieveIfAllowed extension in the request, will be returned in this
* extension.
* <p/>
* ISIS-MTT-SigG: The signature act allows publishing certificates only then,
* when the certificate owner gives his isExplicit permission. Accordingly, there
* may be <EFBFBD>nondownloadable<EFBFBD> certificates, about which the responder must provide
* status information, but MUST NOT include them in the response. Clients may
* get therefore the following three kind of answers on a single request
* including the RetrieveIfAllowed extension:
* <ul>
* <li> a) the responder supports the extension and is allowed to publish the
* certificate: RequestedCertificate returned including the requested
* certificate</li>
* <li>b) the responder supports the extension but is NOT allowed to publish
* the certificate: RequestedCertificate returned including an empty OCTET
* STRING</li>
* <li>c) the responder does not support the extension: RequestedCertificate is
* not included in the response</li>
* </ul>
* Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If
* any of the OCTET STRING options is used, it MUST contain the DER encoding of
* the requested certificate.
* <p/>
* <pre>
* RequestedCertificate ::= CHOICE {
* Certificate Certificate,
* publicKeyCertificate [0] EXPLICIT OCTET STRING,
* attributeCertificate [1] EXPLICIT OCTET STRING
* }
* </pre>
*/
public class RequestedCertificate
: Asn1Encodable, IAsn1Choice
{
public enum Choice
{
Certificate = -1,
PublicKeyCertificate = 0,
AttributeCertificate = 1
}
private readonly X509CertificateStructure cert;
private readonly byte[] publicKeyCert;
private readonly byte[] attributeCert;
public static RequestedCertificate GetInstance(
object obj)
{
if (obj == null || obj is RequestedCertificate)
{
return (RequestedCertificate) obj;
}
if (obj is Asn1Sequence)
{
return new RequestedCertificate(X509CertificateStructure.GetInstance(obj));
}
if (obj is Asn1TaggedObject)
{
return new RequestedCertificate((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static RequestedCertificate GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
if (!isExplicit)
throw new ArgumentException("choice item must be explicitly tagged");
return GetInstance(obj.GetObject());
}
private RequestedCertificate(
Asn1TaggedObject tagged)
{
switch ((Choice) tagged.TagNo)
{
case Choice.AttributeCertificate:
this.attributeCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
break;
case Choice.PublicKeyCertificate:
this.publicKeyCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
break;
default:
throw new ArgumentException("unknown tag number: " + tagged.TagNo);
}
}
/**
* Constructor from a given details.
* <p/>
* Only one parameter can be given. All other must be <code>null</code>.
*
* @param certificate Given as Certificate
*/
public RequestedCertificate(
X509CertificateStructure certificate)
{
this.cert = certificate;
}
public RequestedCertificate(
Choice type,
byte[] certificateOctets)
: this(new DerTaggedObject((int) type, new DerOctetString(certificateOctets)))
{
}
public Choice Type
{
get
{
if (cert != null)
return Choice.Certificate;
if (publicKeyCert != null)
return Choice.PublicKeyCertificate;
return Choice.AttributeCertificate;
}
}
public byte[] GetCertificateBytes()
{
if (cert != null)
{
try
{
return cert.GetEncoded();
}
catch (IOException e)
{
throw new InvalidOperationException("can't decode certificate: " + e);
}
}
if (publicKeyCert != null)
return publicKeyCert;
return attributeCert;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <p/>
* Returns:
* <p/>
* <pre>
* RequestedCertificate ::= CHOICE {
* Certificate Certificate,
* publicKeyCertificate [0] EXPLICIT OCTET STRING,
* attributeCertificate [1] EXPLICIT OCTET STRING
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
if (publicKeyCert != null)
{
return new DerTaggedObject(0, new DerOctetString(publicKeyCert));
}
if (attributeCert != null)
{
return new DerTaggedObject(1, new DerOctetString(attributeCert));
}
return cert.ToAsn1Object();
}
}
}

View File

@ -1,171 +1,170 @@
using System;
namespace Org.BouncyCastle.Asn1.IsisMtt.X509
{
/**
* A declaration of majority.
* <p/>
* <pre>
* DeclarationOfMajoritySyntax ::= CHOICE
* {
* notYoungerThan [0] IMPLICIT INTEGER,
* fullAgeAtCountry [1] IMPLICIT SEQUENCE
* {
* fullAge BOOLEAN DEFAULT TRUE,
* country PrintableString (SIZE(2))
* }
* dateOfBirth [2] IMPLICIT GeneralizedTime
* }
* </pre>
* <p/>
* fullAgeAtCountry indicates the majority of the owner with respect to the laws
* of a specific country.
*/
public class DeclarationOfMajority
: Asn1Encodable
//, ASN1Choice
{
public enum Choice
{
NotYoungerThan = 0,
FullAgeAtCountry = 1,
DateOfBirth = 2
};
private readonly Asn1TaggedObject declaration;
public DeclarationOfMajority(
int notYoungerThan)
{
declaration = new DerTaggedObject(false, 0, new DerInteger(notYoungerThan));
}
public DeclarationOfMajority(
bool fullAge,
string country)
{
if (country.Length > 2)
throw new ArgumentException("country can only be 2 characters");
DerPrintableString countryString = new DerPrintableString(country, true);
DerSequence seq;
if (fullAge)
{
seq = new DerSequence(countryString);
}
else
{
seq = new DerSequence(DerBoolean.False, countryString);
}
this.declaration = new DerTaggedObject(false, 1, seq);
}
public DeclarationOfMajority(
DerGeneralizedTime dateOfBirth)
{
this.declaration = new DerTaggedObject(false, 2, dateOfBirth);
}
public static DeclarationOfMajority GetInstance(
object obj)
{
if (obj == null || obj is DeclarationOfMajority)
{
return (DeclarationOfMajority) obj;
}
if (obj is Asn1TaggedObject)
{
return new DeclarationOfMajority((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
private DeclarationOfMajority(
Asn1TaggedObject o)
{
if (o.TagNo > 2)
throw new ArgumentException("Bad tag number: " + o.TagNo);
this.declaration = o;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <p/>
* Returns:
* <p/>
* <pre>
* DeclarationOfMajoritySyntax ::= CHOICE
* {
* notYoungerThan [0] IMPLICIT INTEGER,
* fullAgeAtCountry [1] IMPLICIT SEQUENCE
* {
* fullAge BOOLEAN DEFAULT TRUE,
* country PrintableString (SIZE(2))
* }
* dateOfBirth [2] IMPLICIT GeneralizedTime
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
return declaration;
}
public Choice Type
{
get { return (Choice) declaration.TagNo; }
}
/**
* @return notYoungerThan if that's what we are, -1 otherwise
*/
public virtual int NotYoungerThan
{
get
{
switch ((Choice) declaration.TagNo)
{
case Choice.NotYoungerThan:
return DerInteger.GetInstance(declaration, false).Value.IntValue;
default:
return -1;
}
}
}
public virtual Asn1Sequence FullAgeAtCountry
{
get
{
switch ((Choice) declaration.TagNo)
{
case Choice.FullAgeAtCountry:
return Asn1Sequence.GetInstance(declaration, false);
default:
return null;
}
}
}
public virtual DerGeneralizedTime DateOfBirth
{
get
{
switch ((Choice) declaration.TagNo)
{
case Choice.DateOfBirth:
return DerGeneralizedTime.GetInstance(declaration, false);
default:
return null;
}
}
}
}
}
using System;
namespace Org.BouncyCastle.Asn1.IsisMtt.X509
{
/**
* A declaration of majority.
* <p/>
* <pre>
* DeclarationOfMajoritySyntax ::= CHOICE
* {
* notYoungerThan [0] IMPLICIT INTEGER,
* fullAgeAtCountry [1] IMPLICIT SEQUENCE
* {
* fullAge BOOLEAN DEFAULT TRUE,
* country PrintableString (SIZE(2))
* }
* dateOfBirth [2] IMPLICIT GeneralizedTime
* }
* </pre>
* <p/>
* fullAgeAtCountry indicates the majority of the owner with respect to the laws
* of a specific country.
*/
public class DeclarationOfMajority
: Asn1Encodable, IAsn1Choice
{
public enum Choice
{
NotYoungerThan = 0,
FullAgeAtCountry = 1,
DateOfBirth = 2
};
private readonly Asn1TaggedObject declaration;
public DeclarationOfMajority(
int notYoungerThan)
{
declaration = new DerTaggedObject(false, 0, new DerInteger(notYoungerThan));
}
public DeclarationOfMajority(
bool fullAge,
string country)
{
if (country.Length > 2)
throw new ArgumentException("country can only be 2 characters");
DerPrintableString countryString = new DerPrintableString(country, true);
DerSequence seq;
if (fullAge)
{
seq = new DerSequence(countryString);
}
else
{
seq = new DerSequence(DerBoolean.False, countryString);
}
this.declaration = new DerTaggedObject(false, 1, seq);
}
public DeclarationOfMajority(
DerGeneralizedTime dateOfBirth)
{
this.declaration = new DerTaggedObject(false, 2, dateOfBirth);
}
public static DeclarationOfMajority GetInstance(
object obj)
{
if (obj == null || obj is DeclarationOfMajority)
{
return (DeclarationOfMajority) obj;
}
if (obj is Asn1TaggedObject)
{
return new DeclarationOfMajority((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
private DeclarationOfMajority(
Asn1TaggedObject o)
{
if (o.TagNo > 2)
throw new ArgumentException("Bad tag number: " + o.TagNo);
this.declaration = o;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <p/>
* Returns:
* <p/>
* <pre>
* DeclarationOfMajoritySyntax ::= CHOICE
* {
* notYoungerThan [0] IMPLICIT INTEGER,
* fullAgeAtCountry [1] IMPLICIT SEQUENCE
* {
* fullAge BOOLEAN DEFAULT TRUE,
* country PrintableString (SIZE(2))
* }
* dateOfBirth [2] IMPLICIT GeneralizedTime
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
return declaration;
}
public Choice Type
{
get { return (Choice) declaration.TagNo; }
}
/**
* @return notYoungerThan if that's what we are, -1 otherwise
*/
public virtual int NotYoungerThan
{
get
{
switch ((Choice) declaration.TagNo)
{
case Choice.NotYoungerThan:
return DerInteger.GetInstance(declaration, false).Value.IntValue;
default:
return -1;
}
}
}
public virtual Asn1Sequence FullAgeAtCountry
{
get
{
switch ((Choice) declaration.TagNo)
{
case Choice.FullAgeAtCountry:
return Asn1Sequence.GetInstance(declaration, false);
default:
return null;
}
}
}
public virtual DerGeneralizedTime DateOfBirth
{
get
{
switch ((Choice) declaration.TagNo)
{
case Choice.DateOfBirth:
return DerGeneralizedTime.GetInstance(declaration, false);
default:
return null;
}
}
}
}
}

View File

@ -1,94 +1,94 @@
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.Ocsp
{
public class CertStatus
: Asn1Encodable
{
private readonly int tagNo;
private readonly Asn1Encodable value;
/**
* create a CertStatus object with a tag of zero.
*/
public CertStatus()
{
tagNo = 0;
value = DerNull.Instance;
}
public CertStatus(
RevokedInfo info)
{
tagNo = 1;
value = info;
}
public CertStatus(
int tagNo,
Asn1Encodable value)
{
this.tagNo = tagNo;
this.value = value;
}
public CertStatus(
Asn1TaggedObject choice)
{
this.tagNo = choice.TagNo;
switch (choice.TagNo)
{
case 1:
value = RevokedInfo.GetInstance(choice, false);
break;
case 0:
case 2:
value = DerNull.Instance;
break;
}
}
public static CertStatus GetInstance(
object obj)
{
if (obj == null || obj is CertStatus)
{
return (CertStatus)obj;
}
if (obj is Asn1TaggedObject)
{
return new CertStatus((Asn1TaggedObject)obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public int TagNo
{
get { return tagNo; }
}
public Asn1Encodable Status
{
get { return value; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* CertStatus ::= CHOICE {
* good [0] IMPLICIT Null,
* revoked [1] IMPLICIT RevokedInfo,
* unknown [2] IMPLICIT UnknownInfo }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return new DerTaggedObject(false, tagNo, value);
}
}
}
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.Ocsp
{
public class CertStatus
: Asn1Encodable, IAsn1Choice
{
private readonly int tagNo;
private readonly Asn1Encodable value;
/**
* create a CertStatus object with a tag of zero.
*/
public CertStatus()
{
tagNo = 0;
value = DerNull.Instance;
}
public CertStatus(
RevokedInfo info)
{
tagNo = 1;
value = info;
}
public CertStatus(
int tagNo,
Asn1Encodable value)
{
this.tagNo = tagNo;
this.value = value;
}
public CertStatus(
Asn1TaggedObject choice)
{
this.tagNo = choice.TagNo;
switch (choice.TagNo)
{
case 1:
value = RevokedInfo.GetInstance(choice, false);
break;
case 0:
case 2:
value = DerNull.Instance;
break;
}
}
public static CertStatus GetInstance(
object obj)
{
if (obj == null || obj is CertStatus)
{
return (CertStatus)obj;
}
if (obj is Asn1TaggedObject)
{
return new CertStatus((Asn1TaggedObject)obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public int TagNo
{
get { return tagNo; }
}
public Asn1Encodable Status
{
get { return value; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* CertStatus ::= CHOICE {
* good [0] IMPLICIT Null,
* revoked [1] IMPLICIT RevokedInfo,
* unknown [2] IMPLICIT UnknownInfo }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return new DerTaggedObject(false, tagNo, value);
}
}
}

View File

@ -1,77 +1,77 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Ocsp
{
public class ResponderID
: Asn1Encodable
{
private readonly Asn1Encodable id;
public static ResponderID GetInstance(
object obj)
{
if (obj == null || obj is ResponderID)
{
return (ResponderID)obj;
}
if (obj is DerOctetString)
{
return new ResponderID((DerOctetString)obj);
}
if (obj is Asn1TaggedObject)
{
Asn1TaggedObject o = (Asn1TaggedObject)obj;
if (o.TagNo == 1)
{
return new ResponderID(X509Name.GetInstance(o, true));
}
return new ResponderID(Asn1OctetString.GetInstance(o, true));
}
return new ResponderID(X509Name.GetInstance(obj));
}
public ResponderID(
Asn1OctetString id)
{
if (id == null)
throw new ArgumentNullException("id");
this.id = id;
}
public ResponderID(
X509Name id)
{
if (id == null)
throw new ArgumentNullException("id");
this.id = id;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* ResponderID ::= CHOICE {
* byName [1] Name,
* byKey [2] KeyHash }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
if (id is Asn1OctetString)
{
return new DerTaggedObject(true, 2, id);
}
return new DerTaggedObject(true, 1, id);
}
}
}
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Ocsp
{
public class ResponderID
: Asn1Encodable, IAsn1Choice
{
private readonly Asn1Encodable id;
public static ResponderID GetInstance(
object obj)
{
if (obj == null || obj is ResponderID)
{
return (ResponderID)obj;
}
if (obj is DerOctetString)
{
return new ResponderID((DerOctetString)obj);
}
if (obj is Asn1TaggedObject)
{
Asn1TaggedObject o = (Asn1TaggedObject)obj;
if (o.TagNo == 1)
{
return new ResponderID(X509Name.GetInstance(o, true));
}
return new ResponderID(Asn1OctetString.GetInstance(o, true));
}
return new ResponderID(X509Name.GetInstance(obj));
}
public ResponderID(
Asn1OctetString id)
{
if (id == null)
throw new ArgumentNullException("id");
this.id = id;
}
public ResponderID(
X509Name id)
{
if (id == null)
throw new ArgumentNullException("id");
this.id = id;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* ResponderID ::= CHOICE {
* byName [1] Name,
* byKey [2] KeyHash }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
if (id is Asn1OctetString)
{
return new DerTaggedObject(true, 2, id);
}
return new DerTaggedObject(true, 1, id);
}
}
}

View File

@ -1,147 +1,151 @@
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using System;
namespace Org.BouncyCastle.Asn1.Ocsp
{
public class TbsRequest
: Asn1Encodable
{
private static readonly DerInteger V1 = new DerInteger(0);
private readonly DerInteger version;
private readonly GeneralName requestorName;
private readonly Asn1Sequence requestList;
private readonly X509Extensions requestExtensions;
public static TbsRequest GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
}
public static TbsRequest GetInstance(
object obj)
{
if (obj == null || obj is TbsRequest)
{
return (TbsRequest)obj;
}
if (obj is Asn1Sequence)
{
return new TbsRequest((Asn1Sequence)obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public TbsRequest(
GeneralName requestorName,
Asn1Sequence requestList,
X509Extensions requestExtensions)
{
this.version = V1;
this.requestorName = requestorName;
this.requestList = requestList;
this.requestExtensions = requestExtensions;
}
private TbsRequest(
Asn1Sequence seq)
{
int index = 0;
Asn1Encodable enc = seq[0];
if (enc is Asn1TaggedObject)
{
Asn1TaggedObject o = (Asn1TaggedObject) enc;
if (o.TagNo == 0)
{
version = DerInteger.GetInstance(o, true);
index++;
}
else
{
version = V1;
}
}
else
{
version = V1;
}
if (seq[index] is Asn1TaggedObject)
{
requestorName = GeneralName.GetInstance((Asn1TaggedObject) seq[index++], true);
}
requestList = (Asn1Sequence) seq[index++];
if (seq.Count == (index + 1))
{
requestExtensions = X509Extensions.GetInstance((Asn1TaggedObject) seq[index], true);
}
}
public DerInteger Version
{
get { return version; }
}
public GeneralName RequestorName
{
get { return requestorName; }
}
public Asn1Sequence RequestList
{
get { return requestList; }
}
public X509Extensions RequestExtensions
{
get { return requestExtensions; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* TBSRequest ::= Sequence {
* version [0] EXPLICIT Version DEFAULT v1,
* requestorName [1] EXPLICIT GeneralName OPTIONAL,
* requestList Sequence OF Request,
* requestExtensions [2] EXPLICIT Extensions OPTIONAL }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector();
//
// if default don't include.
//
if (!version.Equals(V1))
{
v.Add(new DerTaggedObject(true, 0, version));
}
if (requestorName != null)
{
v.Add(new DerTaggedObject(true, 1, requestorName));
}
v.Add(requestList);
if (requestExtensions != null)
{
v.Add(new DerTaggedObject(true, 2, requestExtensions));
}
return new DerSequence(v);
}
}
}
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using System;
namespace Org.BouncyCastle.Asn1.Ocsp
{
public class TbsRequest
: Asn1Encodable
{
private static readonly DerInteger V1 = new DerInteger(0);
private readonly DerInteger version;
private readonly GeneralName requestorName;
private readonly Asn1Sequence requestList;
private readonly X509Extensions requestExtensions;
private bool versionSet;
public static TbsRequest GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
}
public static TbsRequest GetInstance(
object obj)
{
if (obj == null || obj is TbsRequest)
{
return (TbsRequest)obj;
}
if (obj is Asn1Sequence)
{
return new TbsRequest((Asn1Sequence)obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public TbsRequest(
GeneralName requestorName,
Asn1Sequence requestList,
X509Extensions requestExtensions)
{
this.version = V1;
this.requestorName = requestorName;
this.requestList = requestList;
this.requestExtensions = requestExtensions;
}
private TbsRequest(
Asn1Sequence seq)
{
int index = 0;
Asn1Encodable enc = seq[0];
if (enc is Asn1TaggedObject)
{
Asn1TaggedObject o = (Asn1TaggedObject) enc;
if (o.TagNo == 0)
{
versionSet = true;
version = DerInteger.GetInstance(o, true);
index++;
}
else
{
version = V1;
}
}
else
{
version = V1;
}
if (seq[index] is Asn1TaggedObject)
{
requestorName = GeneralName.GetInstance((Asn1TaggedObject) seq[index++], true);
}
requestList = (Asn1Sequence) seq[index++];
if (seq.Count == (index + 1))
{
requestExtensions = X509Extensions.GetInstance((Asn1TaggedObject) seq[index], true);
}
}
public DerInteger Version
{
get { return version; }
}
public GeneralName RequestorName
{
get { return requestorName; }
}
public Asn1Sequence RequestList
{
get { return requestList; }
}
public X509Extensions RequestExtensions
{
get { return requestExtensions; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* TBSRequest ::= Sequence {
* version [0] EXPLICIT Version DEFAULT v1,
* requestorName [1] EXPLICIT GeneralName OPTIONAL,
* requestList Sequence OF Request,
* requestExtensions [2] EXPLICIT Extensions OPTIONAL }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector();
//
// if default don't include - unless explicitly provided. Not strictly correct
// but required for some requests
//
if (!version.Equals(V1) || versionSet)
{
v.Add(new DerTaggedObject(true, 0, version));
}
if (requestorName != null)
{
v.Add(new DerTaggedObject(true, 1, requestorName));
}
v.Add(requestList);
if (requestExtensions != null)
{
v.Add(new DerTaggedObject(true, 2, requestExtensions));
}
return new DerSequence(v);
}
}
}

View File

@ -1,24 +1,29 @@
namespace Org.BouncyCastle.Asn1.Oiw
{
public abstract class OiwObjectIdentifiers
{
public static readonly DerObjectIdentifier MD4WithRsa = new DerObjectIdentifier("1.3.14.3.2.2");
public static readonly DerObjectIdentifier MD5WithRsa = new DerObjectIdentifier("1.3.14.3.2.3");
public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier("1.3.14.3.2.4");
public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7");
// id-SHA1 OBJECT IDENTIFIER ::=
// {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } //
public static readonly DerObjectIdentifier IdSha1 = new DerObjectIdentifier("1.3.14.3.2.26");
public static readonly DerObjectIdentifier DsaWithSha1 = new DerObjectIdentifier("1.3.14.3.2.27");
public static readonly DerObjectIdentifier Sha1WithRsa = new DerObjectIdentifier("1.3.14.3.2.29");
// ElGamal Algorithm OBJECT IDENTIFIER ::=
// {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 }
//
public static readonly DerObjectIdentifier ElGamalAlgorithm = new DerObjectIdentifier("1.3.14.7.2.1.1");
}
}
namespace Org.BouncyCastle.Asn1.Oiw
{
public abstract class OiwObjectIdentifiers
{
public static readonly DerObjectIdentifier MD4WithRsa = new DerObjectIdentifier("1.3.14.3.2.2");
public static readonly DerObjectIdentifier MD5WithRsa = new DerObjectIdentifier("1.3.14.3.2.3");
public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier("1.3.14.3.2.4");
public static readonly DerObjectIdentifier DesEcb = new DerObjectIdentifier("1.3.14.3.2.6");
public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7");
public static readonly DerObjectIdentifier DesOfb = new DerObjectIdentifier("1.3.14.3.2.8");
public static readonly DerObjectIdentifier DesCfb = new DerObjectIdentifier("1.3.14.3.2.9");
public static readonly DerObjectIdentifier DesEde = new DerObjectIdentifier("1.3.14.3.2.17");
// id-SHA1 OBJECT IDENTIFIER ::=
// {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } //
public static readonly DerObjectIdentifier IdSha1 = new DerObjectIdentifier("1.3.14.3.2.26");
public static readonly DerObjectIdentifier DsaWithSha1 = new DerObjectIdentifier("1.3.14.3.2.27");
public static readonly DerObjectIdentifier Sha1WithRsa = new DerObjectIdentifier("1.3.14.3.2.29");
// ElGamal Algorithm OBJECT IDENTIFIER ::=
// {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 }
//
public static readonly DerObjectIdentifier ElGamalAlgorithm = new DerObjectIdentifier("1.3.14.7.2.1.1");
}
}

View File

@ -1,48 +1,61 @@
using System;
using System.Collections;
namespace Org.BouncyCastle.Asn1.Pkcs
{
public class PbeS2Parameters
: Asn1Encodable
{
private readonly KeyDerivationFunc func;
private readonly EncryptionScheme scheme;
public PbeS2Parameters(
Asn1Sequence obj)
{
IEnumerator e = obj.GetEnumerator();
e.MoveNext();
Asn1Sequence funcSeq = (Asn1Sequence) e.Current;
if (funcSeq[0].Equals(PkcsObjectIdentifiers.IdPbkdf2))
{
func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2, funcSeq[1]);
}
else
{
func = new KeyDerivationFunc(funcSeq);
}
e.MoveNext();
scheme = new EncryptionScheme((Asn1Sequence) e.Current);
}
public KeyDerivationFunc KeyDerivationFunc
{
get { return func; }
}
public EncryptionScheme EncryptionScheme
{
get { return scheme; }
}
public override Asn1Object ToAsn1Object()
{
return new DerSequence(func, scheme);
}
}
}
using System;
using System.Collections;
namespace Org.BouncyCastle.Asn1.Pkcs
{
public class PbeS2Parameters
: Asn1Encodable
{
private readonly KeyDerivationFunc func;
private readonly EncryptionScheme scheme;
public static PbeS2Parameters GetInstance(
object obj)
{
if (obj == null || obj is PbeS2Parameters)
return (PbeS2Parameters) obj;
if (obj is Asn1Sequence)
return new PbeS2Parameters((Asn1Sequence) obj);
throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
}
public PbeS2Parameters(
Asn1Sequence seq)
{
if (seq.Count != 2)
throw new ArgumentException("Wrong number of elements in sequence", "seq");
Asn1Sequence funcSeq = (Asn1Sequence)seq[0];
// TODO Not sure if this special case is really necessary/appropriate
if (funcSeq[0].Equals(PkcsObjectIdentifiers.IdPbkdf2))
{
func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2,
Pbkdf2Params.GetInstance(funcSeq[1]));
}
else
{
func = new KeyDerivationFunc(funcSeq);
}
scheme = new EncryptionScheme((Asn1Sequence) seq[1]);
}
public KeyDerivationFunc KeyDerivationFunc
{
get { return func; }
}
public EncryptionScheme EncryptionScheme
{
get { return scheme; }
}
public override Asn1Object ToAsn1Object()
{
return new DerSequence(func, scheme);
}
}
}

View File

@ -1,85 +1,77 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Asn1.Pkcs
{
public class Pbkdf2Params
: Asn1Encodable
{
internal Asn1OctetString octStr;
internal DerInteger iterationCount;
internal DerInteger keyLength;
public static Pbkdf2Params GetInstance(
object obj)
{
if (obj is Pbkdf2Params || obj == null)
{
return (Pbkdf2Params) obj;
}
if (obj is Asn1Sequence)
{
return new Pbkdf2Params((Asn1Sequence) obj);
}
throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
}
public Pbkdf2Params(
Asn1Sequence seq)
{
IEnumerator e = seq.GetEnumerator();
e.MoveNext();
octStr = (Asn1OctetString) e.Current;
e.MoveNext();
iterationCount = (DerInteger) e.Current;
if (e.MoveNext())
{
keyLength = (DerInteger) e.Current;
}
}
public Pbkdf2Params(
byte[] salt,
int iterationCount)
{
this.octStr = new DerOctetString(salt);
this.iterationCount = new DerInteger(iterationCount);
}
public byte[] GetSalt()
{
return octStr.GetOctets();
}
public BigInteger IterationCount
{
get { return iterationCount.Value; }
}
public BigInteger KeyLength
{
get { return keyLength == null ? null : keyLength.Value; }
}
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector(
octStr, iterationCount);
if (keyLength != null)
{
v.Add(keyLength);
}
return new DerSequence(v);
}
}
}
using System;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Asn1.Pkcs
{
public class Pbkdf2Params
: Asn1Encodable
{
private readonly Asn1OctetString octStr;
private readonly DerInteger iterationCount;
private readonly DerInteger keyLength;
public static Pbkdf2Params GetInstance(
object obj)
{
if (obj == null || obj is Pbkdf2Params)
return (Pbkdf2Params)obj;
if (obj is Asn1Sequence)
return new Pbkdf2Params((Asn1Sequence)obj);
throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
}
public Pbkdf2Params(
Asn1Sequence seq)
{
if (seq.Count < 2 || seq.Count > 3)
throw new ArgumentException("Wrong number of elements in sequence", "seq");
octStr = (Asn1OctetString)seq[0];
iterationCount = (DerInteger)seq[1];
if (seq.Count > 2)
{
keyLength = (DerInteger)seq[2];
}
}
public Pbkdf2Params(
byte[] salt,
int iterationCount)
{
this.octStr = new DerOctetString(salt);
this.iterationCount = new DerInteger(iterationCount);
}
public byte[] GetSalt()
{
return octStr.GetOctets();
}
public BigInteger IterationCount
{
get { return iterationCount.Value; }
}
public BigInteger KeyLength
{
get { return keyLength == null ? null : keyLength.Value; }
}
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector(
octStr, iterationCount);
if (keyLength != null)
{
v.Add(keyLength);
}
return new DerSequence(v);
}
}
}

View File

@ -1,76 +1,75 @@
using System;
namespace Org.BouncyCastle.Asn1.X500
{
public class DirectoryString
: Asn1Encodable, IAsn1String
//, Asn1Choice
{
private readonly DerStringBase str;
public static DirectoryString GetInstance(
object obj)
{
if (obj is DirectoryString)
{
return (DirectoryString) obj;
}
if (obj is DerStringBase)
{
if (obj is DerT61String
|| obj is DerPrintableString
|| obj is DerUniversalString
|| obj is DerUtf8String
|| obj is DerBmpString)
{
return new DirectoryString((DerStringBase) obj);
}
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static DirectoryString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
if (!isExplicit)
throw new ArgumentException("choice item must be explicitly tagged");
return GetInstance(obj.GetObject());
}
private DirectoryString(
DerStringBase str)
{
this.str = str;
}
public DirectoryString(
string str)
{
this.str = new DerUtf8String(str);
}
public string GetString()
{
return str.GetString();
}
/**
* <pre>
* DirectoryString ::= CHOICE {
* teletexString TeletexString (SIZE (1..MAX)),
* printableString PrintableString (SIZE (1..MAX)),
* universalString UniversalString (SIZE (1..MAX)),
* utf8String UTF8String (SIZE (1..MAX)),
* bmpString BMPString (SIZE (1..MAX)) }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return str.ToAsn1Object();
}
}
}
using System;
namespace Org.BouncyCastle.Asn1.X500
{
public class DirectoryString
: Asn1Encodable, IAsn1Choice, IAsn1String
{
private readonly DerStringBase str;
public static DirectoryString GetInstance(
object obj)
{
if (obj is DirectoryString)
{
return (DirectoryString) obj;
}
if (obj is DerStringBase)
{
if (obj is DerT61String
|| obj is DerPrintableString
|| obj is DerUniversalString
|| obj is DerUtf8String
|| obj is DerBmpString)
{
return new DirectoryString((DerStringBase) obj);
}
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static DirectoryString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
if (!isExplicit)
throw new ArgumentException("choice item must be explicitly tagged");
return GetInstance(obj.GetObject());
}
private DirectoryString(
DerStringBase str)
{
this.str = str;
}
public DirectoryString(
string str)
{
this.str = new DerUtf8String(str);
}
public string GetString()
{
return str.GetString();
}
/**
* <pre>
* DirectoryString ::= CHOICE {
* teletexString TeletexString (SIZE (1..MAX)),
* printableString PrintableString (SIZE (1..MAX)),
* universalString UniversalString (SIZE (1..MAX)),
* utf8String UTF8String (SIZE (1..MAX)),
* bmpString BMPString (SIZE (1..MAX)) }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return str.ToAsn1Object();
}
}
}

View File

@ -1,88 +1,83 @@
using System;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The AccessDescription object.
* <pre>
* AccessDescription ::= SEQUENCE {
* accessMethod OBJECT IDENTIFIER,
* accessLocation GeneralName }
* </pre>
*/
public class AccessDescription
: Asn1Encodable
{
public readonly static DerObjectIdentifier IdADCAIssuers = new DerObjectIdentifier("1.3.6.1.5.5.7.48.2");
public readonly static DerObjectIdentifier IdADOcsp = new DerObjectIdentifier("1.3.6.1.5.5.7.48.1");
internal DerObjectIdentifier accessMethod;
internal GeneralName accessLocation;
public static AccessDescription GetInstance(
object obj)
{
if (obj is AccessDescription)
{
return (AccessDescription) obj;
}
if (obj is Asn1Sequence)
{
return new AccessDescription((Asn1Sequence) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
private AccessDescription(
Asn1Sequence seq)
{
if (seq.Count != 2)
throw new ArgumentException("wrong number of elements in inner sequence");
accessMethod = DerObjectIdentifier.GetInstance(seq[0]);
accessLocation = GeneralName.GetInstance(seq[1]);
}
/**
* create an AccessDescription with the oid and location provided.
*/
public AccessDescription(
DerObjectIdentifier oid,
GeneralName location)
{
accessMethod = oid;
accessLocation = location;
}
/**
*
* @return the access method.
*/
public DerObjectIdentifier AccessMethod
{
get { return accessMethod; }
}
/**
*
* @return the access location
*/
public GeneralName AccessLocation
{
get { return accessLocation; }
}
public override Asn1Object ToAsn1Object()
{
return new DerSequence(accessMethod, accessLocation);
}
public override string ToString()
{
return ("AccessDescription: Oid(" + this.accessMethod.Id + ")");
}
}
}
using System;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The AccessDescription object.
* <pre>
* AccessDescription ::= SEQUENCE {
* accessMethod OBJECT IDENTIFIER,
* accessLocation GeneralName }
* </pre>
*/
public class AccessDescription
: Asn1Encodable
{
public readonly static DerObjectIdentifier IdADCAIssuers = new DerObjectIdentifier("1.3.6.1.5.5.7.48.2");
public readonly static DerObjectIdentifier IdADOcsp = new DerObjectIdentifier("1.3.6.1.5.5.7.48.1");
private readonly DerObjectIdentifier accessMethod;
private readonly GeneralName accessLocation;
public static AccessDescription GetInstance(
object obj)
{
if (obj is AccessDescription)
return (AccessDescription) obj;
if (obj is Asn1Sequence)
return new AccessDescription((Asn1Sequence) obj);
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
private AccessDescription(
Asn1Sequence seq)
{
if (seq.Count != 2)
throw new ArgumentException("wrong number of elements in sequence");
accessMethod = DerObjectIdentifier.GetInstance(seq[0]);
accessLocation = GeneralName.GetInstance(seq[1]);
}
/**
* create an AccessDescription with the oid and location provided.
*/
public AccessDescription(
DerObjectIdentifier oid,
GeneralName location)
{
accessMethod = oid;
accessLocation = location;
}
/**
*
* @return the access method.
*/
public DerObjectIdentifier AccessMethod
{
get { return accessMethod; }
}
/**
*
* @return the access location
*/
public GeneralName AccessLocation
{
get { return accessLocation; }
}
public override Asn1Object ToAsn1Object()
{
return new DerSequence(accessMethod, accessLocation);
}
public override string ToString()
{
return "AccessDescription: Oid(" + this.accessMethod.Id + ")";
}
}
}

View File

@ -1,86 +1,86 @@
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X509
{
public class AttCertIssuer
: Asn1Encodable
{
internal readonly Asn1Encodable obj;
internal readonly Asn1Object choiceObj;
public static AttCertIssuer GetInstance(
object obj)
{
if (obj is AttCertIssuer)
{
return (AttCertIssuer)obj;
}
else if (obj is V2Form)
{
return new AttCertIssuer(V2Form.GetInstance(obj));
}
else if (obj is GeneralNames)
{
return new AttCertIssuer((GeneralNames)obj);
}
else if (obj is Asn1TaggedObject)
{
return new AttCertIssuer(V2Form.GetInstance((Asn1TaggedObject)obj, false));
}
else if (obj is Asn1Sequence)
{
return new AttCertIssuer(GeneralNames.GetInstance(obj));
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static AttCertIssuer GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
return GetInstance(obj.GetObject()); // must be explictly tagged
}
/// <summary>
/// Don't use this one if you are trying to be RFC 3281 compliant.
/// Use it for v1 attribute certificates only.
/// </summary>
/// <param name="names">Our GeneralNames structure</param>
public AttCertIssuer(
GeneralNames names)
{
obj = names;
choiceObj = obj.ToAsn1Object();
}
public AttCertIssuer(
V2Form v2Form)
{
obj = v2Form;
choiceObj = new DerTaggedObject(false, 0, obj);
}
public Asn1Encodable Issuer
{
get { return obj; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* AttCertIssuer ::= CHOICE {
* v1Form GeneralNames, -- MUST NOT be used in this
* -- profile
* v2Form [0] V2Form -- v2 only
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return choiceObj;
}
}
}
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X509
{
public class AttCertIssuer
: Asn1Encodable, IAsn1Choice
{
internal readonly Asn1Encodable obj;
internal readonly Asn1Object choiceObj;
public static AttCertIssuer GetInstance(
object obj)
{
if (obj is AttCertIssuer)
{
return (AttCertIssuer)obj;
}
else if (obj is V2Form)
{
return new AttCertIssuer(V2Form.GetInstance(obj));
}
else if (obj is GeneralNames)
{
return new AttCertIssuer((GeneralNames)obj);
}
else if (obj is Asn1TaggedObject)
{
return new AttCertIssuer(V2Form.GetInstance((Asn1TaggedObject)obj, false));
}
else if (obj is Asn1Sequence)
{
return new AttCertIssuer(GeneralNames.GetInstance(obj));
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static AttCertIssuer GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
return GetInstance(obj.GetObject()); // must be explictly tagged
}
/// <summary>
/// Don't use this one if you are trying to be RFC 3281 compliant.
/// Use it for v1 attribute certificates only.
/// </summary>
/// <param name="names">Our GeneralNames structure</param>
public AttCertIssuer(
GeneralNames names)
{
obj = names;
choiceObj = obj.ToAsn1Object();
}
public AttCertIssuer(
V2Form v2Form)
{
obj = v2Form;
choiceObj = new DerTaggedObject(false, 0, obj);
}
public Asn1Encodable Issuer
{
get { return obj; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* AttCertIssuer ::= CHOICE {
* v1Form GeneralNames, -- MUST NOT be used in this
* -- profile
* v2Form [0] V2Form -- v2 only
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return choiceObj;
}
}
}

View File

@ -1,87 +1,105 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The AuthorityInformationAccess object.
* <pre>
* id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
*
* AuthorityInfoAccessSyntax ::=
* Sequence SIZE (1..MAX) OF AccessDescription
* AccessDescription ::= Sequence {
* accessMethod OBJECT IDENTIFIER,
* accessLocation GeneralName }
*
* id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
* id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
* id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
* </pre>
*/
public class AuthorityInformationAccess
: Asn1Encodable
{
internal readonly DerObjectIdentifier accessMethod;
internal readonly GeneralName accessLocation;
public static AuthorityInformationAccess GetInstance(
object obj)
{
if (obj is AuthorityInformationAccess)
{
return (AuthorityInformationAccess) obj;
}
if (obj is Asn1Sequence)
{
return new AuthorityInformationAccess((Asn1Sequence) obj);
}
if (obj is X509Extension)
{
return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
private AuthorityInformationAccess(
Asn1Sequence seq)
{
foreach (DerSequence vec in seq)
{
if (vec.Count != 2)
{
throw new ArgumentException("wrong number of elements in inner sequence");
}
accessMethod = (DerObjectIdentifier) vec[0];
accessLocation = (GeneralName) vec[1];
}
}
/**
* create an AuthorityInformationAccess with the oid and location provided.
*/
public AuthorityInformationAccess(
DerObjectIdentifier oid,
GeneralName location)
{
accessMethod = oid;
accessLocation = location;
}
public override Asn1Object ToAsn1Object()
{
return new DerSequence(new DerSequence(accessMethod, accessLocation));
}
public override string ToString()
{
return ("AuthorityInformationAccess: Oid(" + this.accessMethod.Id + ")");
}
}
}
using System;
using System.Collections;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The AuthorityInformationAccess object.
* <pre>
* id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
*
* AuthorityInfoAccessSyntax ::=
* Sequence SIZE (1..MAX) OF AccessDescription
* AccessDescription ::= Sequence {
* accessMethod OBJECT IDENTIFIER,
* accessLocation GeneralName }
*
* id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
* id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
* id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
* </pre>
*/
public class AuthorityInformationAccess
: Asn1Encodable
{
private readonly AccessDescription[] descriptions;
public static AuthorityInformationAccess GetInstance(
object obj)
{
if (obj is AuthorityInformationAccess)
return (AuthorityInformationAccess) obj;
if (obj is Asn1Sequence)
return new AuthorityInformationAccess((Asn1Sequence) obj);
if (obj is X509Extension)
return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
private AuthorityInformationAccess(
Asn1Sequence seq)
{
if (seq.Count < 1)
throw new ArgumentException("sequence may not be empty");
this.descriptions = new AccessDescription[seq.Count];
for (int i = 0; i < seq.Count; ++i)
{
descriptions[i] = AccessDescription.GetInstance(seq[i]);
}
}
/**
* create an AuthorityInformationAccess with the oid and location provided.
*/
[Obsolete("Use version taking an AccessDescription instead")]
public AuthorityInformationAccess(
DerObjectIdentifier oid,
GeneralName location)
{
this.descriptions = new AccessDescription[]{ new AccessDescription(oid, location) };
}
public AuthorityInformationAccess(
AccessDescription description)
{
this.descriptions = new AccessDescription[]{ description };
}
public AccessDescription[] GetAccessDescriptions()
{
return (AccessDescription[]) descriptions.Clone();
}
public override Asn1Object ToAsn1Object()
{
return new DerSequence(descriptions);
}
public override string ToString()
{
StringBuilder buf = new StringBuilder();
string sep = Platform.NewLine;
buf.Append("AuthorityInformationAccess:");
buf.Append(sep);
foreach (AccessDescription description in descriptions)
{
buf.Append(" ");
buf.Append(description);
buf.Append(sep);
}
return buf.ToString();
}
}
}

View File

@ -1,172 +1,172 @@
using System;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* <code>DisplayText</code> class, used in
* <code>CertificatePolicies</code> X509 V3 extensions (in policy qualifiers).
*
* <p>It stores a string in a chosen encoding.
* <pre>
* DisplayText ::= CHOICE {
* ia5String IA5String (SIZE (1..200)),
* visibleString VisibleString (SIZE (1..200)),
* bmpString BMPString (SIZE (1..200)),
* utf8String UTF8String (SIZE (1..200)) }
* </pre></p>
* @see PolicyQualifierInfo
* @see PolicyInformation
*/
public class DisplayText
: Asn1Encodable
{
/**
* Constant corresponding to ia5String encoding.
*
*/
public const int ContentTypeIA5String = 0;
/**
* Constant corresponding to bmpString encoding.
*
*/
public const int ContentTypeBmpString = 1;
/**
* Constant corresponding to utf8String encoding.
*
*/
public const int ContentTypeUtf8String = 2;
/**
* Constant corresponding to visibleString encoding.
*
*/
public const int ContentTypeVisibleString = 3;
/**
* Describe constant <code>DisplayTextMaximumSize</code> here.
*
*/
public const int DisplayTextMaximumSize = 200;
internal readonly int contentType;
internal readonly IAsn1String contents;
/**
* Creates a new <code>DisplayText</code> instance.
*
* @param type the desired encoding type for the text.
* @param text the text to store. Strings longer than 200
* characters are truncated.
*/
public DisplayText(
int type,
string text)
{
if (text.Length > DisplayTextMaximumSize)
{
// RFC3280 limits these strings to 200 chars
// truncate the string
text = text.Substring(0, DisplayTextMaximumSize);
}
contentType = type;
switch (type)
{
case ContentTypeIA5String:
contents = (IAsn1String)new DerIA5String (text);
break;
case ContentTypeUtf8String:
contents = (IAsn1String)new DerUtf8String(text);
break;
case ContentTypeVisibleString:
contents = (IAsn1String)new DerVisibleString(text);
break;
case ContentTypeBmpString:
contents = (IAsn1String)new DerBmpString(text);
break;
default:
contents = (IAsn1String)new DerUtf8String(text);
break;
}
}
// /**
// * return true if the passed in string can be represented without
// * loss as a PrintableString, false otherwise.
// */
// private bool CanBePrintable(
// string str)
// {
// for (int i = str.Length - 1; i >= 0; i--)
// {
// if (str[i] > 0x007f)
// {
// return false;
// }
// }
//
// return true;
// }
/**
* Creates a new <code>DisplayText</code> instance.
*
* @param text the text to encapsulate. Strings longer than 200
* characters are truncated.
*/
public DisplayText(
string text)
{
// by default use UTF8String
if (text.Length > DisplayTextMaximumSize)
{
text = text.Substring(0, DisplayTextMaximumSize);
}
contentType = ContentTypeUtf8String;
contents = new DerUtf8String(text);
}
/**
* Creates a new <code>DisplayText</code> instance.
* <p>Useful when reading back a <code>DisplayText</code> class
* from it's Asn1Encodable form.</p>
*
* @param contents an <code>Asn1Encodable</code> instance.
*/
public DisplayText(
IAsn1String contents)
{
this.contents = contents;
}
public static DisplayText GetInstance(
object obj)
{
if (obj is IAsn1String)
{
return new DisplayText((IAsn1String) obj);
}
if (obj is DisplayText)
{
return (DisplayText) obj;
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public override Asn1Object ToAsn1Object()
{
return (Asn1Object) contents;
}
/**
* Returns the stored <code>string</code> object.
*
* @return the stored text as a <code>string</code>.
*/
public string GetString()
{
return contents.GetString();
}
}
}
using System;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* <code>DisplayText</code> class, used in
* <code>CertificatePolicies</code> X509 V3 extensions (in policy qualifiers).
*
* <p>It stores a string in a chosen encoding.
* <pre>
* DisplayText ::= CHOICE {
* ia5String IA5String (SIZE (1..200)),
* visibleString VisibleString (SIZE (1..200)),
* bmpString BMPString (SIZE (1..200)),
* utf8String UTF8String (SIZE (1..200)) }
* </pre></p>
* @see PolicyQualifierInfo
* @see PolicyInformation
*/
public class DisplayText
: Asn1Encodable, IAsn1Choice
{
/**
* Constant corresponding to ia5String encoding.
*
*/
public const int ContentTypeIA5String = 0;
/**
* Constant corresponding to bmpString encoding.
*
*/
public const int ContentTypeBmpString = 1;
/**
* Constant corresponding to utf8String encoding.
*
*/
public const int ContentTypeUtf8String = 2;
/**
* Constant corresponding to visibleString encoding.
*
*/
public const int ContentTypeVisibleString = 3;
/**
* Describe constant <code>DisplayTextMaximumSize</code> here.
*
*/
public const int DisplayTextMaximumSize = 200;
internal readonly int contentType;
internal readonly IAsn1String contents;
/**
* Creates a new <code>DisplayText</code> instance.
*
* @param type the desired encoding type for the text.
* @param text the text to store. Strings longer than 200
* characters are truncated.
*/
public DisplayText(
int type,
string text)
{
if (text.Length > DisplayTextMaximumSize)
{
// RFC3280 limits these strings to 200 chars
// truncate the string
text = text.Substring(0, DisplayTextMaximumSize);
}
contentType = type;
switch (type)
{
case ContentTypeIA5String:
contents = (IAsn1String)new DerIA5String (text);
break;
case ContentTypeUtf8String:
contents = (IAsn1String)new DerUtf8String(text);
break;
case ContentTypeVisibleString:
contents = (IAsn1String)new DerVisibleString(text);
break;
case ContentTypeBmpString:
contents = (IAsn1String)new DerBmpString(text);
break;
default:
contents = (IAsn1String)new DerUtf8String(text);
break;
}
}
// /**
// * return true if the passed in string can be represented without
// * loss as a PrintableString, false otherwise.
// */
// private bool CanBePrintable(
// string str)
// {
// for (int i = str.Length - 1; i >= 0; i--)
// {
// if (str[i] > 0x007f)
// {
// return false;
// }
// }
//
// return true;
// }
/**
* Creates a new <code>DisplayText</code> instance.
*
* @param text the text to encapsulate. Strings longer than 200
* characters are truncated.
*/
public DisplayText(
string text)
{
// by default use UTF8String
if (text.Length > DisplayTextMaximumSize)
{
text = text.Substring(0, DisplayTextMaximumSize);
}
contentType = ContentTypeUtf8String;
contents = new DerUtf8String(text);
}
/**
* Creates a new <code>DisplayText</code> instance.
* <p>Useful when reading back a <code>DisplayText</code> class
* from it's Asn1Encodable form.</p>
*
* @param contents an <code>Asn1Encodable</code> instance.
*/
public DisplayText(
IAsn1String contents)
{
this.contents = contents;
}
public static DisplayText GetInstance(
object obj)
{
if (obj is IAsn1String)
{
return new DisplayText((IAsn1String) obj);
}
if (obj is DisplayText)
{
return (DisplayText) obj;
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public override Asn1Object ToAsn1Object()
{
return (Asn1Object) contents;
}
/**
* Returns the stored <code>string</code> object.
*
* @return the stored text as a <code>string</code>.
*/
public string GetString()
{
return contents.GetString();
}
}
}

View File

@ -1,130 +1,130 @@
using System;
using System.Text;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The DistributionPointName object.
* <pre>
* DistributionPointName ::= CHOICE {
* fullName [0] GeneralNames,
* nameRelativeToCRLIssuer [1] RelativeDistinguishedName
* }
* </pre>
*/
public class DistributionPointName
: Asn1Encodable
{
internal readonly Asn1Encodable name;
internal readonly int type;
public const int FullName = 0;
public const int NameRelativeToCrlIssuer = 1;
public static DistributionPointName GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(Asn1TaggedObject.GetInstance(obj, explicitly));
}
public static DistributionPointName GetInstance(
object obj)
{
if (obj == null || obj is DistributionPointName)
{
return (DistributionPointName) obj;
}
if (obj is Asn1TaggedObject)
{
return new DistributionPointName((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public DistributionPointName(
int type,
Asn1Encodable name)
{
this.type = type;
this.name = name;
}
public DistributionPointName(
GeneralNames name)
: this(FullName, name)
{
}
public int PointType
{
get { return type; }
}
public Asn1Encodable Name
{
get { return name; }
}
public DistributionPointName(
Asn1TaggedObject obj)
{
this.type = obj.TagNo;
if (type == FullName)
{
this.name = GeneralNames.GetInstance(obj, false);
}
else
{
this.name = Asn1Set.GetInstance(obj, false);
}
}
public override Asn1Object ToAsn1Object()
{
return new DerTaggedObject(false, type, name);
}
public override string ToString()
{
string sep = Platform.NewLine;
StringBuilder buf = new StringBuilder();
buf.Append("DistributionPointName: [");
buf.Append(sep);
if (type == FullName)
{
appendObject(buf, sep, "fullName", name.ToString());
}
else
{
appendObject(buf, sep, "nameRelativeToCRLIssuer", name.ToString());
}
buf.Append("]");
buf.Append(sep);
return buf.ToString();
}
private void appendObject(
StringBuilder buf,
string sep,
string name,
string val)
{
string indent = " ";
buf.Append(indent);
buf.Append(name);
buf.Append(":");
buf.Append(sep);
buf.Append(indent);
buf.Append(indent);
buf.Append(val);
buf.Append(sep);
}
}
}
using System;
using System.Text;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The DistributionPointName object.
* <pre>
* DistributionPointName ::= CHOICE {
* fullName [0] GeneralNames,
* nameRelativeToCRLIssuer [1] RelativeDistinguishedName
* }
* </pre>
*/
public class DistributionPointName
: Asn1Encodable, IAsn1Choice
{
internal readonly Asn1Encodable name;
internal readonly int type;
public const int FullName = 0;
public const int NameRelativeToCrlIssuer = 1;
public static DistributionPointName GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(Asn1TaggedObject.GetInstance(obj, true));
}
public static DistributionPointName GetInstance(
object obj)
{
if (obj == null || obj is DistributionPointName)
{
return (DistributionPointName) obj;
}
if (obj is Asn1TaggedObject)
{
return new DistributionPointName((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public DistributionPointName(
int type,
Asn1Encodable name)
{
this.type = type;
this.name = name;
}
public DistributionPointName(
GeneralNames name)
: this(FullName, name)
{
}
public int PointType
{
get { return type; }
}
public Asn1Encodable Name
{
get { return name; }
}
public DistributionPointName(
Asn1TaggedObject obj)
{
this.type = obj.TagNo;
if (type == FullName)
{
this.name = GeneralNames.GetInstance(obj, false);
}
else
{
this.name = Asn1Set.GetInstance(obj, false);
}
}
public override Asn1Object ToAsn1Object()
{
return new DerTaggedObject(false, type, name);
}
public override string ToString()
{
string sep = Platform.NewLine;
StringBuilder buf = new StringBuilder();
buf.Append("DistributionPointName: [");
buf.Append(sep);
if (type == FullName)
{
appendObject(buf, sep, "fullName", name.ToString());
}
else
{
appendObject(buf, sep, "nameRelativeToCRLIssuer", name.ToString());
}
buf.Append("]");
buf.Append(sep);
return buf.ToString();
}
private void appendObject(
StringBuilder buf,
string sep,
string name,
string val)
{
string indent = " ";
buf.Append(indent);
buf.Append(name);
buf.Append(":");
buf.Append(sep);
buf.Append(indent);
buf.Append(indent);
buf.Append(val);
buf.Append(sep);
}
}
}

View File

@ -1,406 +1,406 @@
using System;
using System.Collections;
using System.Globalization;
using System.Text;
using NetUtils = Org.BouncyCastle.Utilities.Net;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The GeneralName object.
* <pre>
* GeneralName ::= CHOICE {
* otherName [0] OtherName,
* rfc822Name [1] IA5String,
* dNSName [2] IA5String,
* x400Address [3] ORAddress,
* directoryName [4] Name,
* ediPartyName [5] EDIPartyName,
* uniformResourceIdentifier [6] IA5String,
* iPAddress [7] OCTET STRING,
* registeredID [8] OBJECT IDENTIFIER}
*
* OtherName ::= Sequence {
* type-id OBJECT IDENTIFIER,
* value [0] EXPLICIT ANY DEFINED BY type-id }
*
* EDIPartyName ::= Sequence {
* nameAssigner [0] DirectoryString OPTIONAL,
* partyName [1] DirectoryString }
* </pre>
*/
public class GeneralName
: Asn1Encodable
{
public const int OtherName = 0;
public const int Rfc822Name = 1;
public const int DnsName = 2;
public const int X400Address = 3;
public const int DirectoryName = 4;
public const int EdiPartyName = 5;
public const int UniformResourceIdentifier = 6;
public const int IPAddress = 7;
public const int RegisteredID = 8;
internal readonly Asn1Encodable obj;
internal readonly int tag;
public GeneralName(
X509Name directoryName)
{
this.obj = directoryName;
this.tag = 4;
}
/**
* When the subjectAltName extension contains an Internet mail address,
* the address MUST be included as an rfc822Name. The format of an
* rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
*
* When the subjectAltName extension contains a domain name service
* label, the domain name MUST be stored in the dNSName (an IA5String).
* The name MUST be in the "preferred name syntax," as specified by RFC
* 1034 [RFC 1034].
*
* When the subjectAltName extension contains a URI, the name MUST be
* stored in the uniformResourceIdentifier (an IA5String). The name MUST
* be a non-relative URL, and MUST follow the URL syntax and encoding
* rules specified in [RFC 1738]. The name must include both a scheme
* (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
* specific-part must include a fully qualified domain name or IP
* address as the host.
*
* When the subjectAltName extension contains a iPAddress, the address
* MUST be stored in the octet string in "network byte order," as
* specified in RFC 791 [RFC 791]. The least significant bit (LSB) of
* each octet is the LSB of the corresponding byte in the network
* address. For IP Version 4, as specified in RFC 791, the octet string
* MUST contain exactly four octets. For IP Version 6, as specified in
* RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
* 1883].
*/
public GeneralName(
Asn1Object name,
int tag)
{
this.obj = name;
this.tag = tag;
}
public GeneralName(
int tag,
Asn1Encodable name)
{
this.obj = name;
this.tag = tag;
}
/**
* Create a GeneralName for the given tag from the passed in string.
* <p>
* This constructor can handle:
* <ul>
* <li>rfc822Name</li>
* <li>iPAddress</li>
* <li>directoryName</li>
* <li>dNSName</li>
* <li>uniformResourceIdentifier</li>
* <li>registeredID</li>
* </ul>
* For x400Address, otherName and ediPartyName there is no common string
* format defined.
* </p><p>
* Note: A directory name can be encoded in different ways into a byte
* representation. Be aware of this if the byte representation is used for
* comparing results.
* </p>
*
* @param tag tag number
* @param name string representation of name
* @throws ArgumentException if the string encoding is not correct or
* not supported.
*/
public GeneralName(
int tag,
string name)
{
this.tag = tag;
if (tag == Rfc822Name || tag == DnsName || tag == UniformResourceIdentifier)
{
this.obj = new DerIA5String(name);
}
else if (tag == RegisteredID)
{
this.obj = new DerObjectIdentifier(name);
}
else if (tag == DirectoryName)
{
this.obj = new X509Name(name);
}
else if (tag == IPAddress)
{
byte[] enc = toGeneralNameEncoding(name);
if (enc == null)
throw new ArgumentException("IP Address is invalid", "name");
this.obj = new DerOctetString(enc);
}
else
{
throw new ArgumentException("can't process string for tag: " + tag, "tag");
}
}
public static GeneralName GetInstance(
object obj)
{
if (obj == null || obj is GeneralName)
{
return (GeneralName) obj;
}
if (obj is Asn1TaggedObject)
{
Asn1TaggedObject tagObj = (Asn1TaggedObject) obj;
int tag = tagObj.TagNo;
switch (tag)
{
case OtherName:
return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false));
case Rfc822Name:
return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false));
case DnsName:
return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false));
case X400Address:
throw new ArgumentException("unknown tag: " + tag);
case DirectoryName:
return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, true));
case EdiPartyName:
return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false));
case UniformResourceIdentifier:
return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false));
case IPAddress:
return new GeneralName(tag, Asn1OctetString.GetInstance(tagObj, false));
case RegisteredID:
return new GeneralName(tag, DerObjectIdentifier.GetInstance(tagObj, false));
}
}
throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
}
public static GeneralName GetInstance(
Asn1TaggedObject tagObj,
bool explicitly)
{
return GetInstance(Asn1TaggedObject.GetInstance(tagObj, explicitly));
}
public int TagNo
{
get { return tag; }
}
public Asn1Encodable Name
{
get { return obj; }
}
public override string ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(tag);
buf.Append(": ");
switch (tag)
{
case Rfc822Name:
case DnsName:
case UniformResourceIdentifier:
buf.Append(DerIA5String.GetInstance(obj).GetString());
break;
case DirectoryName:
buf.Append(X509Name.GetInstance(obj).ToString());
break;
default:
buf.Append(obj.ToString());
break;
}
return buf.ToString();
}
private byte[] toGeneralNameEncoding(
string ip)
{
if (NetUtils.IPAddress.IsValidIPv6WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv6(ip))
{
int slashIndex = ip.IndexOf('/');
if (slashIndex < 0)
{
byte[] addr = new byte[16];
int[] parsedIp = parseIPv6(ip);
copyInts(parsedIp, addr, 0);
return addr;
}
else
{
byte[] addr = new byte[32];
int[] parsedIp = parseIPv6(ip.Substring(0, slashIndex));
copyInts(parsedIp, addr, 0);
string mask = ip.Substring(slashIndex + 1);
if (mask.IndexOf(':') > 0)
{
parsedIp = parseIPv6(mask);
}
else
{
parsedIp = parseMask(mask);
}
copyInts(parsedIp, addr, 16);
return addr;
}
}
else if (NetUtils.IPAddress.IsValidIPv4WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv4(ip))
{
int slashIndex = ip.IndexOf('/');
if (slashIndex < 0)
{
byte[] addr = new byte[4];
parseIPv4(ip, addr, 0);
return addr;
}
else
{
byte[] addr = new byte[8];
parseIPv4(ip.Substring(0, slashIndex), addr, 0);
string mask = ip.Substring(slashIndex + 1);
if (mask.IndexOf('.') > 0)
{
parseIPv4(mask, addr, 4);
}
else
{
parseIPv4Mask(mask, addr, 4);
}
return addr;
}
}
return null;
}
private void parseIPv4Mask(string mask, byte[] addr, int offset)
{
int maskVal = Int32.Parse(mask);
for (int i = 0; i != maskVal; i++)
{
addr[(i / 8) + offset] |= (byte)(1 << (i % 8));
}
}
private void parseIPv4(string ip, byte[] addr, int offset)
{
foreach (string token in ip.Split('.', '/'))
{
addr[offset++] = (byte)Int32.Parse(token);
}
}
private int[] parseMask(string mask)
{
int[] res = new int[8];
int maskVal = Int32.Parse(mask);
for (int i = 0; i != maskVal; i++)
{
res[i / 16] |= 1 << (i % 16);
}
return res;
}
private void copyInts(int[] parsedIp, byte[] addr, int offSet)
{
for (int i = 0; i != parsedIp.Length; i++)
{
addr[(i * 2) + offSet] = (byte)(parsedIp[i] >> 8);
addr[(i * 2 + 1) + offSet] = (byte)parsedIp[i];
}
}
private int[] parseIPv6(string ip)
{
if (ip.StartsWith("::"))
{
ip = ip.Substring(1);
}
else if (ip.EndsWith("::"))
{
ip = ip.Substring(0, ip.Length - 1);
}
IEnumerator sEnum = ip.Split(':').GetEnumerator();
int index = 0;
int[] val = new int[8];
int doubleColon = -1;
while (sEnum.MoveNext())
{
string e = (string) sEnum.Current;
if (e.Length == 0)
{
doubleColon = index;
val[index++] = 0;
}
else
{
if (e.IndexOf('.') < 0)
{
val[index++] = Int32.Parse(e, NumberStyles.AllowHexSpecifier);
}
else
{
string[] tokens = e.Split('.');
val[index++] = (Int32.Parse(tokens[0]) << 8) | Int32.Parse(tokens[1]);
val[index++] = (Int32.Parse(tokens[2]) << 8) | Int32.Parse(tokens[3]);
}
}
}
if (index != val.Length)
{
Array.Copy(val, doubleColon, val, val.Length - (index - doubleColon), index - doubleColon);
for (int i = doubleColon; i != val.Length - (index - doubleColon); i++)
{
val[i] = 0;
}
}
return val;
}
public override Asn1Object ToAsn1Object()
{
// Explicitly tagged if DirectoryName
return new DerTaggedObject(tag == DirectoryName, tag, obj);
}
}
}
using System;
using System.Collections;
using System.Globalization;
using System.Text;
using NetUtils = Org.BouncyCastle.Utilities.Net;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* The GeneralName object.
* <pre>
* GeneralName ::= CHOICE {
* otherName [0] OtherName,
* rfc822Name [1] IA5String,
* dNSName [2] IA5String,
* x400Address [3] ORAddress,
* directoryName [4] Name,
* ediPartyName [5] EDIPartyName,
* uniformResourceIdentifier [6] IA5String,
* iPAddress [7] OCTET STRING,
* registeredID [8] OBJECT IDENTIFIER}
*
* OtherName ::= Sequence {
* type-id OBJECT IDENTIFIER,
* value [0] EXPLICIT ANY DEFINED BY type-id }
*
* EDIPartyName ::= Sequence {
* nameAssigner [0] DirectoryString OPTIONAL,
* partyName [1] DirectoryString }
* </pre>
*/
public class GeneralName
: Asn1Encodable, IAsn1Choice
{
public const int OtherName = 0;
public const int Rfc822Name = 1;
public const int DnsName = 2;
public const int X400Address = 3;
public const int DirectoryName = 4;
public const int EdiPartyName = 5;
public const int UniformResourceIdentifier = 6;
public const int IPAddress = 7;
public const int RegisteredID = 8;
internal readonly Asn1Encodable obj;
internal readonly int tag;
public GeneralName(
X509Name directoryName)
{
this.obj = directoryName;
this.tag = 4;
}
/**
* When the subjectAltName extension contains an Internet mail address,
* the address MUST be included as an rfc822Name. The format of an
* rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
*
* When the subjectAltName extension contains a domain name service
* label, the domain name MUST be stored in the dNSName (an IA5String).
* The name MUST be in the "preferred name syntax," as specified by RFC
* 1034 [RFC 1034].
*
* When the subjectAltName extension contains a URI, the name MUST be
* stored in the uniformResourceIdentifier (an IA5String). The name MUST
* be a non-relative URL, and MUST follow the URL syntax and encoding
* rules specified in [RFC 1738]. The name must include both a scheme
* (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
* specific-part must include a fully qualified domain name or IP
* address as the host.
*
* When the subjectAltName extension contains a iPAddress, the address
* MUST be stored in the octet string in "network byte order," as
* specified in RFC 791 [RFC 791]. The least significant bit (LSB) of
* each octet is the LSB of the corresponding byte in the network
* address. For IP Version 4, as specified in RFC 791, the octet string
* MUST contain exactly four octets. For IP Version 6, as specified in
* RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
* 1883].
*/
public GeneralName(
Asn1Object name,
int tag)
{
this.obj = name;
this.tag = tag;
}
public GeneralName(
int tag,
Asn1Encodable name)
{
this.obj = name;
this.tag = tag;
}
/**
* Create a GeneralName for the given tag from the passed in string.
* <p>
* This constructor can handle:
* <ul>
* <li>rfc822Name</li>
* <li>iPAddress</li>
* <li>directoryName</li>
* <li>dNSName</li>
* <li>uniformResourceIdentifier</li>
* <li>registeredID</li>
* </ul>
* For x400Address, otherName and ediPartyName there is no common string
* format defined.
* </p><p>
* Note: A directory name can be encoded in different ways into a byte
* representation. Be aware of this if the byte representation is used for
* comparing results.
* </p>
*
* @param tag tag number
* @param name string representation of name
* @throws ArgumentException if the string encoding is not correct or
* not supported.
*/
public GeneralName(
int tag,
string name)
{
this.tag = tag;
if (tag == Rfc822Name || tag == DnsName || tag == UniformResourceIdentifier)
{
this.obj = new DerIA5String(name);
}
else if (tag == RegisteredID)
{
this.obj = new DerObjectIdentifier(name);
}
else if (tag == DirectoryName)
{
this.obj = new X509Name(name);
}
else if (tag == IPAddress)
{
byte[] enc = toGeneralNameEncoding(name);
if (enc == null)
throw new ArgumentException("IP Address is invalid", "name");
this.obj = new DerOctetString(enc);
}
else
{
throw new ArgumentException("can't process string for tag: " + tag, "tag");
}
}
public static GeneralName GetInstance(
object obj)
{
if (obj == null || obj is GeneralName)
{
return (GeneralName) obj;
}
if (obj is Asn1TaggedObject)
{
Asn1TaggedObject tagObj = (Asn1TaggedObject) obj;
int tag = tagObj.TagNo;
switch (tag)
{
case OtherName:
return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false));
case Rfc822Name:
return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false));
case DnsName:
return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false));
case X400Address:
throw new ArgumentException("unknown tag: " + tag);
case DirectoryName:
return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, true));
case EdiPartyName:
return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false));
case UniformResourceIdentifier:
return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false));
case IPAddress:
return new GeneralName(tag, Asn1OctetString.GetInstance(tagObj, false));
case RegisteredID:
return new GeneralName(tag, DerObjectIdentifier.GetInstance(tagObj, false));
}
}
throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
}
public static GeneralName GetInstance(
Asn1TaggedObject tagObj,
bool explicitly)
{
return GetInstance(Asn1TaggedObject.GetInstance(tagObj, true));
}
public int TagNo
{
get { return tag; }
}
public Asn1Encodable Name
{
get { return obj; }
}
public override string ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(tag);
buf.Append(": ");
switch (tag)
{
case Rfc822Name:
case DnsName:
case UniformResourceIdentifier:
buf.Append(DerIA5String.GetInstance(obj).GetString());
break;
case DirectoryName:
buf.Append(X509Name.GetInstance(obj).ToString());
break;
default:
buf.Append(obj.ToString());
break;
}
return buf.ToString();
}
private byte[] toGeneralNameEncoding(
string ip)
{
if (NetUtils.IPAddress.IsValidIPv6WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv6(ip))
{
int slashIndex = ip.IndexOf('/');
if (slashIndex < 0)
{
byte[] addr = new byte[16];
int[] parsedIp = parseIPv6(ip);
copyInts(parsedIp, addr, 0);
return addr;
}
else
{
byte[] addr = new byte[32];
int[] parsedIp = parseIPv6(ip.Substring(0, slashIndex));
copyInts(parsedIp, addr, 0);
string mask = ip.Substring(slashIndex + 1);
if (mask.IndexOf(':') > 0)
{
parsedIp = parseIPv6(mask);
}
else
{
parsedIp = parseMask(mask);
}
copyInts(parsedIp, addr, 16);
return addr;
}
}
else if (NetUtils.IPAddress.IsValidIPv4WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv4(ip))
{
int slashIndex = ip.IndexOf('/');
if (slashIndex < 0)
{
byte[] addr = new byte[4];
parseIPv4(ip, addr, 0);
return addr;
}
else
{
byte[] addr = new byte[8];
parseIPv4(ip.Substring(0, slashIndex), addr, 0);
string mask = ip.Substring(slashIndex + 1);
if (mask.IndexOf('.') > 0)
{
parseIPv4(mask, addr, 4);
}
else
{
parseIPv4Mask(mask, addr, 4);
}
return addr;
}
}
return null;
}
private void parseIPv4Mask(string mask, byte[] addr, int offset)
{
int maskVal = Int32.Parse(mask);
for (int i = 0; i != maskVal; i++)
{
addr[(i / 8) + offset] |= (byte)(1 << (i % 8));
}
}
private void parseIPv4(string ip, byte[] addr, int offset)
{
foreach (string token in ip.Split('.', '/'))
{
addr[offset++] = (byte)Int32.Parse(token);
}
}
private int[] parseMask(string mask)
{
int[] res = new int[8];
int maskVal = Int32.Parse(mask);
for (int i = 0; i != maskVal; i++)
{
res[i / 16] |= 1 << (i % 16);
}
return res;
}
private void copyInts(int[] parsedIp, byte[] addr, int offSet)
{
for (int i = 0; i != parsedIp.Length; i++)
{
addr[(i * 2) + offSet] = (byte)(parsedIp[i] >> 8);
addr[(i * 2 + 1) + offSet] = (byte)parsedIp[i];
}
}
private int[] parseIPv6(string ip)
{
if (ip.StartsWith("::"))
{
ip = ip.Substring(1);
}
else if (ip.EndsWith("::"))
{
ip = ip.Substring(0, ip.Length - 1);
}
IEnumerator sEnum = ip.Split(':').GetEnumerator();
int index = 0;
int[] val = new int[8];
int doubleColon = -1;
while (sEnum.MoveNext())
{
string e = (string) sEnum.Current;
if (e.Length == 0)
{
doubleColon = index;
val[index++] = 0;
}
else
{
if (e.IndexOf('.') < 0)
{
val[index++] = Int32.Parse(e, NumberStyles.AllowHexSpecifier);
}
else
{
string[] tokens = e.Split('.');
val[index++] = (Int32.Parse(tokens[0]) << 8) | Int32.Parse(tokens[1]);
val[index++] = (Int32.Parse(tokens[2]) << 8) | Int32.Parse(tokens[3]);
}
}
}
if (index != val.Length)
{
Array.Copy(val, doubleColon, val, val.Length - (index - doubleColon), index - doubleColon);
for (int i = doubleColon; i != val.Length - (index - doubleColon); i++)
{
val[i] = 0;
}
}
return val;
}
public override Asn1Object ToAsn1Object()
{
// Explicitly tagged if DirectoryName
return new DerTaggedObject(tag == DirectoryName, tag, obj);
}
}
}

View File

@ -1,91 +1,89 @@
using System;
using System.Text;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.X509
{
public class GeneralNames
: Asn1Encodable
{
private readonly Asn1Sequence seq;
public static GeneralNames GetInstance(
object obj)
{
if (obj == null || obj is GeneralNames)
{
return (GeneralNames) obj;
}
if (obj is Asn1Sequence)
{
return new GeneralNames((Asn1Sequence) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static GeneralNames GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
}
/// <summary>Construct a GeneralNames object containing one GeneralName.</summary>
/// <param name="name">The name to be contained.</param>
public GeneralNames(
GeneralName name)
{
this.seq = new DerSequence(name);
}
private GeneralNames(
Asn1Sequence seq)
{
this.seq = seq;
}
public GeneralName[] GetNames()
{
GeneralName[] names = new GeneralName[seq.Count];
for (int i = 0; i != seq.Count; i++)
{
names[i] = GeneralName.GetInstance(seq[i]);
}
return names;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* GeneralNames ::= Sequence SIZE {1..MAX} OF GeneralName
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return seq;
}
public override string ToString()
{
StringBuilder buf = new StringBuilder();
string sep = Platform.NewLine;
GeneralName[] names = GetNames();
buf.Append("GeneralNames:");
buf.Append(sep);
for (int i = 0; i != names.Length; i++)
{
buf.Append(" ");
buf.Append(names[i]);
buf.Append(sep);
}
return buf.ToString();
}
}
}
using System;
using System.Text;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.X509
{
public class GeneralNames
: Asn1Encodable
{
private readonly GeneralName[] names;
public static GeneralNames GetInstance(
object obj)
{
if (obj == null || obj is GeneralNames)
{
return (GeneralNames) obj;
}
if (obj is Asn1Sequence)
{
return new GeneralNames((Asn1Sequence) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public static GeneralNames GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
}
/// <summary>Construct a GeneralNames object containing one GeneralName.</summary>
/// <param name="name">The name to be contained.</param>
public GeneralNames(
GeneralName name)
{
names = new GeneralName[]{ name };
}
private GeneralNames(
Asn1Sequence seq)
{
this.names = new GeneralName[seq.Count];
for (int i = 0; i != seq.Count; i++)
{
names[i] = GeneralName.GetInstance(seq[i]);
}
}
public GeneralName[] GetNames()
{
return (GeneralName[]) names.Clone();
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* GeneralNames ::= Sequence SIZE {1..MAX} OF GeneralName
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return new DerSequence(names);
}
public override string ToString()
{
StringBuilder buf = new StringBuilder();
string sep = Platform.NewLine;
buf.Append("GeneralNames:");
buf.Append(sep);
foreach (GeneralName name in names)
{
buf.Append(" ");
buf.Append(name);
buf.Append(sep);
}
return buf.ToString();
}
}
}

View File

@ -1,234 +1,234 @@
using System;
using System.Text;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* Implementation of the RoleSyntax object as specified by the RFC3281.
*
* <pre>
* RoleSyntax ::= SEQUENCE {
* roleAuthority [0] GeneralNames OPTIONAL,
* roleName [1] GeneralName
* }
* </pre>
*/
public class RoleSyntax
: Asn1Encodable
{
private readonly GeneralNames roleAuthority;
private readonly GeneralName roleName;
/**
* RoleSyntax factory method.
* @param obj the object used to construct an instance of <code>
* RoleSyntax</code>. It must be an instance of <code>RoleSyntax
* </code> or <code>Asn1Sequence</code>.
* @return the instance of <code>RoleSyntax</code> built from the
* supplied object.
* @throws java.lang.ArgumentException if the object passed
* to the factory is not an instance of <code>RoleSyntax</code> or
* <code>Asn1Sequence</code>.
*/
public static RoleSyntax GetInstance(
object obj)
{
if (obj == null || obj is RoleSyntax)
{
return (RoleSyntax) obj;
}
if (obj is Asn1Sequence)
{
return new RoleSyntax((Asn1Sequence) obj);
}
throw new ArgumentException("unknown object in 'RoleSyntax' factory: " + obj.GetType().Name, "obj");
}
/**
* Constructor.
* @param roleAuthority the role authority of this RoleSyntax.
* @param roleName the role name of this RoleSyntax.
*/
public RoleSyntax(
GeneralNames roleAuthority,
GeneralName roleName)
{
if (roleName == null
|| roleName.TagNo != GeneralName.UniformResourceIdentifier
|| ((IAsn1String) roleName.Name).GetString().Equals(""))
{
throw new ArgumentException("the role name MUST be non empty and MUST " +
"use the URI option of GeneralName");
}
this.roleAuthority = roleAuthority;
this.roleName = roleName;
}
/**
* Constructor. Invoking this constructor is the same as invoking
* <code>new RoleSyntax(null, roleName)</code>.
* @param roleName the role name of this RoleSyntax.
*/
public RoleSyntax(
GeneralName roleName)
: this(null, roleName)
{
}
/**
* Utility constructor. Takes a <code>string</code> argument representing
* the role name, builds a <code>GeneralName</code> to hold the role name
* and calls the constructor that takes a <code>GeneralName</code>.
* @param roleName
*/
public RoleSyntax(
string roleName)
: this(new GeneralName(GeneralName.UniformResourceIdentifier,
(roleName == null)? "": roleName))
{
}
/**
* Constructor that builds an instance of <code>RoleSyntax</code> by
* extracting the encoded elements from the <code>Asn1Sequence</code>
* object supplied.
* @param seq an instance of <code>Asn1Sequence</code> that holds
* the encoded elements used to build this <code>RoleSyntax</code>.
*/
private RoleSyntax(
Asn1Sequence seq)
{
if (seq.Count < 1 || seq.Count > 2)
{
throw new ArgumentException("Bad sequence size: " + seq.Count);
}
for (int i = 0; i != seq.Count; i++)
{
Asn1TaggedObject taggedObject = Asn1TaggedObject.GetInstance(seq[i]);
switch (taggedObject.TagNo)
{
case 0:
roleAuthority = GeneralNames.GetInstance(taggedObject, false);
break;
case 1:
roleName = GeneralName.GetInstance(taggedObject, false);
break;
default:
throw new ArgumentException("Unknown tag in RoleSyntax");
}
}
}
/**
* Gets the role authority of this RoleSyntax.
* @return an instance of <code>GeneralNames</code> holding the
* role authority of this RoleSyntax.
*/
public GeneralNames RoleAuthority
{
get { return this.roleAuthority; }
}
/**
* Gets the role name of this RoleSyntax.
* @return an instance of <code>GeneralName</code> holding the
* role name of this RoleSyntax.
*/
public GeneralName RoleName
{
get { return this.roleName; }
}
/**
* Gets the role name as a <code>java.lang.string</code> object.
* @return the role name of this RoleSyntax represented as a
* <code>string</code> object.
*/
public string GetRoleNameAsString()
{
return ((IAsn1String) this.roleName.Name).GetString();
}
/**
* Gets the role authority as a <code>string[]</code> object.
* @return the role authority of this RoleSyntax represented as a
* <code>string[]</code> array.
*/
public string[] GetRoleAuthorityAsString()
{
if (roleAuthority == null)
{
return new string[0];
}
GeneralName[] names = roleAuthority.GetNames();
string[] namesString = new string[names.Length];
for(int i = 0; i < names.Length; i++)
{
Asn1Encodable asn1Value = names[i].Name;
if (asn1Value is IAsn1String)
{
namesString[i] = ((IAsn1String) asn1Value).GetString();
}
else
{
namesString[i] = asn1Value.ToString();
}
}
return namesString;
}
/**
* Implementation of the method <code>ToAsn1Object</code> as
* required by the superclass <code>ASN1Encodable</code>.
*
* <pre>
* RoleSyntax ::= SEQUENCE {
* roleAuthority [0] GeneralNames OPTIONAL,
* roleName [1] GeneralName
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector();
if (this.roleAuthority != null)
{
v.Add(new DerTaggedObject(false, 0, roleAuthority));
}
v.Add(new DerTaggedObject(false, 1, roleName));
return new DerSequence(v);
}
public override string ToString()
{
StringBuilder buff = new StringBuilder("Name: " + this.GetRoleNameAsString() +
" - Auth: ");
if (this.roleAuthority == null || roleAuthority.GetNames().Length == 0)
{
buff.Append("N/A");
}
else
{
string[] names = this.GetRoleAuthorityAsString();
buff.Append('[').Append(names[0]);
for(int i = 1; i < names.Length; i++)
{
buff.Append(", ").Append(names[i]);
}
buff.Append(']');
}
return buff.ToString();
}
}
}
using System;
using System.Text;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* Implementation of the RoleSyntax object as specified by the RFC3281.
*
* <pre>
* RoleSyntax ::= SEQUENCE {
* roleAuthority [0] GeneralNames OPTIONAL,
* roleName [1] GeneralName
* }
* </pre>
*/
public class RoleSyntax
: Asn1Encodable
{
private readonly GeneralNames roleAuthority;
private readonly GeneralName roleName;
/**
* RoleSyntax factory method.
* @param obj the object used to construct an instance of <code>
* RoleSyntax</code>. It must be an instance of <code>RoleSyntax
* </code> or <code>Asn1Sequence</code>.
* @return the instance of <code>RoleSyntax</code> built from the
* supplied object.
* @throws java.lang.ArgumentException if the object passed
* to the factory is not an instance of <code>RoleSyntax</code> or
* <code>Asn1Sequence</code>.
*/
public static RoleSyntax GetInstance(
object obj)
{
if (obj == null || obj is RoleSyntax)
{
return (RoleSyntax) obj;
}
if (obj is Asn1Sequence)
{
return new RoleSyntax((Asn1Sequence) obj);
}
throw new ArgumentException("unknown object in 'RoleSyntax' factory: " + obj.GetType().Name, "obj");
}
/**
* Constructor.
* @param roleAuthority the role authority of this RoleSyntax.
* @param roleName the role name of this RoleSyntax.
*/
public RoleSyntax(
GeneralNames roleAuthority,
GeneralName roleName)
{
if (roleName == null
|| roleName.TagNo != GeneralName.UniformResourceIdentifier
|| ((IAsn1String) roleName.Name).GetString().Equals(""))
{
throw new ArgumentException("the role name MUST be non empty and MUST " +
"use the URI option of GeneralName");
}
this.roleAuthority = roleAuthority;
this.roleName = roleName;
}
/**
* Constructor. Invoking this constructor is the same as invoking
* <code>new RoleSyntax(null, roleName)</code>.
* @param roleName the role name of this RoleSyntax.
*/
public RoleSyntax(
GeneralName roleName)
: this(null, roleName)
{
}
/**
* Utility constructor. Takes a <code>string</code> argument representing
* the role name, builds a <code>GeneralName</code> to hold the role name
* and calls the constructor that takes a <code>GeneralName</code>.
* @param roleName
*/
public RoleSyntax(
string roleName)
: this(new GeneralName(GeneralName.UniformResourceIdentifier,
(roleName == null)? "": roleName))
{
}
/**
* Constructor that builds an instance of <code>RoleSyntax</code> by
* extracting the encoded elements from the <code>Asn1Sequence</code>
* object supplied.
* @param seq an instance of <code>Asn1Sequence</code> that holds
* the encoded elements used to build this <code>RoleSyntax</code>.
*/
private RoleSyntax(
Asn1Sequence seq)
{
if (seq.Count < 1 || seq.Count > 2)
{
throw new ArgumentException("Bad sequence size: " + seq.Count);
}
for (int i = 0; i != seq.Count; i++)
{
Asn1TaggedObject taggedObject = Asn1TaggedObject.GetInstance(seq[i]);
switch (taggedObject.TagNo)
{
case 0:
roleAuthority = GeneralNames.GetInstance(taggedObject, false);
break;
case 1:
roleName = GeneralName.GetInstance(taggedObject, true);
break;
default:
throw new ArgumentException("Unknown tag in RoleSyntax");
}
}
}
/**
* Gets the role authority of this RoleSyntax.
* @return an instance of <code>GeneralNames</code> holding the
* role authority of this RoleSyntax.
*/
public GeneralNames RoleAuthority
{
get { return this.roleAuthority; }
}
/**
* Gets the role name of this RoleSyntax.
* @return an instance of <code>GeneralName</code> holding the
* role name of this RoleSyntax.
*/
public GeneralName RoleName
{
get { return this.roleName; }
}
/**
* Gets the role name as a <code>java.lang.string</code> object.
* @return the role name of this RoleSyntax represented as a
* <code>string</code> object.
*/
public string GetRoleNameAsString()
{
return ((IAsn1String) this.roleName.Name).GetString();
}
/**
* Gets the role authority as a <code>string[]</code> object.
* @return the role authority of this RoleSyntax represented as a
* <code>string[]</code> array.
*/
public string[] GetRoleAuthorityAsString()
{
if (roleAuthority == null)
{
return new string[0];
}
GeneralName[] names = roleAuthority.GetNames();
string[] namesString = new string[names.Length];
for(int i = 0; i < names.Length; i++)
{
Asn1Encodable asn1Value = names[i].Name;
if (asn1Value is IAsn1String)
{
namesString[i] = ((IAsn1String) asn1Value).GetString();
}
else
{
namesString[i] = asn1Value.ToString();
}
}
return namesString;
}
/**
* Implementation of the method <code>ToAsn1Object</code> as
* required by the superclass <code>ASN1Encodable</code>.
*
* <pre>
* RoleSyntax ::= SEQUENCE {
* roleAuthority [0] GeneralNames OPTIONAL,
* roleName [1] GeneralName
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector();
if (this.roleAuthority != null)
{
v.Add(new DerTaggedObject(false, 0, roleAuthority));
}
v.Add(new DerTaggedObject(true, 1, roleName));
return new DerSequence(v);
}
public override string ToString()
{
StringBuilder buff = new StringBuilder("Name: " + this.GetRoleNameAsString() +
" - Auth: ");
if (this.roleAuthority == null || roleAuthority.GetNames().Length == 0)
{
buff.Append("N/A");
}
else
{
string[] names = this.GetRoleAuthorityAsString();
buff.Append('[').Append(names[0]);
for(int i = 1; i < names.Length; i++)
{
buff.Append(", ").Append(names[i]);
}
buff.Append(']');
}
return buff.ToString();
}
}
}

View File

@ -1,140 +1,139 @@
using System;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* Target structure used in target information extension for attribute
* certificates from RFC 3281.
*
* <pre>
* Target ::= CHOICE {
* targetName [0] GeneralName,
* targetGroup [1] GeneralName,
* targetCert [2] TargetCert
* }
* </pre>
*
* <p>
* The targetCert field is currently not supported and must not be used
* according to RFC 3281.</p>
*/
public class Target
: Asn1Encodable
//, ASN1Choice
{
public enum Choice
{
Name = 0,
Group = 1
};
private readonly GeneralName targetName;
private readonly GeneralName targetGroup;
/**
* Creates an instance of a Target from the given object.
* <p>
* <code>obj</code> can be a Target or a {@link Asn1TaggedObject}</p>
*
* @param obj The object.
* @return A Target instance.
* @throws ArgumentException if the given object cannot be
* interpreted as Target.
*/
public static Target GetInstance(
object obj)
{
if (obj is Target)
{
return (Target) obj;
}
if (obj is Asn1TaggedObject)
{
return new Target((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
/**
* Constructor from Asn1TaggedObject.
*
* @param tagObj The tagged object.
* @throws ArgumentException if the encoding is wrong.
*/
private Target(
Asn1TaggedObject tagObj)
{
switch ((Choice) tagObj.TagNo)
{
case Choice.Name: // GeneralName is already a choice so explicit
targetName = GeneralName.GetInstance(tagObj, true);
break;
case Choice.Group:
targetGroup = GeneralName.GetInstance(tagObj, true);
break;
default:
throw new ArgumentException("unknown tag: " + tagObj.TagNo);
}
}
/**
* Constructor from given details.
* <p>
* Exactly one of the parameters must be not <code>null</code>.</p>
*
* @param type the choice type to apply to the name.
* @param name the general name.
* @throws ArgumentException if type is invalid.
*/
public Target(
Choice type,
GeneralName name)
: this(new DerTaggedObject((int) type, name))
{
}
/**
* @return Returns the targetGroup.
*/
public virtual GeneralName TargetGroup
{
get { return targetGroup; }
}
/**
* @return Returns the targetName.
*/
public virtual GeneralName TargetName
{
get { return targetName; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
*
* Returns:
*
* <pre>
* Target ::= CHOICE {
* targetName [0] GeneralName,
* targetGroup [1] GeneralName,
* targetCert [2] TargetCert
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
// GeneralName is a choice already so most be explicitly tagged
if (targetName != null)
{
return new DerTaggedObject(true, 0, targetName);
}
return new DerTaggedObject(true, 1, targetGroup);
}
}
}
using System;
namespace Org.BouncyCastle.Asn1.X509
{
/**
* Target structure used in target information extension for attribute
* certificates from RFC 3281.
*
* <pre>
* Target ::= CHOICE {
* targetName [0] GeneralName,
* targetGroup [1] GeneralName,
* targetCert [2] TargetCert
* }
* </pre>
*
* <p>
* The targetCert field is currently not supported and must not be used
* according to RFC 3281.</p>
*/
public class Target
: Asn1Encodable, IAsn1Choice
{
public enum Choice
{
Name = 0,
Group = 1
};
private readonly GeneralName targetName;
private readonly GeneralName targetGroup;
/**
* Creates an instance of a Target from the given object.
* <p>
* <code>obj</code> can be a Target or a {@link Asn1TaggedObject}</p>
*
* @param obj The object.
* @return A Target instance.
* @throws ArgumentException if the given object cannot be
* interpreted as Target.
*/
public static Target GetInstance(
object obj)
{
if (obj is Target)
{
return (Target) obj;
}
if (obj is Asn1TaggedObject)
{
return new Target((Asn1TaggedObject) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
/**
* Constructor from Asn1TaggedObject.
*
* @param tagObj The tagged object.
* @throws ArgumentException if the encoding is wrong.
*/
private Target(
Asn1TaggedObject tagObj)
{
switch ((Choice) tagObj.TagNo)
{
case Choice.Name: // GeneralName is already a choice so explicit
targetName = GeneralName.GetInstance(tagObj, true);
break;
case Choice.Group:
targetGroup = GeneralName.GetInstance(tagObj, true);
break;
default:
throw new ArgumentException("unknown tag: " + tagObj.TagNo);
}
}
/**
* Constructor from given details.
* <p>
* Exactly one of the parameters must be not <code>null</code>.</p>
*
* @param type the choice type to apply to the name.
* @param name the general name.
* @throws ArgumentException if type is invalid.
*/
public Target(
Choice type,
GeneralName name)
: this(new DerTaggedObject((int) type, name))
{
}
/**
* @return Returns the targetGroup.
*/
public virtual GeneralName TargetGroup
{
get { return targetGroup; }
}
/**
* @return Returns the targetName.
*/
public virtual GeneralName TargetName
{
get { return targetName; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
*
* Returns:
*
* <pre>
* Target ::= CHOICE {
* targetName [0] GeneralName,
* targetGroup [1] GeneralName,
* targetCert [2] TargetCert
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
// GeneralName is a choice already so most be explicitly tagged
if (targetName != null)
{
return new DerTaggedObject(true, 0, targetName);
}
return new DerTaggedObject(true, 1, targetGroup);
}
}
}

View File

@ -1,126 +1,126 @@
using System;
namespace Org.BouncyCastle.Asn1.X509
{
public class Time
: Asn1Encodable
{
internal Asn1Object time;
public static Time GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(obj.GetObject());
}
public Time(
Asn1Object time)
{
if (time == null)
throw new ArgumentNullException("time");
if (!(time is DerUtcTime) && !(time is DerGeneralizedTime))
{
throw new ArgumentException("unknown object passed to Time");
}
this.time = time;
}
/**
* creates a time object from a given date - if the date is between 1950
* and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime
* is used.
*/
public Time(
DateTime date)
{
string d = date.ToString("yyyyMMddHHmmss") + "Z";
int year = Int32.Parse(d.Substring(0, 4));
if (year < 1950 || year > 2049)
{
time = new DerGeneralizedTime(d);
}
else
{
time = new DerUtcTime(d.Substring(2));
}
}
public static Time GetInstance(
object obj)
{
if (obj is Time)
{
return (Time) obj;
}
if (obj is DerUtcTime)
{
return new Time((DerUtcTime) obj);
}
if (obj is DerGeneralizedTime)
{
return new Time((DerGeneralizedTime) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public string GetTime()
{
if (time is DerUtcTime)
{
return ((DerUtcTime) time).AdjustedTimeString;
}
return ((DerGeneralizedTime) time).GetTime();
}
/// <summary>
/// Return our time as DateTime.
/// </summary>
/// <returns>A date time.</returns>
public DateTime ToDateTime()
{
try
{
if (time is DerUtcTime)
{
return ((DerUtcTime)time).ToAdjustedDateTime();
}
else
{
return ((DerGeneralizedTime)time).ToDateTime();
}
}
catch (FormatException e)
{
// this should never happen
throw new InvalidOperationException("invalid date string: " + e.Message);
}
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* Time ::= CHOICE {
* utcTime UTCTime,
* generalTime GeneralizedTime }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return time;
}
public override string ToString()
{
return GetTime();
}
}
}
using System;
namespace Org.BouncyCastle.Asn1.X509
{
public class Time
: Asn1Encodable, IAsn1Choice
{
internal Asn1Object time;
public static Time GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
return GetInstance(obj.GetObject());
}
public Time(
Asn1Object time)
{
if (time == null)
throw new ArgumentNullException("time");
if (!(time is DerUtcTime) && !(time is DerGeneralizedTime))
{
throw new ArgumentException("unknown object passed to Time");
}
this.time = time;
}
/**
* creates a time object from a given date - if the date is between 1950
* and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime
* is used.
*/
public Time(
DateTime date)
{
string d = date.ToString("yyyyMMddHHmmss") + "Z";
int year = Int32.Parse(d.Substring(0, 4));
if (year < 1950 || year > 2049)
{
time = new DerGeneralizedTime(d);
}
else
{
time = new DerUtcTime(d.Substring(2));
}
}
public static Time GetInstance(
object obj)
{
if (obj is Time)
{
return (Time) obj;
}
if (obj is DerUtcTime)
{
return new Time((DerUtcTime) obj);
}
if (obj is DerGeneralizedTime)
{
return new Time((DerGeneralizedTime) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
public string GetTime()
{
if (time is DerUtcTime)
{
return ((DerUtcTime) time).AdjustedTimeString;
}
return ((DerGeneralizedTime) time).GetTime();
}
/// <summary>
/// Return our time as DateTime.
/// </summary>
/// <returns>A date time.</returns>
public DateTime ToDateTime()
{
try
{
if (time is DerUtcTime)
{
return ((DerUtcTime)time).ToAdjustedDateTime();
}
else
{
return ((DerGeneralizedTime)time).ToDateTime();
}
}
catch (FormatException e)
{
// this should never happen
throw new InvalidOperationException("invalid date string: " + e.Message);
}
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* Time ::= CHOICE {
* utcTime UTCTime,
* generalTime GeneralizedTime }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return time;
}
public override string ToString()
{
return GetTime();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +1,84 @@
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X509.Qualified
{
/**
* The Iso4217CurrencyCode object.
* <pre>
* Iso4217CurrencyCode ::= CHOICE {
* alphabetic PrintableString (SIZE 3), --Recommended
* numeric INTEGER (1..999) }
* -- Alphabetic or numeric currency code as defined in ISO 4217
* -- It is recommended that the Alphabetic form is used
* </pre>
*/
public class Iso4217CurrencyCode
: Asn1Encodable
{
internal const int AlphabeticMaxSize = 3;
internal const int NumericMinSize = 1;
internal const int NumericMaxSize = 999;
internal Asn1Encodable obj;
// internal int numeric;
public static Iso4217CurrencyCode GetInstance(
object obj)
{
if (obj == null || obj is Iso4217CurrencyCode)
{
return (Iso4217CurrencyCode) obj;
}
if (obj is DerInteger)
{
DerInteger numericobj = DerInteger.GetInstance(obj);
int numeric = numericobj.Value.IntValue;
return new Iso4217CurrencyCode(numeric);
}
if (obj is DerPrintableString)
{
DerPrintableString alphabetic = DerPrintableString.GetInstance(obj);
return new Iso4217CurrencyCode(alphabetic.GetString());
}
throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
}
public Iso4217CurrencyCode(
int numeric)
{
if (numeric > NumericMaxSize || numeric < NumericMinSize)
{
throw new ArgumentException("wrong size in numeric code : not in (" +NumericMinSize +".."+ NumericMaxSize +")");
}
obj = new DerInteger(numeric);
}
public Iso4217CurrencyCode(
string alphabetic)
{
if (alphabetic.Length > AlphabeticMaxSize)
{
throw new ArgumentException("wrong size in alphabetic code : max size is " + AlphabeticMaxSize);
}
obj = new DerPrintableString(alphabetic);
}
public bool IsAlphabetic { get { return obj is DerPrintableString; } }
public string Alphabetic { get { return ((DerPrintableString) obj).GetString(); } }
public int Numeric { get { return ((DerInteger)obj).Value.IntValue; } }
public override Asn1Object ToAsn1Object()
{
return obj.ToAsn1Object();
}
}
}
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X509.Qualified
{
/**
* The Iso4217CurrencyCode object.
* <pre>
* Iso4217CurrencyCode ::= CHOICE {
* alphabetic PrintableString (SIZE 3), --Recommended
* numeric INTEGER (1..999) }
* -- Alphabetic or numeric currency code as defined in ISO 4217
* -- It is recommended that the Alphabetic form is used
* </pre>
*/
public class Iso4217CurrencyCode
: Asn1Encodable, IAsn1Choice
{
internal const int AlphabeticMaxSize = 3;
internal const int NumericMinSize = 1;
internal const int NumericMaxSize = 999;
internal Asn1Encodable obj;
// internal int numeric;
public static Iso4217CurrencyCode GetInstance(
object obj)
{
if (obj == null || obj is Iso4217CurrencyCode)
{
return (Iso4217CurrencyCode) obj;
}
if (obj is DerInteger)
{
DerInteger numericobj = DerInteger.GetInstance(obj);
int numeric = numericobj.Value.IntValue;
return new Iso4217CurrencyCode(numeric);
}
if (obj is DerPrintableString)
{
DerPrintableString alphabetic = DerPrintableString.GetInstance(obj);
return new Iso4217CurrencyCode(alphabetic.GetString());
}
throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
}
public Iso4217CurrencyCode(
int numeric)
{
if (numeric > NumericMaxSize || numeric < NumericMinSize)
{
throw new ArgumentException("wrong size in numeric code : not in (" +NumericMinSize +".."+ NumericMaxSize +")");
}
obj = new DerInteger(numeric);
}
public Iso4217CurrencyCode(
string alphabetic)
{
if (alphabetic.Length > AlphabeticMaxSize)
{
throw new ArgumentException("wrong size in alphabetic code : max size is " + AlphabeticMaxSize);
}
obj = new DerPrintableString(alphabetic);
}
public bool IsAlphabetic { get { return obj is DerPrintableString; } }
public string Alphabetic { get { return ((DerPrintableString) obj).GetString(); } }
public int Numeric { get { return ((DerInteger)obj).Value.IntValue; } }
public override Asn1Object ToAsn1Object()
{
return obj.ToAsn1Object();
}
}
}

View File

@ -1,91 +1,91 @@
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X509.Qualified
{
/**
* The TypeOfBiometricData object.
* <pre>
* TypeOfBiometricData ::= CHOICE {
* predefinedBiometricType PredefinedBiometricType,
* biometricDataOid OBJECT IDENTIFIER }
*
* PredefinedBiometricType ::= INTEGER {
* picture(0),handwritten-signature(1)}
* (picture|handwritten-signature)
* </pre>
*/
public class TypeOfBiometricData
: Asn1Encodable
{
public const int Picture = 0;
public const int HandwrittenSignature = 1;
internal Asn1Encodable obj;
public static TypeOfBiometricData GetInstance(
object obj)
{
if (obj == null || obj is TypeOfBiometricData)
{
return (TypeOfBiometricData) obj;
}
if (obj is DerInteger)
{
DerInteger predefinedBiometricTypeObj = DerInteger.GetInstance(obj);
int predefinedBiometricType = predefinedBiometricTypeObj.Value.IntValue;
return new TypeOfBiometricData(predefinedBiometricType);
}
if (obj is DerObjectIdentifier)
{
DerObjectIdentifier BiometricDataOid = DerObjectIdentifier.GetInstance(obj);
return new TypeOfBiometricData(BiometricDataOid);
}
throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
}
public TypeOfBiometricData(
int predefinedBiometricType)
{
if (predefinedBiometricType == Picture || predefinedBiometricType == HandwrittenSignature)
{
obj = new DerInteger(predefinedBiometricType);
}
else
{
throw new ArgumentException("unknow PredefinedBiometricType : " + predefinedBiometricType);
}
}
public TypeOfBiometricData(
DerObjectIdentifier biometricDataOid)
{
obj = biometricDataOid;
}
public bool IsPredefined
{
get { return obj is DerInteger; }
}
public int PredefinedBiometricType
{
get { return ((DerInteger) obj).Value.IntValue; }
}
public DerObjectIdentifier BiometricDataOid
{
get { return (DerObjectIdentifier) obj; }
}
public override Asn1Object ToAsn1Object()
{
return obj.ToAsn1Object();
}
}
}
using System;
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X509.Qualified
{
/**
* The TypeOfBiometricData object.
* <pre>
* TypeOfBiometricData ::= CHOICE {
* predefinedBiometricType PredefinedBiometricType,
* biometricDataOid OBJECT IDENTIFIER }
*
* PredefinedBiometricType ::= INTEGER {
* picture(0),handwritten-signature(1)}
* (picture|handwritten-signature)
* </pre>
*/
public class TypeOfBiometricData
: Asn1Encodable, IAsn1Choice
{
public const int Picture = 0;
public const int HandwrittenSignature = 1;
internal Asn1Encodable obj;
public static TypeOfBiometricData GetInstance(
object obj)
{
if (obj == null || obj is TypeOfBiometricData)
{
return (TypeOfBiometricData) obj;
}
if (obj is DerInteger)
{
DerInteger predefinedBiometricTypeObj = DerInteger.GetInstance(obj);
int predefinedBiometricType = predefinedBiometricTypeObj.Value.IntValue;
return new TypeOfBiometricData(predefinedBiometricType);
}
if (obj is DerObjectIdentifier)
{
DerObjectIdentifier BiometricDataOid = DerObjectIdentifier.GetInstance(obj);
return new TypeOfBiometricData(BiometricDataOid);
}
throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
}
public TypeOfBiometricData(
int predefinedBiometricType)
{
if (predefinedBiometricType == Picture || predefinedBiometricType == HandwrittenSignature)
{
obj = new DerInteger(predefinedBiometricType);
}
else
{
throw new ArgumentException("unknow PredefinedBiometricType : " + predefinedBiometricType);
}
}
public TypeOfBiometricData(
DerObjectIdentifier biometricDataOid)
{
obj = biometricDataOid;
}
public bool IsPredefined
{
get { return obj is DerInteger; }
}
public int PredefinedBiometricType
{
get { return ((DerInteger) obj).Value.IntValue; }
}
public DerObjectIdentifier BiometricDataOid
{
get { return (DerObjectIdentifier) obj; }
}
public override Asn1Object ToAsn1Object()
{
return obj.ToAsn1Object();
}
}
}

View File

@ -1,178 +1,177 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1.X500;
namespace Org.BouncyCastle.Asn1.X509.SigI
{
/**
* Structure for a name or pseudonym.
*
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
*
* @see org.bouncycastle.asn1.x509.sigi.PersonalData
*
*/
public class NameOrPseudonym
: Asn1Encodable
//, Asn1Choice
{
private readonly DirectoryString pseudonym;
private readonly DirectoryString surname;
private readonly Asn1Sequence givenName;
public static NameOrPseudonym GetInstance(
object obj)
{
if (obj == null || obj is NameOrPseudonym)
{
return (NameOrPseudonym)obj;
}
if (obj is IAsn1String)
{
return new NameOrPseudonym(DirectoryString.GetInstance(obj));
}
if (obj is Asn1Sequence)
{
return new NameOrPseudonym((Asn1Sequence) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
/**
* Constructor from DERString.
* <p/>
* The sequence is of type NameOrPseudonym:
* <p/>
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
* @param pseudonym pseudonym value to use.
*/
public NameOrPseudonym(
DirectoryString pseudonym)
{
this.pseudonym = pseudonym;
}
/**
* Constructor from Asn1Sequence.
* <p/>
* The sequence is of type NameOrPseudonym:
* <p/>
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
*
* @param seq The ASN.1 sequence.
*/
private NameOrPseudonym(
Asn1Sequence seq)
{
if (seq.Count != 2)
throw new ArgumentException("Bad sequence size: " + seq.Count);
if (!(seq[0] is IAsn1String))
throw new ArgumentException("Bad object encountered: " + seq[0].GetType().Name);
surname = DirectoryString.GetInstance(seq[0]);
givenName = Asn1Sequence.GetInstance(seq[1]);
}
/**
* Constructor from a given details.
*
* @param pseudonym The pseudonym.
*/
public NameOrPseudonym(
string pseudonym)
: this(new DirectoryString(pseudonym))
{
}
/**
* Constructor from a given details.
*
* @param surname The surname.
* @param givenName A sequence of directory strings making up the givenName
*/
public NameOrPseudonym(
DirectoryString surname,
Asn1Sequence givenName)
{
this.surname = surname;
this.givenName = givenName;
}
public DirectoryString Pseudonym
{
get { return pseudonym; }
}
public DirectoryString Surname
{
get { return surname; }
}
public DirectoryString[] GetGivenName()
{
DirectoryString[] items = new DirectoryString[givenName.Count];
int count = 0;
foreach (object o in givenName)
{
items[count++] = DirectoryString.GetInstance(o);
}
return items;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <p/>
* Returns:
* <p/>
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
if (pseudonym != null)
{
return pseudonym.ToAsn1Object();
}
return new DerSequence(surname, givenName);
}
}
}
using System;
using System.Collections;
using Org.BouncyCastle.Asn1.X500;
namespace Org.BouncyCastle.Asn1.X509.SigI
{
/**
* Structure for a name or pseudonym.
*
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
*
* @see org.bouncycastle.asn1.x509.sigi.PersonalData
*
*/
public class NameOrPseudonym
: Asn1Encodable, IAsn1Choice
{
private readonly DirectoryString pseudonym;
private readonly DirectoryString surname;
private readonly Asn1Sequence givenName;
public static NameOrPseudonym GetInstance(
object obj)
{
if (obj == null || obj is NameOrPseudonym)
{
return (NameOrPseudonym)obj;
}
if (obj is IAsn1String)
{
return new NameOrPseudonym(DirectoryString.GetInstance(obj));
}
if (obj is Asn1Sequence)
{
return new NameOrPseudonym((Asn1Sequence) obj);
}
throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
}
/**
* Constructor from DERString.
* <p/>
* The sequence is of type NameOrPseudonym:
* <p/>
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
* @param pseudonym pseudonym value to use.
*/
public NameOrPseudonym(
DirectoryString pseudonym)
{
this.pseudonym = pseudonym;
}
/**
* Constructor from Asn1Sequence.
* <p/>
* The sequence is of type NameOrPseudonym:
* <p/>
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
*
* @param seq The ASN.1 sequence.
*/
private NameOrPseudonym(
Asn1Sequence seq)
{
if (seq.Count != 2)
throw new ArgumentException("Bad sequence size: " + seq.Count);
if (!(seq[0] is IAsn1String))
throw new ArgumentException("Bad object encountered: " + seq[0].GetType().Name);
surname = DirectoryString.GetInstance(seq[0]);
givenName = Asn1Sequence.GetInstance(seq[1]);
}
/**
* Constructor from a given details.
*
* @param pseudonym The pseudonym.
*/
public NameOrPseudonym(
string pseudonym)
: this(new DirectoryString(pseudonym))
{
}
/**
* Constructor from a given details.
*
* @param surname The surname.
* @param givenName A sequence of directory strings making up the givenName
*/
public NameOrPseudonym(
DirectoryString surname,
Asn1Sequence givenName)
{
this.surname = surname;
this.givenName = givenName;
}
public DirectoryString Pseudonym
{
get { return pseudonym; }
}
public DirectoryString Surname
{
get { return surname; }
}
public DirectoryString[] GetGivenName()
{
DirectoryString[] items = new DirectoryString[givenName.Count];
int count = 0;
foreach (object o in givenName)
{
items[count++] = DirectoryString.GetInstance(o);
}
return items;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <p/>
* Returns:
* <p/>
* <pre>
* NameOrPseudonym ::= CHOICE {
* surAndGivenName SEQUENCE {
* surName DirectoryString,
* givenName SEQUENCE OF DirectoryString
* },
* pseudonym DirectoryString
* }
* </pre>
*
* @return an Asn1Object
*/
public override Asn1Object ToAsn1Object()
{
if (pseudonym != null)
{
return pseudonym.ToAsn1Object();
}
return new DerSequence(surname, givenName);
}
}
}

View File

@ -1,53 +1,53 @@
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X9
{
public class X962Parameters
: Asn1Encodable
{
private readonly Asn1Object _params;
public X962Parameters(
X9ECParameters ecParameters)
{
this._params = ecParameters.ToAsn1Object();
}
public X962Parameters(
DerObjectIdentifier namedCurve)
{
this._params = namedCurve;
}
public X962Parameters(
Asn1Object obj)
{
this._params = obj;
}
public bool IsNamedCurve
{
get { return (_params is DerObjectIdentifier); }
}
public Asn1Object Parameters
{
get { return _params; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* Parameters ::= CHOICE {
* ecParameters ECParameters,
* namedCurve CURVES.&amp;id({CurveNames}),
* implicitlyCA Null
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return _params;
}
}
}
using Org.BouncyCastle.Asn1;
namespace Org.BouncyCastle.Asn1.X9
{
public class X962Parameters
: Asn1Encodable, IAsn1Choice
{
private readonly Asn1Object _params;
public X962Parameters(
X9ECParameters ecParameters)
{
this._params = ecParameters.ToAsn1Object();
}
public X962Parameters(
DerObjectIdentifier namedCurve)
{
this._params = namedCurve;
}
public X962Parameters(
Asn1Object obj)
{
this._params = obj;
}
public bool IsNamedCurve
{
get { return (_params is DerObjectIdentifier); }
}
public Asn1Object Parameters
{
get { return _params; }
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* Parameters ::= CHOICE {
* ecParameters ECParameters,
* namedCurve CURVES.&amp;id({CurveNames}),
* implicitlyCA Null
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
return _params;
}
}
}

View File

@ -1,165 +1,170 @@
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
namespace Org.BouncyCastle.Asn1.X9
{
/**
* ASN.1 def for Elliptic-Curve ECParameters structure. See
* X9.62, for further details.
*/
public class X9ECParameters
: Asn1Encodable
{
private X9FieldID fieldID;
private ECCurve curve;
private ECPoint g;
private BigInteger n;
private BigInteger h;
private byte[] seed;
public X9ECParameters(
Asn1Sequence seq)
{
if (!(seq[0] is DerInteger)
|| !((DerInteger) seq[0]).Value.Equals(BigInteger.One))
{
throw new ArgumentException("bad version in X9ECParameters");
}
X9Curve x9c = null;
if (seq[2] is X9Curve)
{
x9c = (X9Curve) seq[2];
}
else
{
x9c = new X9Curve(
new X9FieldID(
(Asn1Sequence) seq[1]),
(Asn1Sequence) seq[2]);
}
this.curve = x9c.Curve;
if (seq[3] is X9ECPoint)
{
this.g = ((X9ECPoint) seq[3]).Point;
}
else
{
this.g = new X9ECPoint(curve, (Asn1OctetString) seq[3]).Point;
}
this.n = ((DerInteger) seq[4]).Value;
this.seed = x9c.GetSeed();
if (seq.Count == 6)
{
this.h = ((DerInteger) seq[5]).Value;
}
else
{
this.h = BigInteger.One;
}
}
public X9ECParameters(
ECCurve curve,
ECPoint g,
BigInteger n)
: this(curve, g, n, BigInteger.One, null)
{
}
public X9ECParameters(
ECCurve curve,
ECPoint g,
BigInteger n,
BigInteger h)
: this(curve, g, n, h, null)
{
}
public X9ECParameters(
ECCurve curve,
ECPoint g,
BigInteger n,
BigInteger h,
byte[] seed)
{
this.curve = curve;
this.g = g;
this.n = n;
this.h = h;
this.seed = seed;
if (curve is FpCurve)
{
this.fieldID = new X9FieldID(((FpCurve) curve).Q);
}
else if (curve is F2mCurve)
{
F2mCurve curveF2m = (F2mCurve) curve;
this.fieldID = new X9FieldID(curveF2m.M, curveF2m.K1,
curveF2m.K2, curveF2m.K3);
}
}
public ECCurve Curve
{
get { return curve; }
}
public ECPoint G
{
get { return g; }
}
public BigInteger N
{
get { return n; }
}
public BigInteger H
{
get { return h; }
}
public byte[] GetSeed()
{
return seed;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* ECParameters ::= Sequence {
* version Integer { ecpVer1(1) } (ecpVer1),
* fieldID FieldID {{FieldTypes}},
* curve X9Curve,
* base X9ECPoint,
* order Integer,
* cofactor Integer OPTIONAL
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector(
new DerInteger(1),
fieldID,
new X9Curve(curve, seed),
new X9ECPoint(g),
new DerInteger(n));
if (!h.Equals(BigInteger.One))
{
v.Add(new DerInteger(h));
}
return new DerSequence(v);
}
}
}
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
namespace Org.BouncyCastle.Asn1.X9
{
/**
* ASN.1 def for Elliptic-Curve ECParameters structure. See
* X9.62, for further details.
*/
public class X9ECParameters
: Asn1Encodable
{
private X9FieldID fieldID;
private ECCurve curve;
private ECPoint g;
private BigInteger n;
private BigInteger h;
private byte[] seed;
public X9ECParameters(
Asn1Sequence seq)
{
if (!(seq[0] is DerInteger)
|| !((DerInteger) seq[0]).Value.Equals(BigInteger.One))
{
throw new ArgumentException("bad version in X9ECParameters");
}
X9Curve x9c = null;
if (seq[2] is X9Curve)
{
x9c = (X9Curve) seq[2];
}
else
{
x9c = new X9Curve(
new X9FieldID(
(Asn1Sequence) seq[1]),
(Asn1Sequence) seq[2]);
}
this.curve = x9c.Curve;
if (seq[3] is X9ECPoint)
{
this.g = ((X9ECPoint) seq[3]).Point;
}
else
{
this.g = new X9ECPoint(curve, (Asn1OctetString) seq[3]).Point;
}
this.n = ((DerInteger) seq[4]).Value;
this.seed = x9c.GetSeed();
if (seq.Count == 6)
{
this.h = ((DerInteger) seq[5]).Value;
}
}
public X9ECParameters(
ECCurve curve,
ECPoint g,
BigInteger n)
: this(curve, g, n, BigInteger.One, null)
{
}
public X9ECParameters(
ECCurve curve,
ECPoint g,
BigInteger n,
BigInteger h)
: this(curve, g, n, h, null)
{
}
public X9ECParameters(
ECCurve curve,
ECPoint g,
BigInteger n,
BigInteger h,
byte[] seed)
{
this.curve = curve;
this.g = g;
this.n = n;
this.h = h;
this.seed = seed;
if (curve is FpCurve)
{
this.fieldID = new X9FieldID(((FpCurve) curve).Q);
}
else if (curve is F2mCurve)
{
F2mCurve curveF2m = (F2mCurve) curve;
this.fieldID = new X9FieldID(curveF2m.M, curveF2m.K1,
curveF2m.K2, curveF2m.K3);
}
}
public ECCurve Curve
{
get { return curve; }
}
public ECPoint G
{
get { return g; }
}
public BigInteger N
{
get { return n; }
}
public BigInteger H
{
get
{
if (h == null)
{
// TODO - this should be calculated, it will cause issues with custom curves.
return BigInteger.One;
}
return h;
}
}
public byte[] GetSeed()
{
return seed;
}
/**
* Produce an object suitable for an Asn1OutputStream.
* <pre>
* ECParameters ::= Sequence {
* version Integer { ecpVer1(1) } (ecpVer1),
* fieldID FieldID {{FieldTypes}},
* curve X9Curve,
* base X9ECPoint,
* order Integer,
* cofactor Integer OPTIONAL
* }
* </pre>
*/
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector(
new DerInteger(1),
fieldID,
new X9Curve(curve, seed),
new X9ECPoint(g),
new DerInteger(n));
if (h != null)
{
v.Add(new DerInteger(h));
}
return new DerSequence(v);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,328 +1,330 @@
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Text;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Bcpg
{
/**
* Basic output stream.
*/
public class ArmoredOutputStream
: BaseOutputStream
{
private static readonly byte[] encodingTable =
{
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
(byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
(byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'v',
(byte)'w', (byte)'x', (byte)'y', (byte)'z',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
(byte)'7', (byte)'8', (byte)'9',
(byte)'+', (byte)'/'
};
/**
* encode the input data producing a base 64 encoded byte array.
*/
private static void Encode(
Stream outStream,
int[] data,
int len)
{
Debug.Assert(len > 0);
Debug.Assert(len < 4);
byte[] bs = new byte[4];
int d1 = data[0];
bs[0] = encodingTable[(d1 >> 2) & 0x3f];
switch (len)
{
case 1:
{
bs[1] = encodingTable[(d1 << 4) & 0x3f];
bs[2] = (byte)'=';
bs[3] = (byte)'=';
break;
}
case 2:
{
int d2 = data[1];
bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f];
bs[2] = encodingTable[(d2 << 2) & 0x3f];
bs[3] = (byte)'=';
break;
}
case 3:
{
int d2 = data[1];
int d3 = data[2];
bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f];
bs[2] = encodingTable[((d2 << 2) | (d3 >> 6)) & 0x3f];
bs[3] = encodingTable[d3 & 0x3f];
break;
}
}
outStream.Write(bs, 0, bs.Length);
}
private readonly Stream outStream;
private int[] buf = new int[3];
private int bufPtr = 0;
private Crc24 crc = new Crc24();
private int chunkCount = 0;
private int lastb;
private bool start = true;
private bool clearText = false;
private bool newLine = false;
private string nl = Platform.NewLine;
private string type;
private string headerStart = "-----BEGIN PGP ";
private string headerTail = "-----";
private string footerStart = "-----END PGP ";
private string footerTail = "-----";
private string version = "BCPG v1.32";
private readonly IDictionary headers;
public ArmoredOutputStream(Stream outStream)
{
this.outStream = outStream;
this.headers = new Hashtable();
this.headers["Version"] = version;
}
public ArmoredOutputStream(Stream outStream, IDictionary headers)
{
this.outStream = outStream;
this.headers = new Hashtable(headers);
this.headers["Version"] = version;
}
/**
* Set an additional header entry.
*
* @param name the name of the header entry.
* @param v the value of the header entry.
*/
public void SetHeader(
string name,
string v)
{
headers[name] = v;
}
/**
* Reset the headers to only contain a Version string.
*/
public void ResetHeaders()
{
headers.Clear();
headers["Version"] = version;
}
/**
* Start a clear text signed message.
* @param hashAlgorithm
*/
public void BeginClearText(
HashAlgorithmTag hashAlgorithm)
{
string hash;
switch (hashAlgorithm)
{
case HashAlgorithmTag.Sha1:
hash = "SHA1";
break;
case HashAlgorithmTag.Sha256:
hash = "SHA256";
break;
case HashAlgorithmTag.Sha384:
hash = "SHA384";
break;
case HashAlgorithmTag.Sha512:
hash = "SHA512";
break;
case HashAlgorithmTag.MD2:
hash = "MD2";
break;
case HashAlgorithmTag.MD5:
hash = "MD5";
break;
case HashAlgorithmTag.RipeMD160:
hash = "RIPEMD160";
break;
default:
throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm);
}
DoWrite("-----BEGIN PGP SIGNED MESSAGE-----" + nl);
DoWrite("Hash: " + hash + nl + nl);
clearText = true;
newLine = true;
lastb = 0;
}
public void EndClearText()
{
clearText = false;
}
public override void WriteByte(
byte b)
{
if (clearText)
{
outStream.WriteByte(b);
if (newLine)
{
if (!(b == '\n' && lastb == '\r'))
{
newLine = false;
}
if (b == '-')
{
outStream.WriteByte((byte)' ');
outStream.WriteByte((byte)'-'); // dash escape
}
}
if (b == '\r' || (b == '\n' && lastb != '\r'))
{
newLine = true;
}
lastb = b;
return;
}
if (start)
{
bool newPacket = (b & 0x40) != 0;
int tag;
if (newPacket)
{
tag = b & 0x3f;
}
else
{
tag = (b & 0x3f) >> 2;
}
switch ((PacketTag)tag)
{
case PacketTag.PublicKey:
type = "PUBLIC KEY BLOCK";
break;
case PacketTag.SecretKey:
type = "PRIVATE KEY BLOCK";
break;
case PacketTag.Signature:
type = "SIGNATURE";
break;
default:
type = "MESSAGE";
break;
}
DoWrite(headerStart + type + headerTail + nl);
WriteHeaderEntry("Version", (string) headers["Version"]);
foreach (DictionaryEntry de in headers)
{
string k = (string) de.Key;
if (k != "Version")
{
string v = (string) de.Value;
WriteHeaderEntry(k, v);
}
}
DoWrite(nl);
start = false;
}
if (bufPtr == 3)
{
Encode(outStream, buf, bufPtr);
bufPtr = 0;
if ((++chunkCount & 0xf) == 0)
{
DoWrite(nl);
}
}
crc.Update(b);
buf[bufPtr++] = b & 0xff;
}
/**
* <b>Note</b>: close does nor close the underlying stream. So it is possible to write
* multiple objects using armoring to a single stream.
*/
public override void Close()
{
if (type != null)
{
if (bufPtr > 0)
{
Encode(outStream, buf, bufPtr);
}
DoWrite(nl + '=');
int crcV = crc.Value;
buf[0] = ((crcV >> 16) & 0xff);
buf[1] = ((crcV >> 8) & 0xff);
buf[2] = (crcV & 0xff);
Encode(outStream, buf, 3);
DoWrite(nl);
DoWrite(footerStart);
DoWrite(type);
DoWrite(footerTail);
DoWrite(nl);
outStream.Flush();
type = null;
start = true;
base.Close();
}
}
private void WriteHeaderEntry(
string name,
string v)
{
DoWrite(name + ": " + v + nl);
}
private void DoWrite(
string s)
{
byte[] bs = Encoding.ASCII.GetBytes(s);
outStream.Write(bs, 0, bs.Length);
}
}
}
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Bcpg
{
/**
* Basic output stream.
*/
public class ArmoredOutputStream
: BaseOutputStream
{
private static readonly byte[] encodingTable =
{
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
(byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
(byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
(byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
(byte)'v',
(byte)'w', (byte)'x', (byte)'y', (byte)'z',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
(byte)'7', (byte)'8', (byte)'9',
(byte)'+', (byte)'/'
};
/**
* encode the input data producing a base 64 encoded byte array.
*/
private static void Encode(
Stream outStream,
int[] data,
int len)
{
Debug.Assert(len > 0);
Debug.Assert(len < 4);
byte[] bs = new byte[4];
int d1 = data[0];
bs[0] = encodingTable[(d1 >> 2) & 0x3f];
switch (len)
{
case 1:
{
bs[1] = encodingTable[(d1 << 4) & 0x3f];
bs[2] = (byte)'=';
bs[3] = (byte)'=';
break;
}
case 2:
{
int d2 = data[1];
bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f];
bs[2] = encodingTable[(d2 << 2) & 0x3f];
bs[3] = (byte)'=';
break;
}
case 3:
{
int d2 = data[1];
int d3 = data[2];
bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f];
bs[2] = encodingTable[((d2 << 2) | (d3 >> 6)) & 0x3f];
bs[3] = encodingTable[d3 & 0x3f];
break;
}
}
outStream.Write(bs, 0, bs.Length);
}
private readonly Stream outStream;
private int[] buf = new int[3];
private int bufPtr = 0;
private Crc24 crc = new Crc24();
private int chunkCount = 0;
private int lastb;
private bool start = true;
private bool clearText = false;
private bool newLine = false;
private string type;
private static readonly string nl = Platform.NewLine;
private static readonly string headerStart = "-----BEGIN PGP ";
private static readonly string headerTail = "-----";
private static readonly string footerStart = "-----END PGP ";
private static readonly string footerTail = "-----";
private static readonly string version = "BCPG C# v"
+ Assembly.GetExecutingAssembly().GetName().Version;
private readonly IDictionary headers;
public ArmoredOutputStream(Stream outStream)
{
this.outStream = outStream;
this.headers = new Hashtable();
this.headers["Version"] = version;
}
public ArmoredOutputStream(Stream outStream, IDictionary headers)
{
this.outStream = outStream;
this.headers = new Hashtable(headers);
this.headers["Version"] = version;
}
/**
* Set an additional header entry.
*
* @param name the name of the header entry.
* @param v the value of the header entry.
*/
public void SetHeader(
string name,
string v)
{
headers[name] = v;
}
/**
* Reset the headers to only contain a Version string.
*/
public void ResetHeaders()
{
headers.Clear();
headers["Version"] = version;
}
/**
* Start a clear text signed message.
* @param hashAlgorithm
*/
public void BeginClearText(
HashAlgorithmTag hashAlgorithm)
{
string hash;
switch (hashAlgorithm)
{
case HashAlgorithmTag.Sha1:
hash = "SHA1";
break;
case HashAlgorithmTag.Sha256:
hash = "SHA256";
break;
case HashAlgorithmTag.Sha384:
hash = "SHA384";
break;
case HashAlgorithmTag.Sha512:
hash = "SHA512";
break;
case HashAlgorithmTag.MD2:
hash = "MD2";
break;
case HashAlgorithmTag.MD5:
hash = "MD5";
break;
case HashAlgorithmTag.RipeMD160:
hash = "RIPEMD160";
break;
default:
throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm);
}
DoWrite("-----BEGIN PGP SIGNED MESSAGE-----" + nl);
DoWrite("Hash: " + hash + nl + nl);
clearText = true;
newLine = true;
lastb = 0;
}
public void EndClearText()
{
clearText = false;
}
public override void WriteByte(
byte b)
{
if (clearText)
{
outStream.WriteByte(b);
if (newLine)
{
if (!(b == '\n' && lastb == '\r'))
{
newLine = false;
}
if (b == '-')
{
outStream.WriteByte((byte)' ');
outStream.WriteByte((byte)'-'); // dash escape
}
}
if (b == '\r' || (b == '\n' && lastb != '\r'))
{
newLine = true;
}
lastb = b;
return;
}
if (start)
{
bool newPacket = (b & 0x40) != 0;
int tag;
if (newPacket)
{
tag = b & 0x3f;
}
else
{
tag = (b & 0x3f) >> 2;
}
switch ((PacketTag)tag)
{
case PacketTag.PublicKey:
type = "PUBLIC KEY BLOCK";
break;
case PacketTag.SecretKey:
type = "PRIVATE KEY BLOCK";
break;
case PacketTag.Signature:
type = "SIGNATURE";
break;
default:
type = "MESSAGE";
break;
}
DoWrite(headerStart + type + headerTail + nl);
WriteHeaderEntry("Version", (string) headers["Version"]);
foreach (DictionaryEntry de in headers)
{
string k = (string) de.Key;
if (k != "Version")
{
string v = (string) de.Value;
WriteHeaderEntry(k, v);
}
}
DoWrite(nl);
start = false;
}
if (bufPtr == 3)
{
Encode(outStream, buf, bufPtr);
bufPtr = 0;
if ((++chunkCount & 0xf) == 0)
{
DoWrite(nl);
}
}
crc.Update(b);
buf[bufPtr++] = b & 0xff;
}
/**
* <b>Note</b>: close does nor close the underlying stream. So it is possible to write
* multiple objects using armoring to a single stream.
*/
public override void Close()
{
if (type != null)
{
if (bufPtr > 0)
{
Encode(outStream, buf, bufPtr);
}
DoWrite(nl + '=');
int crcV = crc.Value;
buf[0] = ((crcV >> 16) & 0xff);
buf[1] = ((crcV >> 8) & 0xff);
buf[2] = (crcV & 0xff);
Encode(outStream, buf, 3);
DoWrite(nl);
DoWrite(footerStart);
DoWrite(type);
DoWrite(footerTail);
DoWrite(nl);
outStream.Flush();
type = null;
start = true;
base.Close();
}
}
private void WriteHeaderEntry(
string name,
string v)
{
DoWrite(name + ": " + v + nl);
}
private void DoWrite(
string s)
{
byte[] bs = Encoding.ASCII.GetBytes(s);
outStream.Write(bs, 0, bs.Length);
}
}
}

View File

@ -1,30 +1,33 @@
namespace Org.BouncyCastle.Bcpg
{
/**
* Basic PGP signature sub-packet tag types.
*/
public enum SignatureSubpacketTag
{
CreationTime = 2, // signature creation time
ExpireTime = 3, // signature expiration time
Exportable = 4, // exportable certification
TrustSig = 5, // trust signature
RegExp = 6, // regular expression
Revocable = 7, // revocable
KeyExpireTime = 9, // key expiration time
Placeholder = 10, // placeholder for backward compatibility
PreferredSymmetricAlgorithms = 11, // preferred symmetric algorithms
RevocationKey = 12, // revocation key
IssuerKeyId = 16, // issuer key ID
NotationData = 20, // notation data
PreferredHashAlgorithms = 21, // preferred hash algorithms
PreferredCompressionAlgorithms = 22, // preferred compression algorithms
KeyServerPreferences = 23, // key server preferences
PreferredKeyServer = 24, // preferred key server
PrimaryUserId = 25, // primary user id
PolicyUrl = 26, // policy URL
KeyFlags = 27, // key flags
SignerUserId = 28, // signer's user id
RevocationReason = 29 // reason for revocation
}
}
namespace Org.BouncyCastle.Bcpg
{
/**
* Basic PGP signature sub-packet tag types.
*/
public enum SignatureSubpacketTag
{
CreationTime = 2, // signature creation time
ExpireTime = 3, // signature expiration time
Exportable = 4, // exportable certification
TrustSig = 5, // trust signature
RegExp = 6, // regular expression
Revocable = 7, // revocable
KeyExpireTime = 9, // key expiration time
Placeholder = 10, // placeholder for backward compatibility
PreferredSymmetricAlgorithms = 11, // preferred symmetric algorithms
RevocationKey = 12, // revocation key
IssuerKeyId = 16, // issuer key ID
NotationData = 20, // notation data
PreferredHashAlgorithms = 21, // preferred hash algorithms
PreferredCompressionAlgorithms = 22, // preferred compression algorithms
KeyServerPreferences = 23, // key server preferences
PreferredKeyServer = 24, // preferred key server
PrimaryUserId = 25, // primary user id
PolicyUrl = 26, // policy URL
KeyFlags = 27, // key flags
SignerUserId = 28, // signer's user id
RevocationReason = 29, // reason for revocation
Features = 30, // features
SignatureTarget = 31, // signature target
EmbeddedSignature = 32 // embedded signature
}
}

View File

@ -0,0 +1,18 @@
using System;
namespace Org.BouncyCastle.Bcpg.Sig
{
/**
* Packet embedded signature
*/
public class EmbeddedSignature
: SignatureSubpacket
{
public EmbeddedSignature(
bool critical,
byte[] data)
: base(SignatureSubpacketTag.EmbeddedSignature, critical, data)
{
}
}
}

View File

@ -1,101 +1,112 @@
using System;
using System.IO;
using System.Text;
namespace Org.BouncyCastle.Bcpg.Sig
{
/**
* Class provided a NotationData object according to
* RFC2440, Chapter 5.2.3.15. Notation Data
*/
public class NotationData
: SignatureSubpacket
{
public const int HeaderFlagLength = 4;
public const int HeaderNameLength = 2;
public const int HeaderValueLength = 2;
public NotationData(
bool critical,
byte[] data)
: base(SignatureSubpacketTag.NotationData, critical, data)
{
}
public NotationData(
bool critical,
bool humanReadable,
string notationName,
string notationValue)
: base(SignatureSubpacketTag.NotationData, critical,
createData(humanReadable, notationName, notationValue))
{
}
private static byte[] createData(
bool humanReadable,
string notationName,
string notationValue)
{
MemoryStream os = new MemoryStream();
// (4 octets of flags, 2 octets of name length (M),
// 2 octets of value length (N),
// M octets of name data,
// N octets of value data)
// flags
os.WriteByte(humanReadable ? (byte)0x80 : (byte)0x00);
os.WriteByte(0x0);
os.WriteByte(0x0);
os.WriteByte(0x0);
byte[] nameData, valueData = null;
int nameLength, valueLength;
nameData = Encoding.UTF8.GetBytes(notationName);
nameLength = System.Math.Min(nameData.Length, 0xFF);
valueData = Encoding.UTF8.GetBytes(notationValue);
valueLength = System.Math.Min(valueData.Length, 0xFF);
// name length
os.WriteByte((byte)(nameLength >> 8));
os.WriteByte((byte)(nameLength >> 0));
// value length
os.WriteByte((byte)(valueLength >> 8));
os.WriteByte((byte)(valueLength >> 0));
// name
os.Write(nameData, 0, nameLength);
// value
os.Write(valueData, 0, valueLength);
return os.ToArray();
}
public bool IsHumanReadable
{
get { return data[0] == (byte)0x80; }
}
public string GetNotationName()
{
int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0));
int namePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength;
return Encoding.UTF8.GetString(data, namePos, nameLength);
}
public string GetNotationValue()
{
int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0));
int valueLength = ((data[HeaderFlagLength + HeaderNameLength] << 8) + (data[HeaderFlagLength + HeaderNameLength + 1] << 0));
int valuePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength + nameLength;
return Encoding.UTF8.GetString(data, valuePos, valueLength);
}
}
}
using System;
using System.IO;
using System.Text;
namespace Org.BouncyCastle.Bcpg.Sig
{
/**
* Class provided a NotationData object according to
* RFC2440, Chapter 5.2.3.15. Notation Data
*/
public class NotationData
: SignatureSubpacket
{
public const int HeaderFlagLength = 4;
public const int HeaderNameLength = 2;
public const int HeaderValueLength = 2;
public NotationData(
bool critical,
byte[] data)
: base(SignatureSubpacketTag.NotationData, critical, data)
{
}
public NotationData(
bool critical,
bool humanReadable,
string notationName,
string notationValue)
: base(SignatureSubpacketTag.NotationData, critical,
createData(humanReadable, notationName, notationValue))
{
}
private static byte[] createData(
bool humanReadable,
string notationName,
string notationValue)
{
MemoryStream os = new MemoryStream();
// (4 octets of flags, 2 octets of name length (M),
// 2 octets of value length (N),
// M octets of name data,
// N octets of value data)
// flags
os.WriteByte(humanReadable ? (byte)0x80 : (byte)0x00);
os.WriteByte(0x0);
os.WriteByte(0x0);
os.WriteByte(0x0);
byte[] nameData, valueData = null;
int nameLength, valueLength;
nameData = Encoding.UTF8.GetBytes(notationName);
nameLength = System.Math.Min(nameData.Length, 0xFF);
valueData = Encoding.UTF8.GetBytes(notationValue);
valueLength = System.Math.Min(valueData.Length, 0xFF);
// name length
os.WriteByte((byte)(nameLength >> 8));
os.WriteByte((byte)(nameLength >> 0));
// value length
os.WriteByte((byte)(valueLength >> 8));
os.WriteByte((byte)(valueLength >> 0));
// name
os.Write(nameData, 0, nameLength);
// value
os.Write(valueData, 0, valueLength);
return os.ToArray();
}
public bool IsHumanReadable
{
get { return data[0] == (byte)0x80; }
}
public string GetNotationName()
{
int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0));
int namePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength;
return Encoding.UTF8.GetString(data, namePos, nameLength);
}
public string GetNotationValue()
{
int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0));
int valueLength = ((data[HeaderFlagLength + HeaderNameLength] << 8) + (data[HeaderFlagLength + HeaderNameLength + 1] << 0));
int valuePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength + nameLength;
return Encoding.UTF8.GetString(data, valuePos, valueLength);
}
public byte[] GetNotationValueBytes()
{
int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0));
int valueLength = ((data[HeaderFlagLength + HeaderNameLength] << 8) + (data[HeaderFlagLength + HeaderNameLength + 1] << 0));
int valuePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength + nameLength;
byte[] bytes = new byte[valueLength];
Array.Copy(data, valuePos, bytes, 0, valueLength);
return bytes;
}
}
}

View File

@ -1,56 +1,43 @@
using System;
namespace Org.BouncyCastle.Bcpg.Sig
{
/**
* packet giving signature creation time.
*/
public class TrustSignature
: SignatureSubpacket
{
private static byte[] IntToByteArray(
int v1,
int v2)
{
byte[] data = new byte[2];
data[0] = (byte)v1;
data[1] = (byte)v2;
return data;
}
public TrustSignature(
bool critical,
byte[] data)
: base(SignatureSubpacketTag.TrustSig, critical, data)
{
}
public TrustSignature(
bool critical,
int depth,
int trustAmount)
: base(SignatureSubpacketTag.TrustSig, critical, IntToByteArray(depth, trustAmount))
{
}
public int Depth
{
get
{
return data[0] & 0xff;
}
}
public int TrustAmount
{
get
{
return data[1] & 0xff;
}
}
}
}
using System;
namespace Org.BouncyCastle.Bcpg.Sig
{
/**
* packet giving trust.
*/
public class TrustSignature
: SignatureSubpacket
{
private static byte[] IntToByteArray(
int v1,
int v2)
{
return new byte[]{ (byte)v1, (byte)v2 };
}
public TrustSignature(
bool critical,
byte[] data)
: base(SignatureSubpacketTag.TrustSig, critical, data)
{
}
public TrustSignature(
bool critical,
int depth,
int trustAmount)
: base(SignatureSubpacketTag.TrustSig, critical, IntToByteArray(depth, trustAmount))
{
}
public int Depth
{
get { return data[0] & 0xff; }
}
public int TrustAmount
{
get { return data[1] & 0xff; }
}
}
}

View File

@ -1,68 +1,86 @@
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
//import javax.crypto.interfaces.PBEKey;
namespace Org.BouncyCastle.Cms
{
public abstract class CmsPbeKey
// TODO Create an equivalent interface somewhere?
// : PBEKey
: ICipherParameters
{
private readonly string password;
private readonly byte[] salt;
private readonly int iterationCount;
public CmsPbeKey(
string password,
byte[] salt,
int iterationCount)
{
this.password = password;
this.salt = Arrays.Clone(salt);
this.iterationCount = iterationCount;
}
public string Password
{
get { return password; }
}
public byte[] Salt
{
get { return Arrays.Clone(salt); }
}
[Obsolete("Use 'Salt' property instead")]
public byte[] GetSalt()
{
return Salt;
}
public int IterationCount
{
get { return iterationCount; }
}
public string Algorithm
{
get { return "PKCS5S2"; }
}
public string Format
{
get { return "RAW"; }
}
public byte[] GetEncoded()
{
return null;
}
internal abstract KeyParameter GetEncoded(string algorithmOid);
}
}
using System;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
//import javax.crypto.interfaces.PBEKey;
namespace Org.BouncyCastle.Cms
{
public abstract class CmsPbeKey
// TODO Create an equivalent interface somewhere?
// : PBEKey
: ICipherParameters
{
private readonly string password;
private readonly byte[] salt;
private readonly int iterationCount;
public CmsPbeKey(
string password,
byte[] salt,
int iterationCount)
{
this.password = password;
this.salt = Arrays.Clone(salt);
this.iterationCount = iterationCount;
}
public CmsPbeKey(
string password,
AlgorithmIdentifier keyDerivationAlgorithm)
{
if (!keyDerivationAlgorithm.ObjectID.Equals(PkcsObjectIdentifiers.IdPbkdf2))
throw new ArgumentException("Unsupported key derivation algorithm: "
+ keyDerivationAlgorithm.ObjectID);
Pbkdf2Params kdfParams = Pbkdf2Params.GetInstance(
keyDerivationAlgorithm.Parameters.ToAsn1Object());
this.password = password;
this.salt = kdfParams.GetSalt();
this.iterationCount = kdfParams.IterationCount.IntValue;
}
public string Password
{
get { return password; }
}
public byte[] Salt
{
get { return Arrays.Clone(salt); }
}
[Obsolete("Use 'Salt' property instead")]
public byte[] GetSalt()
{
return Salt;
}
public int IterationCount
{
get { return iterationCount; }
}
public string Algorithm
{
get { return "PKCS5S2"; }
}
public string Format
{
get { return "RAW"; }
}
public byte[] GetEncoded()
{
return null;
}
internal abstract KeyParameter GetEncoded(string algorithmOid);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,47 @@
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Cms
{
/// <summary>
/// PKCS5 scheme-2 - password converted to bytes assuming ASCII.
/// </summary>
public class Pkcs5Scheme2PbeKey
: CmsPbeKey
{
public Pkcs5Scheme2PbeKey(
string password,
byte[] salt,
int iterationCount)
: base(password, salt, iterationCount)
{
}
internal override KeyParameter GetEncoded(
string algorithmOid)
{
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator();
gen.Init(
PbeParametersGenerator.Pkcs5PasswordToBytes(this.Password),
this.Salt,
this.IterationCount);
return (KeyParameter) gen.GenerateDerivedParameters(
algorithmOid,
CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid));
}
}
}
using System;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Cms
{
/// <summary>
/// PKCS5 scheme-2 - password converted to bytes assuming ASCII.
/// </summary>
public class Pkcs5Scheme2PbeKey
: CmsPbeKey
{
public Pkcs5Scheme2PbeKey(
string password,
byte[] salt,
int iterationCount)
: base(password, salt, iterationCount)
{
}
public Pkcs5Scheme2PbeKey(
string password,
AlgorithmIdentifier keyDerivationAlgorithm)
: base(password, keyDerivationAlgorithm)
{
}
internal override KeyParameter GetEncoded(
string algorithmOid)
{
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator();
gen.Init(
PbeParametersGenerator.Pkcs5PasswordToBytes(this.Password),
this.Salt,
this.IterationCount);
return (KeyParameter) gen.GenerateDerivedParameters(
algorithmOid,
CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid));
}
}
}

View File

@ -1,38 +1,47 @@
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Cms
{
/**
* PKCS5 scheme-2 - password converted to bytes using UTF-8.
*/
public class Pkcs5Scheme2Utf8PbeKey
: CmsPbeKey
{
public Pkcs5Scheme2Utf8PbeKey(
string password,
byte[] salt,
int iterationCount)
: base(password, salt, iterationCount)
{
}
internal override KeyParameter GetEncoded(
string algorithmOid)
{
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator();
gen.Init(
PbeParametersGenerator.Pkcs5PasswordToUtf8Bytes(this.Password),
this.Salt,
this.IterationCount);
return (KeyParameter) gen.GenerateDerivedParameters(
algorithmOid,
CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid));
}
}
}
using System;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Cms
{
/**
* PKCS5 scheme-2 - password converted to bytes using UTF-8.
*/
public class Pkcs5Scheme2Utf8PbeKey
: CmsPbeKey
{
public Pkcs5Scheme2Utf8PbeKey(
string password,
byte[] salt,
int iterationCount)
: base(password, salt, iterationCount)
{
}
public Pkcs5Scheme2Utf8PbeKey(
string password,
AlgorithmIdentifier keyDerivationAlgorithm)
: base(password, keyDerivationAlgorithm)
{
}
internal override KeyParameter GetEncoded(
string algorithmOid)
{
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator();
gen.Init(
PbeParametersGenerator.Pkcs5PasswordToUtf8Bytes(this.Password),
this.Salt,
this.IterationCount);
return (KeyParameter) gen.GenerateDerivedParameters(
algorithmOid,
CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid));
}
}
}

View File

@ -1,88 +1,85 @@
using System;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Cms
{
/**
* the RecipientInfo class for a recipient who has been sent a message
* encrypted using a password.
*/
public class PasswordRecipientInformation
: RecipientInformation
{
private readonly PasswordRecipientInfo _info;
// private readonly AlgorithmIdentifier _encAlg;
public PasswordRecipientInformation(
PasswordRecipientInfo info,
AlgorithmIdentifier encAlg,
Stream data)
: base(encAlg, AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm), data)
{
this._info = info;
// this._encAlg = encAlg;
this._rid = new RecipientID();
}
/**
* return the object identifier for the key derivation algorithm, or null
* if there is none present.
*
* @return OID for key derivation algorithm, if present.
*/
public virtual AlgorithmIdentifier KeyDerivationAlgorithm
{
get
{
return _info.KeyDerivationAlgorithm;
}
}
/**
* decrypt the content and return an input stream.
*/
public override CmsTypedStream GetContentStream(
ICipherParameters key)
{
try
{
AlgorithmIdentifier kekAlg = AlgorithmIdentifier.GetInstance(_info.KeyEncryptionAlgorithm);
Asn1Sequence kekAlgParams = (Asn1Sequence)kekAlg.Parameters;
byte[] encryptedKey = _info.EncryptedKey.GetOctets();
string kekAlgName = DerObjectIdentifier.GetInstance(kekAlgParams[0]).Id;
string cName = CmsEnvelopedHelper.Instance.GetRfc3211WrapperName(kekAlgName);
IWrapper keyWrapper = WrapperUtilities.GetWrapper(cName);
byte[] iv = Asn1OctetString.GetInstance(kekAlgParams[1]).GetOctets();
ICipherParameters parameters = ((CmsPbeKey)key).GetEncoded(kekAlgName);
parameters = new ParametersWithIV(parameters, iv);
keyWrapper.Init(false, parameters);
AlgorithmIdentifier aid = _encAlg;
string alg = aid.ObjectID.Id;
KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
alg, keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));
return GetContentFromSessionKey(sKey);
}
catch (SecurityUtilityException e)
{
throw new CmsException("couldn't create cipher.", e);
}
catch (InvalidKeyException e)
{
throw new CmsException("key invalid in message.", e);
}
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Cms
{
/**
* the RecipientInfo class for a recipient who has been sent a message
* encrypted using a password.
*/
public class PasswordRecipientInformation
: RecipientInformation
{
private readonly PasswordRecipientInfo _info;
// private readonly AlgorithmIdentifier _encAlg;
public PasswordRecipientInformation(
PasswordRecipientInfo info,
AlgorithmIdentifier encAlg,
Stream data)
: base(encAlg, AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm), data)
{
this._info = info;
// this._encAlg = encAlg;
this._rid = new RecipientID();
}
/**
* return the object identifier for the key derivation algorithm, or null
* if there is none present.
*
* @return OID for key derivation algorithm, if present.
*/
public virtual AlgorithmIdentifier KeyDerivationAlgorithm
{
get { return _info.KeyDerivationAlgorithm; }
}
/**
* decrypt the content and return an input stream.
*/
public override CmsTypedStream GetContentStream(
ICipherParameters key)
{
try
{
AlgorithmIdentifier kekAlg = AlgorithmIdentifier.GetInstance(_info.KeyEncryptionAlgorithm);
Asn1Sequence kekAlgParams = (Asn1Sequence)kekAlg.Parameters;
byte[] encryptedKey = _info.EncryptedKey.GetOctets();
string kekAlgName = DerObjectIdentifier.GetInstance(kekAlgParams[0]).Id;
string cName = CmsEnvelopedHelper.Instance.GetRfc3211WrapperName(kekAlgName);
IWrapper keyWrapper = WrapperUtilities.GetWrapper(cName);
byte[] iv = Asn1OctetString.GetInstance(kekAlgParams[1]).GetOctets();
ICipherParameters parameters = ((CmsPbeKey)key).GetEncoded(kekAlgName);
parameters = new ParametersWithIV(parameters, iv);
keyWrapper.Init(false, parameters);
AlgorithmIdentifier aid = _encAlg;
string alg = aid.ObjectID.Id;
KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
alg, keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));
return GetContentFromSessionKey(sKey);
}
catch (SecurityUtilityException e)
{
throw new CmsException("couldn't create cipher.", e);
}
catch (InvalidKeyException e)
{
throw new CmsException("key invalid in message.", e);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,372 +1,380 @@
using System;
using System.Diagnostics;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto
{
/**
* A wrapper class that allows block ciphers to be used to process data in
* a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
* buffer is full and more data is being added, or on a doFinal.
* <p>
* Note: in the case where the underlying cipher is either a CFB cipher or an
* OFB one the last block may not be a multiple of the block size.
* </p>
*/
public class BufferedBlockCipher
: BufferedCipherBase
{
internal byte[] buf;
internal int bufOff;
internal bool forEncryption;
internal IBlockCipher cipher;
/**
* constructor for subclasses
*/
protected BufferedBlockCipher()
{
}
/**
* Create a buffered block cipher without padding.
*
* @param cipher the underlying block cipher this buffering object wraps.
* false otherwise.
*/
public BufferedBlockCipher(
IBlockCipher cipher)
{
if (cipher == null)
throw new ArgumentNullException("cipher");
this.cipher = cipher;
buf = new byte[cipher.GetBlockSize()];
bufOff = 0;
}
public override string AlgorithmName
{
get { return cipher.AlgorithmName; }
}
/**
* initialise the cipher.
*
* @param forEncryption if true the cipher is initialised for
* encryption, if false for decryption.
* @param param the key and other data required by the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
// Note: This doubles as the Init in the event that this cipher is being used as an IWrapper
public override void Init(
bool forEncryption,
ICipherParameters parameters)
{
this.forEncryption = forEncryption;
if (parameters is ParametersWithRandom)
{
parameters = ((ParametersWithRandom) parameters).Parameters;
}
Reset();
cipher.Init(forEncryption, parameters);
}
/**
* return the blocksize for the underlying cipher.
*
* @return the blocksize for the underlying cipher.
*/
public override int GetBlockSize()
{
return cipher.GetBlockSize();
}
/**
* return the size of the output buffer required for an update
* an input of len bytes.
*
* @param len the length of the input.
* @return the space required to accommodate a call to update
* with len bytes of input.
*/
public override int GetUpdateOutputSize(
int length)
{
int total = length + bufOff;
int leftOver = total % buf.Length;
return total - leftOver;
}
/**
* return the size of the output buffer required for an update plus a
* doFinal with an input of len bytes.
*
* @param len the length of the input.
* @return the space required to accommodate a call to update and doFinal
* with len bytes of input.
*/
public override int GetOutputSize(
int length)
{
int total = length + bufOff;
int leftOver = total % buf.Length;
if (leftOver == 0)
{
return total;
}
return total - leftOver + buf.Length;
}
/**
* process a single byte, producing an output block if neccessary.
*
* @param in the input byte.
* @param out the space for any output that might be produced.
* @param outOff the offset from which the output will be copied.
* @return the number of output bytes copied to out.
* @exception DataLengthException if there isn't enough space in out.
* @exception InvalidOperationException if the cipher isn't initialised.
*/
public override int ProcessByte(
byte input,
byte[] output,
int outOff)
{
buf[bufOff++] = input;
if (bufOff == buf.Length)
{
if ((outOff + buf.Length) > output.Length)
throw new DataLengthException("output buffer too short");
bufOff = 0;
return cipher.ProcessBlock(buf, 0, output, outOff);
}
return 0;
}
public override byte[] ProcessByte(
byte input)
{
int outLength = GetUpdateOutputSize(1);
byte[] outBytes = outLength > 0 ? new byte[outLength] : null;
int pos = ProcessByte(input, outBytes, 0);
if (outLength > 0 && pos < outLength)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
return outBytes;
}
public override byte[] ProcessBytes(
byte[] input,
int inOff,
int length)
{
if (input == null)
throw new ArgumentNullException("input");
if (length < 1)
return null;
int outLength = GetUpdateOutputSize(length);
byte[] outBytes = outLength > 0 ? new byte[outLength] : null;
int pos = ProcessBytes(input, inOff, length, outBytes, 0);
if (outLength > 0 && pos < outLength)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
return outBytes;
}
/**
* process an array of bytes, producing output if necessary.
*
* @param in the input byte array.
* @param inOff the offset at which the input data starts.
* @param len the number of bytes to be copied out of the input array.
* @param out the space for any output that might be produced.
* @param outOff the offset from which the output will be copied.
* @return the number of output bytes copied to out.
* @exception DataLengthException if there isn't enough space in out.
* @exception InvalidOperationException if the cipher isn't initialised.
*/
public override int ProcessBytes(
byte[] input,
int inOff,
int length,
byte[] output,
int outOff)
{
if (length < 1)
{
if (length < 0)
throw new ArgumentException("Can't have a negative input length!");
return 0;
}
int blockSize = GetBlockSize();
int outLength = GetUpdateOutputSize(length);
if (outLength > 0)
{
if ((outOff + outLength) > output.Length)
{
throw new DataLengthException("output buffer too short");
}
}
int resultLen = 0;
int gapLen = buf.Length - bufOff;
if (length > gapLen)
{
Array.Copy(input, inOff, buf, bufOff, gapLen);
resultLen += cipher.ProcessBlock(buf, 0, output, outOff);
bufOff = 0;
length -= gapLen;
inOff += gapLen;
while (length > buf.Length)
{
resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen);
length -= blockSize;
inOff += blockSize;
}
}
Array.Copy(input, inOff, buf, bufOff, length);
bufOff += length;
if (bufOff == buf.Length)
{
resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen);
bufOff = 0;
}
return resultLen;
}
public override byte[] DoFinal()
{
byte[] outBytes = EmptyBuffer;
int length = GetOutputSize(0);
if (length > 0)
{
outBytes = new byte[length];
int pos = DoFinal(outBytes, 0);
if (pos < outBytes.Length)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
}
return outBytes;
}
public override byte[] DoFinal(
byte[] input,
int inOff,
int inLen)
{
if (input == null)
throw new ArgumentNullException("input");
int length = GetOutputSize(inLen);
byte[] outBytes = EmptyBuffer;
if (length > 0)
{
outBytes = new byte[length];
int pos = (inLen > 0)
? ProcessBytes(input, inOff, inLen, outBytes, 0)
: 0;
pos += DoFinal(outBytes, pos);
if (pos < outBytes.Length)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
}
return outBytes;
}
/**
* Process the last block in the buffer.
*
* @param out the array the block currently being held is copied into.
* @param outOff the offset at which the copying starts.
* @return the number of output bytes copied to out.
* @exception DataLengthException if there is insufficient space in out for
* the output, or the input is not block size aligned and should be.
* @exception InvalidOperationException if the underlying cipher is not
* initialised.
* @exception InvalidCipherTextException if padding is expected and not found.
* @exception DataLengthException if the input is not block size
* aligned.
*/
public override int DoFinal(
byte[] output,
int outOff)
{
if (bufOff != 0)
{
if (!cipher.IsPartialBlockOkay)
{
throw new DataLengthException("data not block size aligned");
}
if (outOff + bufOff > output.Length)
{
throw new DataLengthException("output buffer too short for DoFinal()");
}
// NB: Can't copy directly, or we may write too much output
cipher.ProcessBlock(buf, 0, buf, 0);
Array.Copy(buf, 0, output, outOff, bufOff);
}
int resultLen = bufOff;
Reset();
return resultLen;
}
/**
* Reset the buffer and cipher. After resetting the object is in the same
* state as it was after the last init (if there was one).
*/
public override void Reset()
{
Array.Clear(buf, 0, buf.Length);
bufOff = 0;
cipher.Reset();
}
}
}
using System;
using System.Diagnostics;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto
{
/**
* A wrapper class that allows block ciphers to be used to process data in
* a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
* buffer is full and more data is being added, or on a doFinal.
* <p>
* Note: in the case where the underlying cipher is either a CFB cipher or an
* OFB one the last block may not be a multiple of the block size.
* </p>
*/
public class BufferedBlockCipher
: BufferedCipherBase
{
internal byte[] buf;
internal int bufOff;
internal bool forEncryption;
internal IBlockCipher cipher;
/**
* constructor for subclasses
*/
protected BufferedBlockCipher()
{
}
/**
* Create a buffered block cipher without padding.
*
* @param cipher the underlying block cipher this buffering object wraps.
* false otherwise.
*/
public BufferedBlockCipher(
IBlockCipher cipher)
{
if (cipher == null)
throw new ArgumentNullException("cipher");
this.cipher = cipher;
buf = new byte[cipher.GetBlockSize()];
bufOff = 0;
}
public override string AlgorithmName
{
get { return cipher.AlgorithmName; }
}
/**
* initialise the cipher.
*
* @param forEncryption if true the cipher is initialised for
* encryption, if false for decryption.
* @param param the key and other data required by the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
// Note: This doubles as the Init in the event that this cipher is being used as an IWrapper
public override void Init(
bool forEncryption,
ICipherParameters parameters)
{
this.forEncryption = forEncryption;
if (parameters is ParametersWithRandom)
{
parameters = ((ParametersWithRandom) parameters).Parameters;
}
Reset();
cipher.Init(forEncryption, parameters);
}
/**
* return the blocksize for the underlying cipher.
*
* @return the blocksize for the underlying cipher.
*/
public override int GetBlockSize()
{
return cipher.GetBlockSize();
}
/**
* return the size of the output buffer required for an update
* an input of len bytes.
*
* @param len the length of the input.
* @return the space required to accommodate a call to update
* with len bytes of input.
*/
public override int GetUpdateOutputSize(
int length)
{
int total = length + bufOff;
int leftOver = total % buf.Length;
return total - leftOver;
}
/**
* return the size of the output buffer required for an update plus a
* doFinal with an input of len bytes.
*
* @param len the length of the input.
* @return the space required to accommodate a call to update and doFinal
* with len bytes of input.
*/
public override int GetOutputSize(
int length)
{
int total = length + bufOff;
int leftOver = total % buf.Length;
if (leftOver == 0)
{
return total;
}
return total - leftOver + buf.Length;
}
/**
* process a single byte, producing an output block if neccessary.
*
* @param in the input byte.
* @param out the space for any output that might be produced.
* @param outOff the offset from which the output will be copied.
* @return the number of output bytes copied to out.
* @exception DataLengthException if there isn't enough space in out.
* @exception InvalidOperationException if the cipher isn't initialised.
*/
public override int ProcessByte(
byte input,
byte[] output,
int outOff)
{
buf[bufOff++] = input;
if (bufOff == buf.Length)
{
if ((outOff + buf.Length) > output.Length)
throw new DataLengthException("output buffer too short");
bufOff = 0;
return cipher.ProcessBlock(buf, 0, output, outOff);
}
return 0;
}
public override byte[] ProcessByte(
byte input)
{
int outLength = GetUpdateOutputSize(1);
byte[] outBytes = outLength > 0 ? new byte[outLength] : null;
int pos = ProcessByte(input, outBytes, 0);
if (outLength > 0 && pos < outLength)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
return outBytes;
}
public override byte[] ProcessBytes(
byte[] input,
int inOff,
int length)
{
if (input == null)
throw new ArgumentNullException("input");
if (length < 1)
return null;
int outLength = GetUpdateOutputSize(length);
byte[] outBytes = outLength > 0 ? new byte[outLength] : null;
int pos = ProcessBytes(input, inOff, length, outBytes, 0);
if (outLength > 0 && pos < outLength)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
return outBytes;
}
/**
* process an array of bytes, producing output if necessary.
*
* @param in the input byte array.
* @param inOff the offset at which the input data starts.
* @param len the number of bytes to be copied out of the input array.
* @param out the space for any output that might be produced.
* @param outOff the offset from which the output will be copied.
* @return the number of output bytes copied to out.
* @exception DataLengthException if there isn't enough space in out.
* @exception InvalidOperationException if the cipher isn't initialised.
*/
public override int ProcessBytes(
byte[] input,
int inOff,
int length,
byte[] output,
int outOff)
{
if (length < 1)
{
if (length < 0)
throw new ArgumentException("Can't have a negative input length!");
return 0;
}
int blockSize = GetBlockSize();
int outLength = GetUpdateOutputSize(length);
if (outLength > 0)
{
if ((outOff + outLength) > output.Length)
{
throw new DataLengthException("output buffer too short");
}
}
int resultLen = 0;
int gapLen = buf.Length - bufOff;
if (length > gapLen)
{
Array.Copy(input, inOff, buf, bufOff, gapLen);
resultLen += cipher.ProcessBlock(buf, 0, output, outOff);
bufOff = 0;
length -= gapLen;
inOff += gapLen;
while (length > buf.Length)
{
resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen);
length -= blockSize;
inOff += blockSize;
}
}
Array.Copy(input, inOff, buf, bufOff, length);
bufOff += length;
if (bufOff == buf.Length)
{
resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen);
bufOff = 0;
}
return resultLen;
}
public override byte[] DoFinal()
{
byte[] outBytes = EmptyBuffer;
int length = GetOutputSize(0);
if (length > 0)
{
outBytes = new byte[length];
int pos = DoFinal(outBytes, 0);
if (pos < outBytes.Length)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
}
else
{
Reset();
}
return outBytes;
}
public override byte[] DoFinal(
byte[] input,
int inOff,
int inLen)
{
if (input == null)
throw new ArgumentNullException("input");
int length = GetOutputSize(inLen);
byte[] outBytes = EmptyBuffer;
if (length > 0)
{
outBytes = new byte[length];
int pos = (inLen > 0)
? ProcessBytes(input, inOff, inLen, outBytes, 0)
: 0;
pos += DoFinal(outBytes, pos);
if (pos < outBytes.Length)
{
byte[] tmp = new byte[pos];
Array.Copy(outBytes, 0, tmp, 0, pos);
outBytes = tmp;
}
}
else
{
Reset();
}
return outBytes;
}
/**
* Process the last block in the buffer.
*
* @param out the array the block currently being held is copied into.
* @param outOff the offset at which the copying starts.
* @return the number of output bytes copied to out.
* @exception DataLengthException if there is insufficient space in out for
* the output, or the input is not block size aligned and should be.
* @exception InvalidOperationException if the underlying cipher is not
* initialised.
* @exception InvalidCipherTextException if padding is expected and not found.
* @exception DataLengthException if the input is not block size
* aligned.
*/
public override int DoFinal(
byte[] output,
int outOff)
{
if (bufOff != 0)
{
if (!cipher.IsPartialBlockOkay)
{
throw new DataLengthException("data not block size aligned");
}
if (outOff + bufOff > output.Length)
{
throw new DataLengthException("output buffer too short for DoFinal()");
}
// NB: Can't copy directly, or we may write too much output
cipher.ProcessBlock(buf, 0, buf, 0);
Array.Copy(buf, 0, output, outOff, bufOff);
}
int resultLen = bufOff;
Reset();
return resultLen;
}
/**
* Reset the buffer and cipher. After resetting the object is in the same
* state as it was after the last init (if there was one).
*/
public override void Reset()
{
Array.Clear(buf, 0, buf.Length);
bufOff = 0;
cipher.Reset();
}
}
}

View File

@ -1,229 +1,232 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Encodings
{
/**
* this does your basic Pkcs 1 v1.5 padding - whether or not you should be using this
* depends on your application - see Pkcs1 Version 2 for details.
*/
public class Pkcs1Encoding
: IAsymmetricBlockCipher
{
/**
* some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to
* work with one of these set the system property Org.BouncyCastle.Pkcs1.Strict to false.
*/
public const string StrictLengthEnabledProperty = "Org.BouncyCastle.Pkcs1.Strict";
private const int HeaderLength = 10;
/**
* The same effect can be achieved by setting the static property directly
* <p>
* The static property is checked during construction of the encoding object, it is set to
* true by default.
* </p>
*/
public static bool StrictLengthEnabled
{
get { return strictLengthEnabled[0]; }
set { strictLengthEnabled[0] = value; }
}
private static readonly bool[] strictLengthEnabled;
static Pkcs1Encoding()
{
string strictProperty = Platform.GetEnvironmentVariable(StrictLengthEnabledProperty);
strictLengthEnabled = new bool[]{ strictProperty == null || strictProperty.Equals("true")};
}
private SecureRandom random;
private IAsymmetricBlockCipher engine;
private bool forEncryption;
private bool forPrivateKey;
private bool useStrictLength;
/**
* Basic constructor.
* @param cipher
*/
public Pkcs1Encoding(
IAsymmetricBlockCipher cipher)
{
this.engine = cipher;
this.useStrictLength = StrictLengthEnabled;
}
public IAsymmetricBlockCipher GetUnderlyingCipher()
{
return engine;
}
public string AlgorithmName
{
get { return engine.AlgorithmName + "/PKCS1Padding"; }
}
public void Init(
bool forEncryption,
ICipherParameters parameters)
{
AsymmetricKeyParameter kParam;
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)parameters;
this.random = rParam.Random;
kParam = (AsymmetricKeyParameter)rParam.Parameters;
}
else
{
this.random = new SecureRandom();
kParam = (AsymmetricKeyParameter)parameters;
}
engine.Init(forEncryption, parameters);
this.forPrivateKey = kParam.IsPrivate;
this.forEncryption = forEncryption;
}
public int GetInputBlockSize()
{
int baseBlockSize = engine.GetInputBlockSize();
return forEncryption
? baseBlockSize - HeaderLength
: baseBlockSize;
}
public int GetOutputBlockSize()
{
int baseBlockSize = engine.GetOutputBlockSize();
return forEncryption
? baseBlockSize
: baseBlockSize - HeaderLength;
}
public byte[] ProcessBlock(
byte[] input,
int inOff,
int length)
{
return forEncryption
? EncodeBlock(input, inOff, length)
: DecodeBlock(input, inOff, length);
}
private byte[] EncodeBlock(
byte[] input,
int inOff,
int inLen)
{
byte[] block = new byte[engine.GetInputBlockSize()];
if (forPrivateKey)
{
block[0] = 0x01; // type code 1
for (int i = 1; i != block.Length - inLen - 1; i++)
{
block[i] = (byte)0xFF;
}
}
else
{
random.NextBytes(block); // random fill
block[0] = 0x02; // type code 2
//
// a zero byte marks the end of the padding, so all
// the pad bytes must be non-zero.
//
for (int i = 1; i != block.Length - inLen - 1; i++)
{
while (block[i] == 0)
{
block[i] = (byte)random.NextInt();
}
}
}
block[block.Length - inLen - 1] = 0x00; // mark the end of the padding
Array.Copy(input, inOff, block, block.Length - inLen, inLen);
return engine.ProcessBlock(block, 0, block.Length);
}
/**
* @exception InvalidCipherTextException if the decrypted block is not in Pkcs1 format.
*/
private byte[] DecodeBlock(
byte[] input,
int inOff,
int inLen)
{
byte[] block = engine.ProcessBlock(input, inOff, inLen);
if (block.Length < GetOutputBlockSize())
{
throw new InvalidCipherTextException("block truncated");
}
byte type = block[0];
if (type != 1 && type != 2)
{
throw new InvalidCipherTextException("unknown block type");
}
if (useStrictLength && block.Length != engine.GetOutputBlockSize())
{
throw new InvalidCipherTextException("block incorrect size");
}
//
// find and extract the message block.
//
int start;
for (start = 1; start != block.Length; start++)
{
byte pad = block[start];
if (pad == 0)
{
break;
}
if (type == 1 && pad != (byte)0xff)
{
throw new InvalidCipherTextException("block padding incorrect");
}
}
start++; // data should start at the next byte
if (start >= block.Length || start < HeaderLength)
{
throw new InvalidCipherTextException("no data in block");
}
byte[] result = new byte[block.Length - start];
Array.Copy(block, start, result, 0, result.Length);
return result;
}
}
}
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Encodings
{
/**
* this does your basic Pkcs 1 v1.5 padding - whether or not you should be using this
* depends on your application - see Pkcs1 Version 2 for details.
*/
public class Pkcs1Encoding
: IAsymmetricBlockCipher
{
/**
* some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to
* work with one of these set the system property Org.BouncyCastle.Pkcs1.Strict to false.
*/
public const string StrictLengthEnabledProperty = "Org.BouncyCastle.Pkcs1.Strict";
private const int HeaderLength = 10;
/**
* The same effect can be achieved by setting the static property directly
* <p>
* The static property is checked during construction of the encoding object, it is set to
* true by default.
* </p>
*/
public static bool StrictLengthEnabled
{
get { return strictLengthEnabled[0]; }
set { strictLengthEnabled[0] = value; }
}
private static readonly bool[] strictLengthEnabled;
static Pkcs1Encoding()
{
string strictProperty = Platform.GetEnvironmentVariable(StrictLengthEnabledProperty);
strictLengthEnabled = new bool[]{ strictProperty == null || strictProperty.Equals("true")};
}
private SecureRandom random;
private IAsymmetricBlockCipher engine;
private bool forEncryption;
private bool forPrivateKey;
private bool useStrictLength;
/**
* Basic constructor.
* @param cipher
*/
public Pkcs1Encoding(
IAsymmetricBlockCipher cipher)
{
this.engine = cipher;
this.useStrictLength = StrictLengthEnabled;
}
public IAsymmetricBlockCipher GetUnderlyingCipher()
{
return engine;
}
public string AlgorithmName
{
get { return engine.AlgorithmName + "/PKCS1Padding"; }
}
public void Init(
bool forEncryption,
ICipherParameters parameters)
{
AsymmetricKeyParameter kParam;
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)parameters;
this.random = rParam.Random;
kParam = (AsymmetricKeyParameter)rParam.Parameters;
}
else
{
this.random = new SecureRandom();
kParam = (AsymmetricKeyParameter)parameters;
}
engine.Init(forEncryption, parameters);
this.forPrivateKey = kParam.IsPrivate;
this.forEncryption = forEncryption;
}
public int GetInputBlockSize()
{
int baseBlockSize = engine.GetInputBlockSize();
return forEncryption
? baseBlockSize - HeaderLength
: baseBlockSize;
}
public int GetOutputBlockSize()
{
int baseBlockSize = engine.GetOutputBlockSize();
return forEncryption
? baseBlockSize
: baseBlockSize - HeaderLength;
}
public byte[] ProcessBlock(
byte[] input,
int inOff,
int length)
{
return forEncryption
? EncodeBlock(input, inOff, length)
: DecodeBlock(input, inOff, length);
}
private byte[] EncodeBlock(
byte[] input,
int inOff,
int inLen)
{
if (inLen > GetInputBlockSize())
throw new ArgumentException("input data too large", "inLen");
byte[] block = new byte[engine.GetInputBlockSize()];
if (forPrivateKey)
{
block[0] = 0x01; // type code 1
for (int i = 1; i != block.Length - inLen - 1; i++)
{
block[i] = (byte)0xFF;
}
}
else
{
random.NextBytes(block); // random fill
block[0] = 0x02; // type code 2
//
// a zero byte marks the end of the padding, so all
// the pad bytes must be non-zero.
//
for (int i = 1; i != block.Length - inLen - 1; i++)
{
while (block[i] == 0)
{
block[i] = (byte)random.NextInt();
}
}
}
block[block.Length - inLen - 1] = 0x00; // mark the end of the padding
Array.Copy(input, inOff, block, block.Length - inLen, inLen);
return engine.ProcessBlock(block, 0, block.Length);
}
/**
* @exception InvalidCipherTextException if the decrypted block is not in Pkcs1 format.
*/
private byte[] DecodeBlock(
byte[] input,
int inOff,
int inLen)
{
byte[] block = engine.ProcessBlock(input, inOff, inLen);
if (block.Length < GetOutputBlockSize())
{
throw new InvalidCipherTextException("block truncated");
}
byte type = block[0];
if (type != 1 && type != 2)
{
throw new InvalidCipherTextException("unknown block type");
}
if (useStrictLength && block.Length != engine.GetOutputBlockSize())
{
throw new InvalidCipherTextException("block incorrect size");
}
//
// find and extract the message block.
//
int start;
for (start = 1; start != block.Length; start++)
{
byte pad = block[start];
if (pad == 0)
{
break;
}
if (type == 1 && pad != (byte)0xff)
{
throw new InvalidCipherTextException("block padding incorrect");
}
}
start++; // data should start at the next byte
if (start >= block.Length || start < HeaderLength)
{
throw new InvalidCipherTextException("no data in block");
}
byte[] result = new byte[block.Length - start];
Array.Copy(block, start, result, 0, result.Length);
return result;
}
}
}

View File

@ -0,0 +1,581 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Engines
{
/**
* Camellia - based on RFC 3713, smaller implementation, about half the size of CamelliaEngine.
*/
public class CamelliaLightEngine
: IBlockCipher
{
private const int BLOCK_SIZE = 16;
// private const int MASK8 = 0xff;
private bool initialised;
private bool _keyis128;
private uint[] subkey = new uint[24 * 4];
private uint[] kw = new uint[4 * 2]; // for whitening
private uint[] ke = new uint[6 * 2]; // for FL and FL^(-1)
private uint[] state = new uint[4]; // for encryption and decryption
private static readonly uint[] SIGMA = {
0xa09e667f, 0x3bcc908b,
0xb67ae858, 0x4caa73b2,
0xc6ef372f, 0xe94f82be,
0x54ff53a5, 0xf1d36f1c,
0x10e527fa, 0xde682d1d,
0xb05688c2, 0xb3e6c1fd
};
/*
*
* S-box data
*
*/
private static readonly byte[] SBOX1 = {
(byte)112, (byte)130, (byte)44, (byte)236,
(byte)179, (byte)39, (byte)192, (byte)229,
(byte)228, (byte)133, (byte)87, (byte)53,
(byte)234, (byte)12, (byte)174, (byte)65,
(byte)35, (byte)239, (byte)107, (byte)147,
(byte)69, (byte)25, (byte)165, (byte)33,
(byte)237, (byte)14, (byte)79, (byte)78,
(byte)29, (byte)101, (byte)146, (byte)189,
(byte)134, (byte)184, (byte)175, (byte)143,
(byte)124, (byte)235, (byte)31, (byte)206,
(byte)62, (byte)48, (byte)220, (byte)95,
(byte)94, (byte)197, (byte)11, (byte)26,
(byte)166, (byte)225, (byte)57, (byte)202,
(byte)213, (byte)71, (byte)93, (byte)61,
(byte)217, (byte)1, (byte)90, (byte)214,
(byte)81, (byte)86, (byte)108, (byte)77,
(byte)139, (byte)13, (byte)154, (byte)102,
(byte)251, (byte)204, (byte)176, (byte)45,
(byte)116, (byte)18, (byte)43, (byte)32,
(byte)240, (byte)177, (byte)132, (byte)153,
(byte)223, (byte)76, (byte)203, (byte)194,
(byte)52, (byte)126, (byte)118, (byte)5,
(byte)109, (byte)183, (byte)169, (byte)49,
(byte)209, (byte)23, (byte)4, (byte)215,
(byte)20, (byte)88, (byte)58, (byte)97,
(byte)222, (byte)27, (byte)17, (byte)28,
(byte)50, (byte)15, (byte)156, (byte)22,
(byte)83, (byte)24, (byte)242, (byte)34,
(byte)254, (byte)68, (byte)207, (byte)178,
(byte)195, (byte)181, (byte)122, (byte)145,
(byte)36, (byte)8, (byte)232, (byte)168,
(byte)96, (byte)252, (byte)105, (byte)80,
(byte)170, (byte)208, (byte)160, (byte)125,
(byte)161, (byte)137, (byte)98, (byte)151,
(byte)84, (byte)91, (byte)30, (byte)149,
(byte)224, (byte)255, (byte)100, (byte)210,
(byte)16, (byte)196, (byte)0, (byte)72,
(byte)163, (byte)247, (byte)117, (byte)219,
(byte)138, (byte)3, (byte)230, (byte)218,
(byte)9, (byte)63, (byte)221, (byte)148,
(byte)135, (byte)92, (byte)131, (byte)2,
(byte)205, (byte)74, (byte)144, (byte)51,
(byte)115, (byte)103, (byte)246, (byte)243,
(byte)157, (byte)127, (byte)191, (byte)226,
(byte)82, (byte)155, (byte)216, (byte)38,
(byte)200, (byte)55, (byte)198, (byte)59,
(byte)129, (byte)150, (byte)111, (byte)75,
(byte)19, (byte)190, (byte)99, (byte)46,
(byte)233, (byte)121, (byte)167, (byte)140,
(byte)159, (byte)110, (byte)188, (byte)142,
(byte)41, (byte)245, (byte)249, (byte)182,
(byte)47, (byte)253, (byte)180, (byte)89,
(byte)120, (byte)152, (byte)6, (byte)106,
(byte)231, (byte)70, (byte)113, (byte)186,
(byte)212, (byte)37, (byte)171, (byte)66,
(byte)136, (byte)162, (byte)141, (byte)250,
(byte)114, (byte)7, (byte)185, (byte)85,
(byte)248, (byte)238, (byte)172, (byte)10,
(byte)54, (byte)73, (byte)42, (byte)104,
(byte)60, (byte)56, (byte)241, (byte)164,
(byte)64, (byte)40, (byte)211, (byte)123,
(byte)187, (byte)201, (byte)67, (byte)193,
(byte)21, (byte)227, (byte)173, (byte)244,
(byte)119, (byte)199, (byte)128, (byte)158
};
private static uint rightRotate(uint x, int s)
{
return ((x >> s) + (x << (32 - s)));
}
private static uint leftRotate(uint x, int s)
{
return (x << s) + (x >> (32 - s));
}
private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot));
ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot));
ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot));
ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot));
ki[0 + ioff] = ko[0 + ooff];
ki[1 + ioff] = ko[1 + ooff];
ki[2 + ioff] = ko[2 + ooff];
ki[3 + ioff] = ko[3 + ooff];
}
private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot));
ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot));
ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot));
ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot));
ki[0 + ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[0 + ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot));
ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot));
ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot));
ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
ki[0 + ioff] = ko[0 + ooff];
ki[1 + ioff] = ko[1 + ooff];
ki[2 + ioff] = ko[2 + ooff];
ki[3 + ioff] = ko[3 + ooff];
}
private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot));
ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot));
ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot));
ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
ki[0 + ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[0 + ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static uint bytes2uint(byte[] src, int offset)
{
uint word = 0;
for (int i = 0; i < 4; i++)
{
word = (word << 8) + (uint)src[i + offset];
}
return word;
}
private static void uint2bytes(uint word, byte[] dst, int offset)
{
for (int i = 0; i < 4; i++)
{
dst[(3 - i) + offset] = (byte)word;
word >>= 8;
}
}
private byte lRot8(byte v, int rot)
{
return (byte)(((uint)v << rot) | ((uint)v >> (8 - rot)));
}
private uint sbox2(int x)
{
return (uint)lRot8(SBOX1[x], 1);
}
private uint sbox3(int x)
{
return (uint)lRot8(SBOX1[x], 7);
}
private uint sbox4(int x)
{
return (uint)SBOX1[lRot8((byte)x, 1)];
}
private void camelliaF2(uint[] s, uint[] skey, int keyoff)
{
uint t1, t2, u, v;
t1 = s[0] ^ skey[0 + keyoff];
u = sbox4((byte)t1);
u |= (sbox3((byte)(t1 >> 8)) << 8);
u |= (sbox2((byte)(t1 >> 16)) << 16);
u |= ((uint)(SBOX1[(byte)(t1 >> 24)]) << 24);
t2 = s[1] ^ skey[1 + keyoff];
v = (uint)SBOX1[(byte)t2];
v |= (sbox4((byte)(t2 >> 8)) << 8);
v |= (sbox3((byte)(t2 >> 16)) << 16);
v |= (sbox2((byte)(t2 >> 24)) << 24);
v = leftRotate(v, 8);
u ^= v;
v = leftRotate(v, 8) ^ u;
u = rightRotate(u, 8) ^ v;
s[2] ^= leftRotate(v, 16) ^ u;
s[3] ^= leftRotate(u, 8);
t1 = s[2] ^ skey[2 + keyoff];
u = sbox4((byte)t1);
u |= sbox3((byte)(t1 >> 8)) << 8;
u |= sbox2((byte)(t1 >> 16)) << 16;
u |= ((uint)SBOX1[(byte)(t1 >> 24)]) << 24;
t2 = s[3] ^ skey[3 + keyoff];
v = (uint)SBOX1[(byte)t2];
v |= sbox4((byte)(t2 >> 8)) << 8;
v |= sbox3((byte)(t2 >> 16)) << 16;
v |= sbox2((byte)(t2 >> 24)) << 24;
v = leftRotate(v, 8);
u ^= v;
v = leftRotate(v, 8) ^ u;
u = rightRotate(u, 8) ^ v;
s[0] ^= leftRotate(v, 16) ^ u;
s[1] ^= leftRotate(u, 8);
}
private void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
{
s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1);
s[0] ^= fkey[1 + keyoff] | s[1];
s[2] ^= fkey[3 + keyoff] | s[3];
s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1);
}
private void setKey(bool forEncryption, byte[] key)
{
uint[] k = new uint[8];
uint[] ka = new uint[4];
uint[] kb = new uint[4];
uint[] t = new uint[4];
switch (key.Length)
{
case 16:
_keyis128 = true;
k[0] = bytes2uint(key, 0);
k[1] = bytes2uint(key, 4);
k[2] = bytes2uint(key, 8);
k[3] = bytes2uint(key, 12);
k[4] = k[5] = k[6] = k[7] = 0;
break;
case 24:
k[0] = bytes2uint(key, 0);
k[1] = bytes2uint(key, 4);
k[2] = bytes2uint(key, 8);
k[3] = bytes2uint(key, 12);
k[4] = bytes2uint(key, 16);
k[5] = bytes2uint(key, 20);
k[6] = ~k[4];
k[7] = ~k[5];
_keyis128 = false;
break;
case 32:
k[0] = bytes2uint(key, 0);
k[1] = bytes2uint(key, 4);
k[2] = bytes2uint(key, 8);
k[3] = bytes2uint(key, 12);
k[4] = bytes2uint(key, 16);
k[5] = bytes2uint(key, 20);
k[6] = bytes2uint(key, 24);
k[7] = bytes2uint(key, 28);
_keyis128 = false;
break;
default:
throw new ArgumentException("key sizes are only 16/24/32 bytes.");
}
for (int i = 0; i < 4; i++)
{
ka[i] = k[i] ^ k[i + 4];
}
/* compute KA */
camelliaF2(ka, SIGMA, 0);
for (int i = 0; i < 4; i++)
{
ka[i] ^= k[i];
}
camelliaF2(ka, SIGMA, 4);
if (_keyis128)
{
if (forEncryption)
{
/* KL dependant keys */
kw[0] = k[0];
kw[1] = k[1];
kw[2] = k[2];
kw[3] = k[3];
roldq(15, k, 0, subkey, 4);
roldq(30, k, 0, subkey, 12);
roldq(15, k, 0, t, 0);
subkey[18] = t[2];
subkey[19] = t[3];
roldq(17, k, 0, ke, 4);
roldq(17, k, 0, subkey, 24);
roldq(17, k, 0, subkey, 32);
/* KA dependant keys */
subkey[0] = ka[0];
subkey[1] = ka[1];
subkey[2] = ka[2];
subkey[3] = ka[3];
roldq(15, ka, 0, subkey, 8);
roldq(15, ka, 0, ke, 0);
roldq(15, ka, 0, t, 0);
subkey[16] = t[0];
subkey[17] = t[1];
roldq(15, ka, 0, subkey, 20);
roldqo32(34, ka, 0, subkey, 28);
roldq(17, ka, 0, kw, 4);
}
else
{ // decryption
/* KL dependant keys */
kw[4] = k[0];
kw[5] = k[1];
kw[6] = k[2];
kw[7] = k[3];
decroldq(15, k, 0, subkey, 28);
decroldq(30, k, 0, subkey, 20);
decroldq(15, k, 0, t, 0);
subkey[16] = t[0];
subkey[17] = t[1];
decroldq(17, k, 0, ke, 0);
decroldq(17, k, 0, subkey, 8);
decroldq(17, k, 0, subkey, 0);
/* KA dependant keys */
subkey[34] = ka[0];
subkey[35] = ka[1];
subkey[32] = ka[2];
subkey[33] = ka[3];
decroldq(15, ka, 0, subkey, 24);
decroldq(15, ka, 0, ke, 4);
decroldq(15, ka, 0, t, 0);
subkey[18] = t[2];
subkey[19] = t[3];
decroldq(15, ka, 0, subkey, 12);
decroldqo32(34, ka, 0, subkey, 4);
roldq(17, ka, 0, kw, 0);
}
}
else
{ // 192bit or 256bit
/* compute KB */
for (int i = 0; i < 4; i++)
{
kb[i] = ka[i] ^ k[i + 4];
}
camelliaF2(kb, SIGMA, 8);
if (forEncryption)
{
/* KL dependant keys */
kw[0] = k[0];
kw[1] = k[1];
kw[2] = k[2];
kw[3] = k[3];
roldqo32(45, k, 0, subkey, 16);
roldq(15, k, 0, ke, 4);
roldq(17, k, 0, subkey, 32);
roldqo32(34, k, 0, subkey, 44);
/* KR dependant keys */
roldq(15, k, 4, subkey, 4);
roldq(15, k, 4, ke, 0);
roldq(30, k, 4, subkey, 24);
roldqo32(34, k, 4, subkey, 36);
/* KA dependant keys */
roldq(15, ka, 0, subkey, 8);
roldq(30, ka, 0, subkey, 20);
/* 32bit rotation */
ke[8] = ka[1];
ke[9] = ka[2];
ke[10] = ka[3];
ke[11] = ka[0];
roldqo32(49, ka, 0, subkey, 40);
/* KB dependant keys */
subkey[0] = kb[0];
subkey[1] = kb[1];
subkey[2] = kb[2];
subkey[3] = kb[3];
roldq(30, kb, 0, subkey, 12);
roldq(30, kb, 0, subkey, 28);
roldqo32(51, kb, 0, kw, 4);
}
else
{ // decryption
/* KL dependant keys */
kw[4] = k[0];
kw[5] = k[1];
kw[6] = k[2];
kw[7] = k[3];
decroldqo32(45, k, 0, subkey, 28);
decroldq(15, k, 0, ke, 4);
decroldq(17, k, 0, subkey, 12);
decroldqo32(34, k, 0, subkey, 0);
/* KR dependant keys */
decroldq(15, k, 4, subkey, 40);
decroldq(15, k, 4, ke, 8);
decroldq(30, k, 4, subkey, 20);
decroldqo32(34, k, 4, subkey, 8);
/* KA dependant keys */
decroldq(15, ka, 0, subkey, 36);
decroldq(30, ka, 0, subkey, 24);
/* 32bit rotation */
ke[2] = ka[1];
ke[3] = ka[2];
ke[0] = ka[3];
ke[1] = ka[0];
decroldqo32(49, ka, 0, subkey, 4);
/* KB dependant keys */
subkey[46] = kb[0];
subkey[47] = kb[1];
subkey[44] = kb[2];
subkey[45] = kb[3];
decroldq(30, kb, 0, subkey, 32);
decroldq(30, kb, 0, subkey, 16);
roldqo32(51, kb, 0, kw, 0);
}
}
}
private int processBlock128(byte[] input, int inOff, byte[] output, int outOff)
{
for (int i = 0; i < 4; i++)
{
state[i] = bytes2uint(input, inOff + (i * 4));
state[i] ^= kw[i];
}
camelliaF2(state, subkey, 0);
camelliaF2(state, subkey, 4);
camelliaF2(state, subkey, 8);
camelliaFLs(state, ke, 0);
camelliaF2(state, subkey, 12);
camelliaF2(state, subkey, 16);
camelliaF2(state, subkey, 20);
camelliaFLs(state, ke, 4);
camelliaF2(state, subkey, 24);
camelliaF2(state, subkey, 28);
camelliaF2(state, subkey, 32);
state[2] ^= kw[4];
state[3] ^= kw[5];
state[0] ^= kw[6];
state[1] ^= kw[7];
uint2bytes(state[2], output, outOff);
uint2bytes(state[3], output, outOff + 4);
uint2bytes(state[0], output, outOff + 8);
uint2bytes(state[1], output, outOff + 12);
return BLOCK_SIZE;
}
private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
{
for (int i = 0; i < 4; i++)
{
state[i] = bytes2uint(input, inOff + (i * 4));
state[i] ^= kw[i];
}
camelliaF2(state, subkey, 0);
camelliaF2(state, subkey, 4);
camelliaF2(state, subkey, 8);
camelliaFLs(state, ke, 0);
camelliaF2(state, subkey, 12);
camelliaF2(state, subkey, 16);
camelliaF2(state, subkey, 20);
camelliaFLs(state, ke, 4);
camelliaF2(state, subkey, 24);
camelliaF2(state, subkey, 28);
camelliaF2(state, subkey, 32);
camelliaFLs(state, ke, 8);
camelliaF2(state, subkey, 36);
camelliaF2(state, subkey, 40);
camelliaF2(state, subkey, 44);
state[2] ^= kw[4];
state[3] ^= kw[5];
state[0] ^= kw[6];
state[1] ^= kw[7];
uint2bytes(state[2], output, outOff);
uint2bytes(state[3], output, outOff + 4);
uint2bytes(state[0], output, outOff + 8);
uint2bytes(state[1], output, outOff + 12);
return BLOCK_SIZE;
}
public CamelliaLightEngine()
{
initialised = false;
}
public string AlgorithmName
{
get { return "Camellia"; }
}
public bool IsPartialBlockOkay
{
get { return false; }
}
public int GetBlockSize()
{
return BLOCK_SIZE;
}
public void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException("only simple KeyParameter expected.");
setKey(forEncryption, ((KeyParameter)parameters).GetKey());
initialised = true;
}
public int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
int outOff)
{
if (!initialised)
throw new InvalidOperationException("Camellia engine not initialised");
if ((inOff + BLOCK_SIZE) > input.Length)
throw new DataLengthException("input buffer too short");
if ((outOff + BLOCK_SIZE) > output.Length)
throw new DataLengthException("output buffer too short");
if (_keyis128)
{
return processBlock128(input, inOff, output, outOff);
}
else
{
return processBlock192or256(input, inOff, output, outOff);
}
}
public void Reset()
{
}
}
}

View File

@ -1,224 +1,234 @@
using System;
using System.Diagnostics;
using System.IO;
using Org.BouncyCastle.Crypto;
namespace Org.BouncyCastle.Crypto.IO
{
public class CipherStream : Stream
{
internal Stream stream;
internal IBufferedCipher inCipher, outCipher;
private byte[] mInBuf;
private int mInPos;
private bool inStreamEnded;
public CipherStream(
Stream stream,
IBufferedCipher readCipher,
IBufferedCipher writeCipher)
{
this.stream = stream;
if (readCipher != null)
{
this.inCipher = readCipher;
mInBuf = null;
}
if (writeCipher != null)
{
this.outCipher = writeCipher;
}
}
public IBufferedCipher ReadCipher
{
get { return inCipher; }
}
public IBufferedCipher WriteCipher
{
get { return outCipher; }
}
public override int ReadByte()
{
if (inCipher == null)
{
return stream.ReadByte();
}
if (mInBuf == null || mInPos >= mInBuf.Length)
{
if (!FillInBuf())
{
return -1;
}
}
return mInBuf[mInPos++];
}
public override int Read(byte[] buffer, int offset, int count)
{
if (inCipher == null)
{
return stream.Read(buffer, offset, count);
}
// int pos = offset;
// int end = offset + count;
// try
// {
// while (pos < end)
// {
// if (mInPos >= mInBufEnd && !FillInBuf()) break;
//
// int len = System.Math.Min(end - pos, mInBufEnd - mInPos);
// Array.Copy(mInBuf, mInPos, buffer, pos, len);
// mInPos += len;
// pos += len;
// }
// }
// catch (IOException)
// {
// if (pos == offset) throw;
// }
// return pos - offset;
// TODO Optimise
int i = 0;
while (i < count)
{
int c = ReadByte();
if (c < 0) break;
buffer[offset + i++] = (byte) c;
}
return i;
}
private bool FillInBuf()
{
if (inStreamEnded)
{
return false;
}
mInPos = 0;
do
{
mInBuf = readAndProcessBlock();
}
while (!inStreamEnded && mInBuf == null);
return mInBuf != null;
}
private byte[] readAndProcessBlock()
{
int blockSize = inCipher.GetBlockSize();
int readSize = (blockSize == 0) ? 256 : blockSize;
byte[] block = new byte[readSize];
int numRead = 0;
do
{
int count = stream.Read(block, numRead, block.Length - numRead);
if (count < 1)
{
inStreamEnded = true;
break;
}
numRead += count;
}
while (numRead < block.Length);
Debug.Assert(inStreamEnded || numRead == block.Length);
byte[] bytes = inStreamEnded
? inCipher.DoFinal(block, 0, numRead)
: inCipher.ProcessBytes(block);
if (bytes != null && bytes.Length == 0)
{
bytes = null;
}
return bytes;
}
public override void Write(byte[] buffer, int offset, int count)
{
Debug.Assert(buffer != null);
Debug.Assert(0 <= offset && offset <= buffer.Length);
Debug.Assert(count >= 0);
int end = offset + count;
Debug.Assert(0 <= end && end <= buffer.Length);
if (outCipher == null)
{
stream.Write(buffer, offset, count);
return;
}
byte[] data = outCipher.ProcessBytes(buffer, offset, count);
if (data != null)
{
stream.Write(data, 0, data.Length);
}
}
public override void WriteByte(
byte value)
{
if (outCipher == null)
{
stream.WriteByte(value);
return;
}
byte[] data = outCipher.ProcessByte(value);
if (data != null)
{
stream.Write(data, 0, data.Length);
}
}
public override bool CanRead
{
get { return stream.CanRead && (inCipher != null); }
}
public override bool CanWrite
{
get { return stream.CanWrite && (outCipher != null); }
}
public override bool CanSeek
{
get { return false; }
}
public sealed override long Length { get { throw new NotSupportedException(); } }
public sealed override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public override void Close()
{
if (outCipher != null)
{
byte[] data = outCipher.DoFinal();
stream.Write(data, 0, data.Length);
stream.Flush();
}
stream.Close();
}
public override void Flush()
{
// Note: outCipher.DoFinal is only called during Close()
stream.Flush();
}
public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); }
public sealed override void SetLength(long value) { throw new NotSupportedException(); }
}
}
using System;
using System.Diagnostics;
using System.IO;
using Org.BouncyCastle.Crypto;
namespace Org.BouncyCastle.Crypto.IO
{
public class CipherStream
: Stream
{
internal Stream stream;
internal IBufferedCipher inCipher, outCipher;
private byte[] mInBuf;
private int mInPos;
private bool inStreamEnded;
public CipherStream(
Stream stream,
IBufferedCipher readCipher,
IBufferedCipher writeCipher)
{
this.stream = stream;
if (readCipher != null)
{
this.inCipher = readCipher;
mInBuf = null;
}
if (writeCipher != null)
{
this.outCipher = writeCipher;
}
}
public IBufferedCipher ReadCipher
{
get { return inCipher; }
}
public IBufferedCipher WriteCipher
{
get { return outCipher; }
}
public override int ReadByte()
{
if (inCipher == null)
return stream.ReadByte();
if (mInBuf == null || mInPos >= mInBuf.Length)
{
if (!FillInBuf())
return -1;
}
return mInBuf[mInPos++];
}
public override int Read(
byte[] buffer,
int offset,
int count)
{
if (inCipher == null)
return stream.Read(buffer, offset, count);
int num = 0;
while (num < count)
{
if (mInBuf == null || mInPos >= mInBuf.Length)
{
if (!FillInBuf())
break;
}
int numToCopy = System.Math.Min(count - num, mInBuf.Length - mInPos);
Array.Copy(mInBuf, mInPos, buffer, offset + num, numToCopy);
mInPos += numToCopy;
num += numToCopy;
}
return num;
}
private bool FillInBuf()
{
if (inStreamEnded)
return false;
mInPos = 0;
do
{
mInBuf = ReadAndProcessBlock();
}
while (!inStreamEnded && mInBuf == null);
return mInBuf != null;
}
private byte[] ReadAndProcessBlock()
{
int blockSize = inCipher.GetBlockSize();
int readSize = (blockSize == 0) ? 256 : blockSize;
byte[] block = new byte[readSize];
int numRead = 0;
do
{
int count = stream.Read(block, numRead, block.Length - numRead);
if (count < 1)
{
inStreamEnded = true;
break;
}
numRead += count;
}
while (numRead < block.Length);
Debug.Assert(inStreamEnded || numRead == block.Length);
byte[] bytes = inStreamEnded
? inCipher.DoFinal(block, 0, numRead)
: inCipher.ProcessBytes(block);
if (bytes != null && bytes.Length == 0)
{
bytes = null;
}
return bytes;
}
public override void Write(
byte[] buffer,
int offset,
int count)
{
Debug.Assert(buffer != null);
Debug.Assert(0 <= offset && offset <= buffer.Length);
Debug.Assert(count >= 0);
int end = offset + count;
Debug.Assert(0 <= end && end <= buffer.Length);
if (outCipher == null)
{
stream.Write(buffer, offset, count);
return;
}
byte[] data = outCipher.ProcessBytes(buffer, offset, count);
if (data != null)
{
stream.Write(data, 0, data.Length);
}
}
public override void WriteByte(
byte b)
{
if (outCipher == null)
{
stream.WriteByte(b);
return;
}
byte[] data = outCipher.ProcessByte(b);
if (data != null)
{
stream.Write(data, 0, data.Length);
}
}
public override bool CanRead
{
get { return stream.CanRead && (inCipher != null); }
}
public override bool CanWrite
{
get { return stream.CanWrite && (outCipher != null); }
}
public override bool CanSeek
{
get { return false; }
}
public sealed override long Length
{
get { throw new NotSupportedException(); }
}
public sealed override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public override void Close()
{
if (outCipher != null)
{
byte[] data = outCipher.DoFinal();
stream.Write(data, 0, data.Length);
stream.Flush();
}
stream.Close();
}
public override void Flush()
{
// Note: outCipher.DoFinal is only called during Close()
stream.Flush();
}
public sealed override long Seek(
long offset,
SeekOrigin origin)
{
throw new NotSupportedException();
}
public sealed override void SetLength(
long length)
{
throw new NotSupportedException();
}
}
}

View File

@ -1,77 +1,79 @@
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Paddings
{
/**
* A padder that adds Pkcs7/Pkcs5 padding to a block.
*/
public class Pkcs7Padding: IBlockCipherPadding
{
/**
* Initialise the padder.
*
* @param random - a SecureRandom if available.
*/
public void Init(SecureRandom random)
{
// nothing to do.
}
/**
* Return the name of the algorithm the cipher implements.
*
* @return the name of the algorithm the cipher implements.
*/
public string PaddingName
{
get { return "PKCS7"; }
}
/**
* add the pad bytes to the passed in block, returning the
* number of bytes added.
*/
public int AddPadding(
byte[] input,
int inOff)
{
byte code = (byte)(input.Length - inOff);
while (inOff < input.Length)
{
input[inOff] = code;
inOff++;
}
return code;
}
/**
* return the number of pad bytes present in the block.
*/
public int PadCount(
byte[] input)
{
int count = (int) input[input.Length - 1];
if (count < 1 || count > input.Length)
{
throw new InvalidCipherTextException("pad block corrupted");
}
for (int i = 1; i <= count; i++)
{
if (input[input.Length - i] != count)
{
throw new InvalidCipherTextException("pad block corrupted");
}
}
return count;
}
}
}
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Paddings
{
/**
* A padder that adds Pkcs7/Pkcs5 padding to a block.
*/
public class Pkcs7Padding
: IBlockCipherPadding
{
/**
* Initialise the padder.
*
* @param random - a SecureRandom if available.
*/
public void Init(
SecureRandom random)
{
// nothing to do.
}
/**
* Return the name of the algorithm the cipher implements.
*
* @return the name of the algorithm the cipher implements.
*/
public string PaddingName
{
get { return "PKCS7"; }
}
/**
* add the pad bytes to the passed in block, returning the
* number of bytes added.
*/
public int AddPadding(
byte[] input,
int inOff)
{
byte code = (byte)(input.Length - inOff);
while (inOff < input.Length)
{
input[inOff] = code;
inOff++;
}
return code;
}
/**
* return the number of pad bytes present in the block.
*/
public int PadCount(
byte[] input)
{
int count = (int) input[input.Length - 1];
if (count < 1 || count > input.Length)
{
throw new InvalidCipherTextException("pad block corrupted");
}
for (int i = 1; i <= count; i++)
{
if (input[input.Length - i] != count)
{
throw new InvalidCipherTextException("pad block corrupted");
}
}
return count;
}
}
}

View File

@ -1,107 +1,129 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
namespace Org.BouncyCastle.Crypto.Prng
{
/**
* Random generation based on the digest with counter. Calling addSeedMaterial will
* always increase the entropy of the hash.
* <p>
* Internal access to the digest is syncrhonized so a single one of these can be shared.
* </p>
*/
public class DigestRandomGenerator
: IRandomGenerator
{
private long counter;
private IDigest digest;
private byte[] state;
public DigestRandomGenerator(
IDigest digest)
{
this.digest = digest;
this.state = new byte[digest.GetDigestSize()];
this.counter = 1;
}
public void AddSeedMaterial(
byte[] inSeed)
{
lock (this)
{
DigestUpdate(inSeed);
}
}
public void AddSeedMaterial(
long rSeed)
{
lock (this)
{
for (int i = 0; i != 8; i++)
{
DigestUpdate((byte)rSeed);
// rSeed >>>= 8;
rSeed >>= 8;
}
}
}
public void NextBytes(
byte[] bytes)
{
NextBytes(bytes, 0, bytes.Length);
}
public void NextBytes(
byte[] bytes,
int start,
int len)
{
lock (this)
{
int stateOff = 0;
DigestDoFinal(state);
int end = start + len;
for (int i = start; i < end; ++i)
{
if (stateOff == state.Length)
{
DigestUpdate(counter++);
DigestUpdate(state);
DigestDoFinal(state);
stateOff = 0;
}
bytes[i] = state[stateOff++];
}
DigestUpdate(counter++);
DigestUpdate(state);
}
}
private void DigestUpdate(long seed)
{
for (int i = 0; i != 8; i++)
{
digest.Update((byte)seed);
// seed >>>= 8;
seed >>= 8;
}
}
private void DigestUpdate(byte[] inSeed)
{
digest.BlockUpdate(inSeed, 0, inSeed.Length);
}
private void DigestDoFinal(byte[] result)
{
digest.DoFinal(result, 0);
}
}
}
using System;
using Org.BouncyCastle.Crypto.Digests;
namespace Org.BouncyCastle.Crypto.Prng
{
/**
* Random generation based on the digest with counter. Calling AddSeedMaterial will
* always increase the entropy of the hash.
* <p>
* Internal access to the digest is synchronized so a single one of these can be shared.
* </p>
*/
public class DigestRandomGenerator
: IRandomGenerator
{
private const long CYCLE_COUNT = 10;
private long stateCounter;
private long seedCounter;
private IDigest digest;
private byte[] state;
private byte[] seed;
public DigestRandomGenerator(
IDigest digest)
{
this.digest = digest;
this.seed = new byte[digest.GetDigestSize()];
this.seedCounter = 1;
this.state = new byte[digest.GetDigestSize()];
this.stateCounter = 1;
}
public void AddSeedMaterial(
byte[] inSeed)
{
lock (this)
{
DigestUpdate(inSeed);
DigestUpdate(seed);
DigestDoFinal(seed);
}
}
public void AddSeedMaterial(
long rSeed)
{
lock (this)
{
DigestAddCounter(rSeed);
DigestUpdate(seed);
DigestDoFinal(seed);
}
}
public void NextBytes(
byte[] bytes)
{
NextBytes(bytes, 0, bytes.Length);
}
public void NextBytes(
byte[] bytes,
int start,
int len)
{
lock (this)
{
int stateOff = 0;
GenerateState();
int end = start + len;
for (int i = start; i < end; ++i)
{
if (stateOff == state.Length)
{
GenerateState();
stateOff = 0;
}
bytes[i] = state[stateOff++];
}
}
}
private void CycleSeed()
{
DigestUpdate(seed);
DigestAddCounter(seedCounter++);
DigestDoFinal(seed);
}
private void GenerateState()
{
DigestAddCounter(stateCounter++);
DigestUpdate(state);
DigestUpdate(seed);
DigestDoFinal(state);
if ((stateCounter % CYCLE_COUNT) == 0)
{
CycleSeed();
}
}
private void DigestAddCounter(long seedVal)
{
ulong seed = (ulong)seedVal;
for (int i = 0; i != 8; i++)
{
digest.Update((byte)seed);
seed >>= 8;
}
}
private void DigestUpdate(byte[] inSeed)
{
digest.BlockUpdate(inSeed, 0, inSeed.Length);
}
private void DigestDoFinal(byte[] result)
{
digest.DoFinal(result, 0);
}
}
}

View File

@ -1,150 +1,156 @@
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* EC-DSA as described in X9.62
*/
public class ECDsaSigner
: IDsa
{
private ECKeyParameters key;
private SecureRandom random;
public string AlgorithmName
{
get { return "ECDSA"; }
}
public void Init(
bool forSigning,
ICipherParameters parameters)
{
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom) parameters;
this.random = rParam.Random;
parameters = rParam.Parameters;
}
else
{
this.random = new SecureRandom();
}
if (!(parameters is ECPrivateKeyParameters))
throw new InvalidKeyException("EC private key required for signing");
this.key = (ECPrivateKeyParameters) parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
throw new InvalidKeyException("EC public key required for verification");
this.key = (ECPublicKeyParameters) parameters;
}
}
// 5.3 pg 28
/**
* Generate a signature for the given message using the key we were
* initialised with. For conventional DSA the message should be a SHA-1
* hash of the message of interest.
*
* @param message the message that will be verified later.
*/
public BigInteger[] GenerateSignature(
byte[] message)
{
BigInteger n = key.Parameters.N;
BigInteger e = calculateE(n, message);
BigInteger r = null;
BigInteger s = null;
// 5.3.2
do // Generate s
{
BigInteger k = null;
do // Generate r
{
do
{
k = new BigInteger(n.BitLength, random);
}
while (k.SignValue == 0);
ECPoint p = key.Parameters.G.Multiply(k);
// 5.3.3
BigInteger x = p.X.ToBigInteger();
r = x.Mod(n);
}
while (r.SignValue == 0);
BigInteger d = ((ECPrivateKeyParameters)key).D;
s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n);
}
while (s.SignValue == 0);
return new BigInteger[]{ r, s };
}
// 5.4 pg 29
/**
* return true if the value r and s represent a DSA signature for
* the passed in message (for standard DSA the message should be
* a SHA-1 hash of the real message to be verified).
*/
public bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
{
BigInteger n = key.Parameters.N;
// r and s should both in the range [1,n-1]
if (r.SignValue < 1 || s.SignValue < 1
|| r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
{
return false;
}
BigInteger e = calculateE(n, message);
BigInteger c = s.ModInverse(n);
BigInteger u1 = e.Multiply(c).Mod(n);
BigInteger u2 = r.Multiply(c).Mod(n);
ECPoint G = key.Parameters.G;
ECPoint Q = ((ECPublicKeyParameters) key).Q;
ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2);
BigInteger v = point.X.ToBigInteger().Mod(n);
return v.Equals(r);
}
private BigInteger calculateE(
BigInteger n,
byte[] message)
{
int length = System.Math.Min(message.Length, n.BitLength / 8);
return new BigInteger(1, message, 0, length);
}
}
}
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* EC-DSA as described in X9.62
*/
public class ECDsaSigner
: IDsa
{
private ECKeyParameters key;
private SecureRandom random;
public string AlgorithmName
{
get { return "ECDSA"; }
}
public void Init(
bool forSigning,
ICipherParameters parameters)
{
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom) parameters;
this.random = rParam.Random;
parameters = rParam.Parameters;
}
else
{
this.random = new SecureRandom();
}
if (!(parameters is ECPrivateKeyParameters))
throw new InvalidKeyException("EC private key required for signing");
this.key = (ECPrivateKeyParameters) parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
throw new InvalidKeyException("EC public key required for verification");
this.key = (ECPublicKeyParameters) parameters;
}
}
// 5.3 pg 28
/**
* Generate a signature for the given message using the key we were
* initialised with. For conventional DSA the message should be a SHA-1
* hash of the message of interest.
*
* @param message the message that will be verified later.
*/
public BigInteger[] GenerateSignature(
byte[] message)
{
BigInteger n = key.Parameters.N;
BigInteger e = calculateE(n, message);
BigInteger r = null;
BigInteger s = null;
// 5.3.2
do // Generate s
{
BigInteger k = null;
do // Generate r
{
do
{
k = new BigInteger(n.BitLength, random);
}
while (k.SignValue == 0);
ECPoint p = key.Parameters.G.Multiply(k);
// 5.3.3
BigInteger x = p.X.ToBigInteger();
r = x.Mod(n);
}
while (r.SignValue == 0);
BigInteger d = ((ECPrivateKeyParameters)key).D;
s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n);
}
while (s.SignValue == 0);
return new BigInteger[]{ r, s };
}
// 5.4 pg 29
/**
* return true if the value r and s represent a DSA signature for
* the passed in message (for standard DSA the message should be
* a SHA-1 hash of the real message to be verified).
*/
public bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
{
BigInteger n = key.Parameters.N;
// r and s should both in the range [1,n-1]
if (r.SignValue < 1 || s.SignValue < 1
|| r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
{
return false;
}
BigInteger e = calculateE(n, message);
BigInteger c = s.ModInverse(n);
BigInteger u1 = e.Multiply(c).Mod(n);
BigInteger u2 = r.Multiply(c).Mod(n);
ECPoint G = key.Parameters.G;
ECPoint Q = ((ECPublicKeyParameters) key).Q;
ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2);
BigInteger v = point.X.ToBigInteger().Mod(n);
return v.Equals(r);
}
private BigInteger calculateE(
BigInteger n,
byte[] message)
{
int messageBitLength = message.Length * 8;
BigInteger trunc = new BigInteger(1, message);
if (n.BitLength < messageBitLength)
{
trunc = trunc.ShiftRight(messageBitLength - n.BitLength);
}
return trunc;
}
}
}

View File

@ -1,196 +1,196 @@
using System;
using System.Text;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Tls
{
/// <remarks>A generic TLS 1.0 block cipher suite. This can be used for AES or 3DES for example.</remarks>
public class TlsBlockCipherCipherSuite
: TlsCipherSuite
{
private IBlockCipher encryptCipher;
private IBlockCipher decryptCipher;
private IDigest writeDigest;
private IDigest readDigest;
private int cipherKeySize;
private short keyExchange;
private TlsMac writeMac;
private TlsMac readMac;
internal TlsBlockCipherCipherSuite(
IBlockCipher encrypt,
IBlockCipher decrypt,
IDigest writeDigest,
IDigest readDigest,
int cipherKeySize,
short keyExchange)
{
this.encryptCipher = encrypt;
this.decryptCipher = decrypt;
this.writeDigest = writeDigest;
this.readDigest = readDigest;
this.cipherKeySize = cipherKeySize;
this.keyExchange = keyExchange;
}
internal override void Init(byte[] ms, byte[] cr, byte[] sr)
{
int prfSize = (2 * cipherKeySize) + (2 * writeDigest.GetDigestSize())
+ (2 * encryptCipher.GetBlockSize());
byte[] key_block = new byte[prfSize];
byte[] random = new byte[cr.Length + sr.Length];
Array.Copy(cr, 0, random, sr.Length, cr.Length);
Array.Copy(sr, 0, random, 0, sr.Length);
TlsUtilities.PRF(ms, TlsUtilities.ToByteArray("key expansion"), random, key_block);
int offset = 0;
// Init MACs
writeMac = new TlsMac(writeDigest, key_block, offset, writeDigest
.GetDigestSize());
offset += writeDigest.GetDigestSize();
readMac = new TlsMac(readDigest, key_block, offset, readDigest
.GetDigestSize());
offset += readDigest.GetDigestSize();
// Init Ciphers
this.initCipher(true, encryptCipher, key_block, cipherKeySize, offset,
offset + (cipherKeySize * 2));
offset += cipherKeySize;
this.initCipher(false, decryptCipher, key_block, cipherKeySize, offset,
offset + cipherKeySize + decryptCipher.GetBlockSize());
}
private void initCipher(bool forEncryption, IBlockCipher cipher,
byte[] key_block, int key_size, int key_offset, int iv_offset)
{
KeyParameter key_parameter = new KeyParameter(key_block, key_offset,
key_size);
ParametersWithIV parameters_with_iv = new ParametersWithIV(
key_parameter, key_block, iv_offset, cipher.GetBlockSize());
cipher.Init(forEncryption, parameters_with_iv);
}
internal override byte[] EncodePlaintext(
short type,
byte[] plaintext,
int offset,
int len)
{
int blocksize = encryptCipher.GetBlockSize();
int paddingsize = blocksize
- ((len + writeMac.Size + 1) % blocksize);
int totalsize = len + writeMac.Size + paddingsize + 1;
byte[] outbuf = new byte[totalsize];
Array.Copy(plaintext, offset, outbuf, 0, len);
byte[] mac = writeMac.CalculateMac(type, plaintext, offset, len);
Array.Copy(mac, 0, outbuf, len, mac.Length);
int paddoffset = len + mac.Length;
for (int i = 0; i <= paddingsize; i++)
{
outbuf[i + paddoffset] = (byte)paddingsize;
}
for (int i = 0; i < totalsize; i += blocksize)
{
encryptCipher.ProcessBlock(outbuf, i, outbuf, i);
}
return outbuf;
}
internal override byte[] DecodeCiphertext(
short type,
byte[] ciphertext,
int offset,
int len,
TlsProtocolHandler handler)
{
int blocksize = decryptCipher.GetBlockSize();
bool decrypterror = false;
/*
* Decrypt all the ciphertext using the blockcipher
*/
for (int i = 0; i < len; i += blocksize)
{
decryptCipher.ProcessBlock(ciphertext, i + offset, ciphertext, i
+ offset);
}
/*
* Check if padding is correct
*/
int paddingsize = ciphertext[offset + len - 1];
if (offset + len - 1 - paddingsize < 0)
{
/*
* This would lead to an negativ array index, so this padding
* must be incorrect!
*/
decrypterror = true;
paddingsize = 0;
}
else
{
/*
* Now, check all the padding-bytes.
*/
for (int i = 0; i <= paddingsize; i++)
{
if (ciphertext[offset + len - 1 - i] != paddingsize)
{
/* Wrong padding */
decrypterror = true;
}
}
}
/*
* We now don't care if padding verification has failed or not,
* we will calculate the mac to give an attacker no kind of timing
* profile he can use to find out if mac verification failed or
* padding verification failed.
*/
int plaintextlength = len - readMac.Size - paddingsize - 1;
byte[] calculatedMac = readMac.CalculateMac(type, ciphertext, offset,
plaintextlength);
/*
* Check all bytes in the mac.
*/
for (int i = 0; i < calculatedMac.Length; i++)
{
if (ciphertext[offset + plaintextlength + i] != calculatedMac[i])
{
decrypterror = true;
}
}
/*
* Now, it is save to fail.
*/
if (decrypterror)
{
handler.FailWithError(TlsProtocolHandler.AL_fatal,
TlsProtocolHandler.AP_bad_record_mac);
}
byte[] plaintext = new byte[plaintextlength];
Array.Copy(ciphertext, offset, plaintext, 0, plaintextlength);
return plaintext;
}
internal override short KeyExchangeAlgorithm
{
get { return this.keyExchange; }
}
}
}
using System;
using System.Text;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Tls
{
/// <remarks>A generic TLS 1.0 block cipher suite. This can be used for AES or 3DES for example.</remarks>
public class TlsBlockCipherCipherSuite
: TlsCipherSuite
{
private IBlockCipher encryptCipher;
private IBlockCipher decryptCipher;
private IDigest writeDigest;
private IDigest readDigest;
private int cipherKeySize;
private short keyExchange;
private TlsMac writeMac;
private TlsMac readMac;
internal TlsBlockCipherCipherSuite(
IBlockCipher encrypt,
IBlockCipher decrypt,
IDigest writeDigest,
IDigest readDigest,
int cipherKeySize,
short keyExchange)
{
this.encryptCipher = encrypt;
this.decryptCipher = decrypt;
this.writeDigest = writeDigest;
this.readDigest = readDigest;
this.cipherKeySize = cipherKeySize;
this.keyExchange = keyExchange;
}
internal override void Init(byte[] ms, byte[] cr, byte[] sr)
{
int prfSize = (2 * cipherKeySize) + (2 * writeDigest.GetDigestSize())
+ (2 * encryptCipher.GetBlockSize());
byte[] key_block = new byte[prfSize];
byte[] random = new byte[cr.Length + sr.Length];
Array.Copy(cr, 0, random, sr.Length, cr.Length);
Array.Copy(sr, 0, random, 0, sr.Length);
TlsUtilities.PRF(ms, TlsUtilities.ToByteArray("key expansion"), random, key_block);
int offset = 0;
// Init MACs
writeMac = new TlsMac(writeDigest, key_block, offset, writeDigest
.GetDigestSize());
offset += writeDigest.GetDigestSize();
readMac = new TlsMac(readDigest, key_block, offset, readDigest
.GetDigestSize());
offset += readDigest.GetDigestSize();
// Init Ciphers
this.initCipher(true, encryptCipher, key_block, cipherKeySize, offset,
offset + (cipherKeySize * 2));
offset += cipherKeySize;
this.initCipher(false, decryptCipher, key_block, cipherKeySize, offset,
offset + cipherKeySize + decryptCipher.GetBlockSize());
}
private void initCipher(bool forEncryption, IBlockCipher cipher,
byte[] key_block, int key_size, int key_offset, int iv_offset)
{
KeyParameter key_parameter = new KeyParameter(key_block, key_offset,
key_size);
ParametersWithIV parameters_with_iv = new ParametersWithIV(
key_parameter, key_block, iv_offset, cipher.GetBlockSize());
cipher.Init(forEncryption, parameters_with_iv);
}
internal override byte[] EncodePlaintext(
short type,
byte[] plaintext,
int offset,
int len)
{
int blocksize = encryptCipher.GetBlockSize();
int paddingsize = blocksize
- ((len + writeMac.Size + 1) % blocksize);
int totalsize = len + writeMac.Size + paddingsize + 1;
byte[] outbuf = new byte[totalsize];
Array.Copy(plaintext, offset, outbuf, 0, len);
byte[] mac = writeMac.CalculateMac(type, plaintext, offset, len);
Array.Copy(mac, 0, outbuf, len, mac.Length);
int paddoffset = len + mac.Length;
for (int i = 0; i <= paddingsize; i++)
{
outbuf[i + paddoffset] = (byte)paddingsize;
}
for (int i = 0; i < totalsize; i += blocksize)
{
encryptCipher.ProcessBlock(outbuf, i, outbuf, i);
}
return outbuf;
}
internal override byte[] DecodeCiphertext(
short type,
byte[] ciphertext,
int offset,
int len,
TlsProtocolHandler handler)
{
int blocksize = decryptCipher.GetBlockSize();
bool decrypterror = false;
/*
* Decrypt all the ciphertext using the blockcipher
*/
for (int i = 0; i < len; i += blocksize)
{
decryptCipher.ProcessBlock(ciphertext, i + offset, ciphertext, i
+ offset);
}
/*
* Check if padding is correct
*/
int paddingsize = ciphertext[offset + len - 1];
if (offset + len - 1 - paddingsize < 0)
{
/*
* This would lead to a negative array index, so this padding
* must be incorrect!
*/
decrypterror = true;
paddingsize = 0;
}
else
{
/*
* Now, check all the padding-bytes.
*/
for (int i = 0; i <= paddingsize; i++)
{
if (ciphertext[offset + len - 1 - i] != paddingsize)
{
/* Wrong padding */
decrypterror = true;
}
}
}
/*
* We now don't care if padding verification has failed or not,
* we will calculate the mac to give an attacker no kind of timing
* profile he can use to find out if mac verification failed or
* padding verification failed.
*/
int plaintextlength = len - readMac.Size - paddingsize - 1;
byte[] calculatedMac = readMac.CalculateMac(type, ciphertext, offset,
plaintextlength);
/*
* Check all bytes in the mac.
*/
for (int i = 0; i < calculatedMac.Length; i++)
{
if (ciphertext[offset + plaintextlength + i] != calculatedMac[i])
{
decrypterror = true;
}
}
/*
* Now, it is safe to fail.
*/
if (decrypterror)
{
handler.FailWithError(TlsProtocolHandler.AL_fatal,
TlsProtocolHandler.AP_bad_record_mac);
}
byte[] plaintext = new byte[plaintextlength];
Array.Copy(ciphertext, offset, plaintext, 0, plaintextlength);
return plaintext;
}
internal override short KeyExchangeAlgorithm
{
get { return this.keyExchange; }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,166 +1,166 @@
using System;
using System.Collections;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>
/// Generator for a PGP master and subkey ring.
/// This class will generate both the secret and public key rings
/// </remarks>
public class PgpKeyRingGenerator
{
private ArrayList keys = new ArrayList();
private string id;
private SymmetricKeyAlgorithmTag encAlgorithm;
private int certificationLevel;
private char[] passPhrase;
private bool useSha1;
private PgpKeyPair masterKey;
private PgpSignatureSubpacketVector hashedPacketVector;
private PgpSignatureSubpacketVector unhashedPacketVector;
private SecureRandom rand;
/// <summary>
/// Create a new key ring generator using old style checksumming. It is recommended to use
/// SHA1 checksumming where possible.
/// </summary>
/// <param name="certificationLevel">The certification level for keys on this ring.</param>
/// <param name="masterKey">The master key pair.</param>
/// <param name="id">The id to be associated with the ring.</param>
/// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param>
/// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param>
/// <param name="hashedPackets">Packets to be included in the certification hash.</param>
/// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param>
/// <param name="rand">input secured random.</param>
public PgpKeyRingGenerator(
int certificationLevel,
PgpKeyPair masterKey,
string id,
SymmetricKeyAlgorithmTag encAlgorithm,
char[] passPhrase,
PgpSignatureSubpacketVector hashedPackets,
PgpSignatureSubpacketVector unhashedPackets,
SecureRandom rand)
: this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand)
{
}
/// <summary>
/// Create a new key ring generator.
/// </summary>
/// <param name="certificationLevel">The certification level for keys on this ring.</param>
/// <param name="masterKey">The master key pair.</param>
/// <param name="id">The id to be associated with the ring.</param>
/// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param>
/// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param>
/// <param name="useSha1">Checksum the secret keys with SHA1 rather than the older 16 bit checksum.</param>
/// <param name="hashedPackets">Packets to be included in the certification hash.</param>
/// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param>
/// <param name="rand">input secured random.</param>
public PgpKeyRingGenerator(
int certificationLevel,
PgpKeyPair masterKey,
string id,
SymmetricKeyAlgorithmTag encAlgorithm,
char[] passPhrase,
bool useSha1,
PgpSignatureSubpacketVector hashedPackets,
PgpSignatureSubpacketVector unhashedPackets,
SecureRandom rand)
{
this.certificationLevel = certificationLevel;
this.masterKey = masterKey;
this.id = id;
this.encAlgorithm = encAlgorithm;
this.passPhrase = passPhrase;
this.useSha1 = useSha1;
this.hashedPacketVector = hashedPackets;
this.unhashedPacketVector = unhashedPackets;
this.rand = rand;
keys.Add(new PgpSecretKey(certificationLevel, masterKey, id, encAlgorithm, passPhrase, useSha1, hashedPackets, unhashedPackets, rand));
}
/// <summary>Add a subkey to the key ring to be generated with default certification.</summary>
public void AddSubKey(
PgpKeyPair keyPair)
{
AddSubKey(keyPair, this.hashedPacketVector, this.unhashedPacketVector);
}
/// <summary>
/// Add a subkey with specific hashed and unhashed packets associated with it and
/// default certification.
/// </summary>
/// <param name="keyPair">Public/private key pair.</param>
/// <param name="hashedPackets">Hashed packet values to be included in certification.</param>
/// <param name="unhashedPackets">Unhashed packets values to be included in certification.</param>
/// <exception cref="PgpException"></exception>
public void AddSubKey(
PgpKeyPair keyPair,
PgpSignatureSubpacketVector hashedPackets,
PgpSignatureSubpacketVector unhashedPackets)
{
try
{
PgpSignatureGenerator sGen = new PgpSignatureGenerator(
masterKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
//
// Generate the certification
//
sGen.InitSign(PgpSignature.SubkeyBinding, masterKey.PrivateKey);
sGen.SetHashedSubpackets(hashedPackets);
sGen.SetUnhashedSubpackets(unhashedPackets);
ArrayList subSigs = new ArrayList();
subSigs.Add(sGen.GenerateCertification(masterKey.PublicKey, keyPair.PublicKey));
keys.Add(new PgpSecretKey(keyPair, null, subSigs, encAlgorithm, passPhrase, useSha1, rand));
}
catch (PgpException e)
{
throw e;
}
catch (Exception e)
{
throw new PgpException("exception adding subkey: ", e);
}
}
/// <summary>Return the secret key ring.</summary>
public PgpSecretKeyRing GenerateSecretKeyRing()
{
return new PgpSecretKeyRing(keys);
}
/// <summary>Return the public key ring that corresponds to the secret key ring.</summary>
public PgpPublicKeyRing GeneratePublicKeyRing()
{
ArrayList pubKeys = new ArrayList();
IEnumerator enumerator = keys.GetEnumerator();
enumerator.MoveNext();
PgpSecretKey pgpSecretKey = (PgpSecretKey) enumerator.Current;
pubKeys.Add(pgpSecretKey.PublicKey);
while (enumerator.MoveNext())
{
pgpSecretKey = (PgpSecretKey) enumerator.Current;
PgpPublicKey k = new PgpPublicKey(pgpSecretKey.PublicKey);
k.publicPk = new PublicSubkeyPacket(
k.Algorithm, k.CreationTime, k.publicPk.Key);
pubKeys.Add(k);
}
return new PgpPublicKeyRing(pubKeys);
}
}
}
using System;
using System.Collections;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>
/// Generator for a PGP master and subkey ring.
/// This class will generate both the secret and public key rings
/// </remarks>
public class PgpKeyRingGenerator
{
private ArrayList keys = new ArrayList();
private string id;
private SymmetricKeyAlgorithmTag encAlgorithm;
private int certificationLevel;
private char[] passPhrase;
private bool useSha1;
private PgpKeyPair masterKey;
private PgpSignatureSubpacketVector hashedPacketVector;
private PgpSignatureSubpacketVector unhashedPacketVector;
private SecureRandom rand;
/// <summary>
/// Create a new key ring generator using old style checksumming. It is recommended to use
/// SHA1 checksumming where possible.
/// </summary>
/// <param name="certificationLevel">The certification level for keys on this ring.</param>
/// <param name="masterKey">The master key pair.</param>
/// <param name="id">The id to be associated with the ring.</param>
/// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param>
/// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param>
/// <param name="hashedPackets">Packets to be included in the certification hash.</param>
/// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param>
/// <param name="rand">input secured random.</param>
public PgpKeyRingGenerator(
int certificationLevel,
PgpKeyPair masterKey,
string id,
SymmetricKeyAlgorithmTag encAlgorithm,
char[] passPhrase,
PgpSignatureSubpacketVector hashedPackets,
PgpSignatureSubpacketVector unhashedPackets,
SecureRandom rand)
: this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand)
{
}
/// <summary>
/// Create a new key ring generator.
/// </summary>
/// <param name="certificationLevel">The certification level for keys on this ring.</param>
/// <param name="masterKey">The master key pair.</param>
/// <param name="id">The id to be associated with the ring.</param>
/// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param>
/// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param>
/// <param name="useSha1">Checksum the secret keys with SHA1 rather than the older 16 bit checksum.</param>
/// <param name="hashedPackets">Packets to be included in the certification hash.</param>
/// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param>
/// <param name="rand">input secured random.</param>
public PgpKeyRingGenerator(
int certificationLevel,
PgpKeyPair masterKey,
string id,
SymmetricKeyAlgorithmTag encAlgorithm,
char[] passPhrase,
bool useSha1,
PgpSignatureSubpacketVector hashedPackets,
PgpSignatureSubpacketVector unhashedPackets,
SecureRandom rand)
{
this.certificationLevel = certificationLevel;
this.masterKey = masterKey;
this.id = id;
this.encAlgorithm = encAlgorithm;
this.passPhrase = passPhrase;
this.useSha1 = useSha1;
this.hashedPacketVector = hashedPackets;
this.unhashedPacketVector = unhashedPackets;
this.rand = rand;
keys.Add(new PgpSecretKey(certificationLevel, masterKey, id, encAlgorithm, passPhrase, useSha1, hashedPackets, unhashedPackets, rand));
}
/// <summary>Add a subkey to the key ring to be generated with default certification.</summary>
public void AddSubKey(
PgpKeyPair keyPair)
{
AddSubKey(keyPair, this.hashedPacketVector, this.unhashedPacketVector);
}
/// <summary>
/// Add a subkey with specific hashed and unhashed packets associated with it and
/// default certification.
/// </summary>
/// <param name="keyPair">Public/private key pair.</param>
/// <param name="hashedPackets">Hashed packet values to be included in certification.</param>
/// <param name="unhashedPackets">Unhashed packets values to be included in certification.</param>
/// <exception cref="PgpException"></exception>
public void AddSubKey(
PgpKeyPair keyPair,
PgpSignatureSubpacketVector hashedPackets,
PgpSignatureSubpacketVector unhashedPackets)
{
try
{
PgpSignatureGenerator sGen = new PgpSignatureGenerator(
masterKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
//
// Generate the certification
//
sGen.InitSign(PgpSignature.SubkeyBinding, masterKey.PrivateKey);
sGen.SetHashedSubpackets(hashedPackets);
sGen.SetUnhashedSubpackets(unhashedPackets);
ArrayList subSigs = new ArrayList();
subSigs.Add(sGen.GenerateCertification(masterKey.PublicKey, keyPair.PublicKey));
keys.Add(new PgpSecretKey(keyPair.PrivateKey, new PgpPublicKey(keyPair.PublicKey, null, subSigs), encAlgorithm, passPhrase, useSha1, rand));
}
catch (PgpException e)
{
throw e;
}
catch (Exception e)
{
throw new PgpException("exception adding subkey: ", e);
}
}
/// <summary>Return the secret key ring.</summary>
public PgpSecretKeyRing GenerateSecretKeyRing()
{
return new PgpSecretKeyRing(keys);
}
/// <summary>Return the public key ring that corresponds to the secret key ring.</summary>
public PgpPublicKeyRing GeneratePublicKeyRing()
{
ArrayList pubKeys = new ArrayList();
IEnumerator enumerator = keys.GetEnumerator();
enumerator.MoveNext();
PgpSecretKey pgpSecretKey = (PgpSecretKey) enumerator.Current;
pubKeys.Add(pgpSecretKey.PublicKey);
while (enumerator.MoveNext())
{
pgpSecretKey = (PgpSecretKey) enumerator.Current;
PgpPublicKey k = new PgpPublicKey(pgpSecretKey.PublicKey);
k.publicPk = new PublicSubkeyPacket(
k.Algorithm, k.CreationTime, k.publicPk.Key);
pubKeys.Add(k);
}
return new PgpPublicKeyRing(pubKeys);
}
}
}

View File

@ -1,179 +1,179 @@
using System;
using System.IO;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>A one pass signature object.</remarks>
public class PgpOnePassSignature
{
private OnePassSignaturePacket sigPack;
private int signatureType;
private ISigner sig;
private byte lastb;
internal PgpOnePassSignature(
BcpgInputStream bcpgInput)
: this((OnePassSignaturePacket) bcpgInput.ReadPacket())
{
}
internal PgpOnePassSignature(
OnePassSignaturePacket sigPack)
{
this.sigPack = sigPack;
this.signatureType = sigPack.SignatureType;
try
{
this.sig = SignerUtilities.GetSigner(
PgpUtilities.GetSignatureName(sigPack.KeyAlgorithm, sigPack.HashAlgorithm));
}
catch (Exception e)
{
throw new PgpException("can't set up signature object.", e);
}
}
/// <summary>Initialise the signature object for verification.</summary>
public void InitVerify(
PgpPublicKey pubKey)
{
lastb = 0;
try
{
sig.Init(false, pubKey.GetKey());
}
catch (InvalidKeyException e)
{
throw new PgpException("invalid key.", e);
}
}
public void Update(
byte b)
{
if (signatureType == PgpSignature.CanonicalTextDocument)
{
doCanonicalUpdateByte(b);
}
else
{
sig.Update(b);
}
}
private void doCanonicalUpdateByte(
byte b)
{
if (b == '\r')
{
doUpdateCRLF();
}
else if (b == '\n')
{
if (lastb != '\r')
{
doUpdateCRLF();
}
}
else
{
sig.Update(b);
}
lastb = b;
}
private void doUpdateCRLF()
{
sig.Update((byte)'\r');
sig.Update((byte)'\n');
}
public void Update(
byte[] bytes)
{
if (signatureType == PgpSignature.CanonicalTextDocument)
{
for (int i = 0; i != bytes.Length; i++)
{
doCanonicalUpdateByte(bytes[i]);
}
}
else
{
sig.BlockUpdate(bytes, 0, bytes.Length);
}
}
public void Update(
byte[] bytes,
int off,
int length)
{
if (signatureType == PgpSignature.CanonicalTextDocument)
{
int finish = off + length;
for (int i = off; i != finish; i++)
{
doCanonicalUpdateByte(bytes[i]);
}
}
else
{
sig.BlockUpdate(bytes, off, length);
}
}
/// <summary>Verify the calculated signature against the passed in PgpSignature.</summary>
public bool Verify(
PgpSignature pgpSig)
{
byte[] trailer = pgpSig.GetSignatureTrailer();
sig.BlockUpdate(trailer, 0, trailer.Length);
return sig.VerifySignature(pgpSig.GetSignature());
}
public long KeyId
{
get { return sigPack.KeyId; }
}
public int SignatureType
{
get { return sigPack.SignatureType; }
}
public HashAlgorithmTag HashAlgorithm
{
get { return sigPack.HashAlgorithm; }
}
public PublicKeyAlgorithmTag KeyAlgorithm
{
get { return sigPack.KeyAlgorithm; }
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStr)
{
BcpgOutputStream.Wrap(outStr).WritePacket(sigPack);
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>A one pass signature object.</remarks>
public class PgpOnePassSignature
{
private OnePassSignaturePacket sigPack;
private int signatureType;
private ISigner sig;
private byte lastb;
internal PgpOnePassSignature(
BcpgInputStream bcpgInput)
: this((OnePassSignaturePacket) bcpgInput.ReadPacket())
{
}
internal PgpOnePassSignature(
OnePassSignaturePacket sigPack)
{
this.sigPack = sigPack;
this.signatureType = sigPack.SignatureType;
}
/// <summary>Initialise the signature object for verification.</summary>
public void InitVerify(
PgpPublicKey pubKey)
{
lastb = 0;
try
{
sig = SignerUtilities.GetSigner(
PgpUtilities.GetSignatureName(sigPack.KeyAlgorithm, sigPack.HashAlgorithm));
}
catch (Exception e)
{
throw new PgpException("can't set up signature object.", e);
}
try
{
sig.Init(false, pubKey.GetKey());
}
catch (InvalidKeyException e)
{
throw new PgpException("invalid key.", e);
}
}
public void Update(
byte b)
{
if (signatureType == PgpSignature.CanonicalTextDocument)
{
doCanonicalUpdateByte(b);
}
else
{
sig.Update(b);
}
}
private void doCanonicalUpdateByte(
byte b)
{
if (b == '\r')
{
doUpdateCRLF();
}
else if (b == '\n')
{
if (lastb != '\r')
{
doUpdateCRLF();
}
}
else
{
sig.Update(b);
}
lastb = b;
}
private void doUpdateCRLF()
{
sig.Update((byte)'\r');
sig.Update((byte)'\n');
}
public void Update(
byte[] bytes)
{
if (signatureType == PgpSignature.CanonicalTextDocument)
{
for (int i = 0; i != bytes.Length; i++)
{
doCanonicalUpdateByte(bytes[i]);
}
}
else
{
sig.BlockUpdate(bytes, 0, bytes.Length);
}
}
public void Update(
byte[] bytes,
int off,
int length)
{
if (signatureType == PgpSignature.CanonicalTextDocument)
{
int finish = off + length;
for (int i = off; i != finish; i++)
{
doCanonicalUpdateByte(bytes[i]);
}
}
else
{
sig.BlockUpdate(bytes, off, length);
}
}
/// <summary>Verify the calculated signature against the passed in PgpSignature.</summary>
public bool Verify(
PgpSignature pgpSig)
{
byte[] trailer = pgpSig.GetSignatureTrailer();
sig.BlockUpdate(trailer, 0, trailer.Length);
return sig.VerifySignature(pgpSig.GetSignature());
}
public long KeyId
{
get { return sigPack.KeyId; }
}
public int SignatureType
{
get { return sigPack.SignatureType; }
}
public HashAlgorithmTag HashAlgorithm
{
get { return sigPack.HashAlgorithm; }
}
public PublicKeyAlgorithmTag KeyAlgorithm
{
get { return sigPack.KeyAlgorithm; }
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStr)
{
BcpgOutputStream.Wrap(outStr).WritePacket(sigPack);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,187 +1,194 @@
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>
/// Class to hold a single master public key and its subkeys.
/// <p>
/// Often PGP keyring files consist of multiple master keys, if you are trying to process
/// or construct one of these you should use the <c>PgpPublicKeyRingBundle</c> class.
/// </p>
/// </remarks>
public class PgpPublicKeyRing
: PgpKeyRing
{
private readonly ArrayList keys;
public PgpPublicKeyRing(
byte[] encoding)
: this(new MemoryStream(encoding, false))
{
}
internal PgpPublicKeyRing(
ArrayList pubKeys)
{
this.keys = pubKeys;
}
public PgpPublicKeyRing(
Stream inputStream)
{
this.keys = new ArrayList();
BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
PacketTag initialTag = bcpgInput.NextPacketTag();
if (initialTag != PacketTag.PublicKey && initialTag != PacketTag.PublicSubkey)
{
throw new IOException("public key ring doesn't start with public key tag: "
+ "tag 0x" + ((int)initialTag).ToString("X"));
}
PublicKeyPacket pubPk = (PublicKeyPacket) bcpgInput.ReadPacket();;
TrustPacket trustPk = ReadOptionalTrustPacket(bcpgInput);
// direct signatures and revocations
ArrayList keySigs = ReadSignaturesAndTrust(bcpgInput);
ArrayList ids, idTrusts, idSigs;
ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs);
keys.Add(new PgpPublicKey(pubPk, trustPk, keySigs, ids, idTrusts, idSigs));
// Read subkeys
while (bcpgInput.NextPacketTag() == PacketTag.PublicSubkey)
{
PublicKeyPacket pk = (PublicKeyPacket) bcpgInput.ReadPacket();
TrustPacket kTrust = ReadOptionalTrustPacket(bcpgInput);
// PGP 8 actually leaves out the signature.
ArrayList sigList = ReadSignaturesAndTrust(bcpgInput);
keys.Add(new PgpPublicKey(pk, kTrust, sigList));
}
}
/// <summary>Return the first public key in the ring.</summary>
public PgpPublicKey GetPublicKey()
{
return (PgpPublicKey) keys[0];
}
/// <summary>Return the public key referred to by the passed in key ID if it is present.</summary>
public PgpPublicKey GetPublicKey(
long keyId)
{
foreach (PgpPublicKey k in keys)
{
if (keyId == k.KeyId)
{
return k;
}
}
return null;
}
/// <summary>Allows enumeration of all the public keys.</summary>
/// <returns>An <c>IEnumerable</c> of <c>PgpPublicKey</c> objects.</returns>
public IEnumerable GetPublicKeys()
{
return new EnumerableProxy(keys);
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStr)
{
if (outStr == null)
throw new ArgumentNullException("outStr");
foreach (PgpPublicKey k in keys)
{
k.Encode(outStr);
}
}
/// <summary>
/// Returns a new key ring with the public key passed in either added or
/// replacing an existing one.
/// </summary>
/// <param name="pubRing">The public key ring to be modified.</param>
/// <param name="pubKey">The public key to be inserted.</param>
/// <returns>A new <c>PgpPublicKeyRing</c></returns>
public static PgpPublicKeyRing InsertPublicKey(
PgpPublicKeyRing pubRing,
PgpPublicKey pubKey)
{
ArrayList keys = new ArrayList(pubRing.keys);
bool found = false;
bool masterFound = false;
for (int i = 0; i != keys.Count; i++)
{
PgpPublicKey key = (PgpPublicKey) keys[i];
if (key.KeyId == pubKey.KeyId)
{
found = true;
keys[i] = pubKey;
}
if (key.IsMasterKey)
{
masterFound = true;
}
}
if (!found)
{
if (pubKey.IsMasterKey && masterFound)
throw new ArgumentException("cannot add a master key to a ring that already has one");
keys.Add(pubKey);
}
return new PgpPublicKeyRing(keys);
}
/// <summary>Returns a new key ring with the public key passed in removed from the key ring.</summary>
/// <param name="pubRing">The public key ring to be modified.</param>
/// <param name="pubKey">The public key to be removed.</param>
/// <returns>A new <c>PgpPublicKeyRing</c>, or null if pubKey is not found.</returns>
public static PgpPublicKeyRing RemovePublicKey(
PgpPublicKeyRing pubRing,
PgpPublicKey pubKey)
{
ArrayList keys = new ArrayList(pubRing.keys);
bool found = false;
for (int i = 0; i < keys.Count; i++)
{
PgpPublicKey key = (PgpPublicKey) keys[i];
if (key.KeyId == pubKey.KeyId)
{
found = true;
keys.RemoveAt(i);
}
}
return found ? new PgpPublicKeyRing(keys) : null;
}
}
}
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>
/// Class to hold a single master public key and its subkeys.
/// <p>
/// Often PGP keyring files consist of multiple master keys, if you are trying to process
/// or construct one of these you should use the <c>PgpPublicKeyRingBundle</c> class.
/// </p>
/// </remarks>
public class PgpPublicKeyRing
: PgpKeyRing
{
private readonly ArrayList keys;
public PgpPublicKeyRing(
byte[] encoding)
: this(new MemoryStream(encoding, false))
{
}
internal PgpPublicKeyRing(
ArrayList pubKeys)
{
this.keys = pubKeys;
}
public PgpPublicKeyRing(
Stream inputStream)
{
this.keys = new ArrayList();
BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
PacketTag initialTag = bcpgInput.NextPacketTag();
if (initialTag != PacketTag.PublicKey && initialTag != PacketTag.PublicSubkey)
{
throw new IOException("public key ring doesn't start with public key tag: "
+ "tag 0x" + ((int)initialTag).ToString("X"));
}
PublicKeyPacket pubPk = (PublicKeyPacket) bcpgInput.ReadPacket();;
TrustPacket trustPk = ReadOptionalTrustPacket(bcpgInput);
// direct signatures and revocations
ArrayList keySigs = ReadSignaturesAndTrust(bcpgInput);
ArrayList ids, idTrusts, idSigs;
ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs);
keys.Add(new PgpPublicKey(pubPk, trustPk, keySigs, ids, idTrusts, idSigs));
// Read subkeys
while (bcpgInput.NextPacketTag() == PacketTag.PublicSubkey)
{
PublicKeyPacket pk = (PublicKeyPacket) bcpgInput.ReadPacket();
TrustPacket kTrust = ReadOptionalTrustPacket(bcpgInput);
// PGP 8 actually leaves out the signature.
ArrayList sigList = ReadSignaturesAndTrust(bcpgInput);
keys.Add(new PgpPublicKey(pk, kTrust, sigList));
}
}
/// <summary>Return the first public key in the ring.</summary>
public PgpPublicKey GetPublicKey()
{
return (PgpPublicKey) keys[0];
}
/// <summary>Return the public key referred to by the passed in key ID if it is present.</summary>
public PgpPublicKey GetPublicKey(
long keyId)
{
foreach (PgpPublicKey k in keys)
{
if (keyId == k.KeyId)
{
return k;
}
}
return null;
}
/// <summary>Allows enumeration of all the public keys.</summary>
/// <returns>An <c>IEnumerable</c> of <c>PgpPublicKey</c> objects.</returns>
public IEnumerable GetPublicKeys()
{
return new EnumerableProxy(keys);
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStr)
{
if (outStr == null)
throw new ArgumentNullException("outStr");
foreach (PgpPublicKey k in keys)
{
k.Encode(outStr);
}
}
/// <summary>
/// Returns a new key ring with the public key passed in either added or
/// replacing an existing one.
/// </summary>
/// <param name="pubRing">The public key ring to be modified.</param>
/// <param name="pubKey">The public key to be inserted.</param>
/// <returns>A new <c>PgpPublicKeyRing</c></returns>
public static PgpPublicKeyRing InsertPublicKey(
PgpPublicKeyRing pubRing,
PgpPublicKey pubKey)
{
ArrayList keys = new ArrayList(pubRing.keys);
bool found = false;
bool masterFound = false;
for (int i = 0; i != keys.Count; i++)
{
PgpPublicKey key = (PgpPublicKey) keys[i];
if (key.KeyId == pubKey.KeyId)
{
found = true;
keys[i] = pubKey;
}
if (key.IsMasterKey)
{
masterFound = true;
}
}
if (!found)
{
if (pubKey.IsMasterKey)
{
if (masterFound)
throw new ArgumentException("cannot add a master key to a ring that already has one");
keys.Insert(0, pubKey);
}
else
{
keys.Add(pubKey);
}
}
return new PgpPublicKeyRing(keys);
}
/// <summary>Returns a new key ring with the public key passed in removed from the key ring.</summary>
/// <param name="pubRing">The public key ring to be modified.</param>
/// <param name="pubKey">The public key to be removed.</param>
/// <returns>A new <c>PgpPublicKeyRing</c>, or null if pubKey is not found.</returns>
public static PgpPublicKeyRing RemovePublicKey(
PgpPublicKeyRing pubRing,
PgpPublicKey pubKey)
{
ArrayList keys = new ArrayList(pubRing.keys);
bool found = false;
for (int i = 0; i < keys.Count; i++)
{
PgpPublicKey key = (PgpPublicKey) keys[i];
if (key.KeyId == pubKey.KeyId)
{
found = true;
keys.RemoveAt(i);
}
}
return found ? new PgpPublicKeyRing(keys) : null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,208 +1,308 @@
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>
/// Class to hold a single master secret key and its subkeys.
/// <p>
/// Often PGP keyring files consist of multiple master keys, if you are trying to process
/// or construct one of these you should use the <c>PgpSecretKeyRingBundle</c> class.
/// </p>
/// </remarks>
public class PgpSecretKeyRing
: PgpKeyRing
{
private readonly ArrayList keys;
internal PgpSecretKeyRing(
ArrayList keys)
{
this.keys = keys;
}
public PgpSecretKeyRing(
byte[] encoding)
: this(new MemoryStream(encoding))
{
}
public PgpSecretKeyRing(
Stream inputStream)
{
this.keys = new ArrayList();
BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
PacketTag initialTag = bcpgInput.NextPacketTag();
if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey)
{
throw new IOException("secret key ring doesn't start with secret key tag: "
+ "tag 0x" + ((int)initialTag).ToString("X"));
}
SecretKeyPacket secret = (SecretKeyPacket) bcpgInput.ReadPacket();
//
// ignore GPG comment packets if found.
//
while (bcpgInput.NextPacketTag() == PacketTag.Experimental2)
{
bcpgInput.ReadPacket();
}
TrustPacket trust = ReadOptionalTrustPacket(bcpgInput);
// revocation and direct signatures
ArrayList keySigs = ReadSignaturesAndTrust(bcpgInput);
ArrayList ids, idTrusts, idSigs;
ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs);
keys.Add(new PgpSecretKey(secret, trust, keySigs, ids, idTrusts, idSigs));
// Read subkeys
while (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey)
{
SecretSubkeyPacket sub = (SecretSubkeyPacket) bcpgInput.ReadPacket();
//
// ignore GPG comment packets if found.
//
while (bcpgInput.NextPacketTag() == PacketTag.Experimental2)
{
bcpgInput.ReadPacket();
}
TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput);
ArrayList sigList = ReadSignaturesAndTrust(bcpgInput);
keys.Add(new PgpSecretKey(sub, subTrust, sigList));
}
}
/// <summary>Return the public key for the master key.</summary>
public PgpPublicKey GetPublicKey()
{
return ((PgpSecretKey) keys[0]).PublicKey;
}
/// <summary>Return the master private key.</summary>
public PgpSecretKey GetSecretKey()
{
return (PgpSecretKey) keys[0];
}
/// <summary>Allows enumeration of the secret keys.</summary>
/// <returns>An <c>IEnumerable</c> of <c>PgpSecretKey</c> objects.</returns>
public IEnumerable GetSecretKeys()
{
return new EnumerableProxy(keys);
}
public PgpSecretKey GetSecretKey(
long keyId)
{
foreach (PgpSecretKey k in keys)
{
if (keyId == k.KeyId)
{
return k;
}
}
return null;
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStr)
{
if (outStr == null)
throw new ArgumentNullException("outStr");
foreach (PgpSecretKey k in keys)
{
k.Encode(outStr);
}
}
/// <summary>
/// Returns a new key ring with the secret key passed in either added or
/// replacing an existing one with the same key ID.
/// </summary>
/// <param name="secRing">The secret key ring to be modified.</param>
/// <param name="secKey">The secret key to be inserted.</param>
/// <returns>A new <c>PgpSecretKeyRing</c></returns>
public static PgpSecretKeyRing InsertSecretKey(
PgpSecretKeyRing secRing,
PgpSecretKey secKey)
{
ArrayList keys = new ArrayList(secRing.keys);
bool found = false;
bool masterFound = false;
for (int i = 0; i != keys.Count; i++)
{
PgpSecretKey key = (PgpSecretKey) keys[i];
if (key.KeyId == secKey.KeyId)
{
found = true;
keys[i] = secKey;
}
if (key.IsMasterKey)
{
masterFound = true;
}
}
if (!found)
{
if (secKey.IsMasterKey && masterFound)
throw new ArgumentException("cannot add a master key to a ring that already has one");
keys.Add(secKey);
}
return new PgpSecretKeyRing(keys);
}
/// <summary>Returns a new key ring with the secret key passed in removed from the key ring.</summary>
/// <param name="secRing">The secret key ring to be modified.</param>
/// <param name="secKey">The secret key to be removed.</param>
/// <returns>A new <c>PgpSecretKeyRing</c>, or null if secKey is not found.</returns>
public static PgpSecretKeyRing RemoveSecretKey(
PgpSecretKeyRing secRing,
PgpSecretKey secKey)
{
ArrayList keys = new ArrayList(secRing.keys);
bool found = false;
for (int i = 0; i < keys.Count; i++)
{
PgpSecretKey key = (PgpSecretKey)keys[i];
if (key.KeyId == secKey.KeyId)
{
found = true;
keys.RemoveAt(i);
}
}
return found ? new PgpSecretKeyRing(keys) : null;
}
}
}
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>
/// Class to hold a single master secret key and its subkeys.
/// <p>
/// Often PGP keyring files consist of multiple master keys, if you are trying to process
/// or construct one of these you should use the <c>PgpSecretKeyRingBundle</c> class.
/// </p>
/// </remarks>
public class PgpSecretKeyRing
: PgpKeyRing
{
private readonly IList keys;
private readonly IList extraPubKeys;
internal PgpSecretKeyRing(
IList keys)
: this(keys, new ArrayList())
{
}
private PgpSecretKeyRing(
IList keys,
IList extraPubKeys)
{
this.keys = keys;
this.extraPubKeys = extraPubKeys;
}
public PgpSecretKeyRing(
byte[] encoding)
: this(new MemoryStream(encoding))
{
}
public PgpSecretKeyRing(
Stream inputStream)
{
this.keys = new ArrayList();
this.extraPubKeys = new ArrayList();
BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
PacketTag initialTag = bcpgInput.NextPacketTag();
if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey)
{
throw new IOException("secret key ring doesn't start with secret key tag: "
+ "tag 0x" + ((int)initialTag).ToString("X"));
}
SecretKeyPacket secret = (SecretKeyPacket) bcpgInput.ReadPacket();
//
// ignore GPG comment packets if found.
//
while (bcpgInput.NextPacketTag() == PacketTag.Experimental2)
{
bcpgInput.ReadPacket();
}
TrustPacket trust = ReadOptionalTrustPacket(bcpgInput);
// revocation and direct signatures
ArrayList keySigs = ReadSignaturesAndTrust(bcpgInput);
ArrayList ids, idTrusts, idSigs;
ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs);
keys.Add(new PgpSecretKey(secret, new PgpPublicKey(secret.PublicKeyPacket, trust, keySigs, ids, idTrusts, idSigs)));
// Read subkeys
while (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey
|| bcpgInput.NextPacketTag() == PacketTag.PublicSubkey)
{
if (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey)
{
SecretSubkeyPacket sub = (SecretSubkeyPacket) bcpgInput.ReadPacket();
//
// ignore GPG comment packets if found.
//
while (bcpgInput.NextPacketTag() == PacketTag.Experimental2)
{
bcpgInput.ReadPacket();
}
TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput);
ArrayList sigList = ReadSignaturesAndTrust(bcpgInput);
keys.Add(new PgpSecretKey(sub, new PgpPublicKey(sub.PublicKeyPacket, subTrust, sigList)));
}
else
{
PublicSubkeyPacket sub = (PublicSubkeyPacket) bcpgInput.ReadPacket();
TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput);
ArrayList sigList = ReadSignaturesAndTrust(bcpgInput);
extraPubKeys.Add(new PgpPublicKey(sub, subTrust, sigList));
}
}
}
/// <summary>Return the public key for the master key.</summary>
public PgpPublicKey GetPublicKey()
{
return ((PgpSecretKey) keys[0]).PublicKey;
}
/// <summary>Return the master private key.</summary>
public PgpSecretKey GetSecretKey()
{
return (PgpSecretKey) keys[0];
}
/// <summary>Allows enumeration of the secret keys.</summary>
/// <returns>An <c>IEnumerable</c> of <c>PgpSecretKey</c> objects.</returns>
public IEnumerable GetSecretKeys()
{
return new EnumerableProxy(keys);
}
public PgpSecretKey GetSecretKey(
long keyId)
{
foreach (PgpSecretKey k in keys)
{
if (keyId == k.KeyId)
{
return k;
}
}
return null;
}
/// <summary>
/// Return an iterator of the public keys in the secret key ring that
/// have no matching private key. At the moment only personal certificate data
/// appears in this fashion.
/// </summary>
/// <returns>An <c>IEnumerable</c> of unattached, or extra, public keys.</returns>
public IEnumerable GetExtraPublicKeys()
{
return new EnumerableProxy(extraPubKeys);
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStr)
{
if (outStr == null)
throw new ArgumentNullException("outStr");
foreach (PgpSecretKey key in keys)
{
key.Encode(outStr);
}
foreach (PgpPublicKey extraPubKey in extraPubKeys)
{
extraPubKey.Encode(outStr);
}
}
/// <summary>
/// Replace the public key set on the secret ring with the corresponding key off the public ring.
/// </summary>
/// <param name="secretRing">Secret ring to be changed.</param>
/// <param name="publicRing">Public ring containing the new public key set.</param>
public static PgpSecretKeyRing ReplacePublicKeys(
PgpSecretKeyRing secretRing,
PgpPublicKeyRing publicRing)
{
IList newList = new ArrayList(secretRing.keys.Count);
foreach (PgpSecretKey sk in secretRing.keys)
{
PgpPublicKey pk = null;
try
{
pk = publicRing.GetPublicKey(sk.KeyId);
}
catch (PgpException e)
{
throw new InvalidOperationException(e.Message, e);
}
newList.Add(PgpSecretKey.ReplacePublicKey(sk, pk));
}
return new PgpSecretKeyRing(newList);
}
/// <summary>
/// Return a copy of the passed in secret key ring, with the master key and sub keys encrypted
/// using a new password and the passed in algorithm.
/// </summary>
/// <param name="ring">The <c>PgpSecretKeyRing</c> to be copied.</param>
/// <param name="oldPassPhrase">The current password for key.</param>
/// <param name="newPassPhrase">The new password for the key.</param>
/// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param>
/// <param name="rand">Source of randomness.</param>
public static PgpSecretKeyRing CopyWithNewPassword(
PgpSecretKeyRing ring,
char[] oldPassPhrase,
char[] newPassPhrase,
SymmetricKeyAlgorithmTag newEncAlgorithm,
SecureRandom rand)
{
IList newKeys = new ArrayList(ring.keys.Count);
foreach (PgpSecretKey secretKey in ring.GetSecretKeys())
{
newKeys.Add(PgpSecretKey.CopyWithNewPassword(secretKey, oldPassPhrase, newPassPhrase, newEncAlgorithm, rand));
}
return new PgpSecretKeyRing(newKeys, ring.extraPubKeys);
}
/// <summary>
/// Returns a new key ring with the secret key passed in either added or
/// replacing an existing one with the same key ID.
/// </summary>
/// <param name="secRing">The secret key ring to be modified.</param>
/// <param name="secKey">The secret key to be inserted.</param>
/// <returns>A new <c>PgpSecretKeyRing</c></returns>
public static PgpSecretKeyRing InsertSecretKey(
PgpSecretKeyRing secRing,
PgpSecretKey secKey)
{
ArrayList keys = new ArrayList(secRing.keys);
bool found = false;
bool masterFound = false;
for (int i = 0; i != keys.Count; i++)
{
PgpSecretKey key = (PgpSecretKey) keys[i];
if (key.KeyId == secKey.KeyId)
{
found = true;
keys[i] = secKey;
}
if (key.IsMasterKey)
{
masterFound = true;
}
}
if (!found)
{
if (secKey.IsMasterKey)
{
if (masterFound)
throw new ArgumentException("cannot add a master key to a ring that already has one");
keys.Insert(0, secKey);
}
else
{
keys.Add(secKey);
}
}
return new PgpSecretKeyRing(keys, secRing.extraPubKeys);
}
/// <summary>Returns a new key ring with the secret key passed in removed from the key ring.</summary>
/// <param name="secRing">The secret key ring to be modified.</param>
/// <param name="secKey">The secret key to be removed.</param>
/// <returns>A new <c>PgpSecretKeyRing</c>, or null if secKey is not found.</returns>
public static PgpSecretKeyRing RemoveSecretKey(
PgpSecretKeyRing secRing,
PgpSecretKey secKey)
{
ArrayList keys = new ArrayList(secRing.keys);
bool found = false;
for (int i = 0; i < keys.Count; i++)
{
PgpSecretKey key = (PgpSecretKey)keys[i];
if (key.KeyId == secKey.KeyId)
{
found = true;
keys.RemoveAt(i);
}
}
return found ? new PgpSecretKeyRing(keys, secRing.extraPubKeys) : null;
}
}
}

View File

@ -1,421 +1,422 @@
using System;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Date;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>A PGP signature object.</remarks>
public class PgpSignature
{
public const int BinaryDocument = 0x00;
public const int CanonicalTextDocument = 0x01;
public const int StandAlone = 0x02;
public const int DefaultCertification = 0x10;
public const int NoCertification = 0x11;
public const int CasualCertification = 0x12;
public const int PositiveCertification = 0x13;
public const int SubkeyBinding = 0x18;
public const int DirectKey = 0x1f;
public const int KeyRevocation = 0x20;
public const int SubkeyRevocation = 0x28;
public const int CertificationRevocation = 0x30;
public const int Timestamp = 0x40;
private readonly SignaturePacket sigPck;
private readonly int signatureType;
private readonly TrustPacket trustPck;
private ISigner sig;
private byte lastb; // Initial value anything but '\r'
internal PgpSignature(
BcpgInputStream bcpgInput)
: this((SignaturePacket)bcpgInput.ReadPacket())
{
}
internal PgpSignature(
SignaturePacket sigPacket)
: this(sigPacket, null)
{
}
internal PgpSignature(
SignaturePacket sigPacket,
TrustPacket trustPacket)
{
if (sigPacket == null)
throw new ArgumentNullException("sigPacket");
this.sigPck = sigPacket;
this.signatureType = sigPck.SignatureType;
this.trustPck = trustPacket;
}
private void GetSig()
{
this.sig = SignerUtilities.GetSigner(
PgpUtilities.GetSignatureName(sigPck.KeyAlgorithm, sigPck.HashAlgorithm));
}
/// <summary>The OpenPGP version number for this signature.</summary>
public int Version
{
get { return sigPck.Version; }
}
/// <summary>The key algorithm associated with this signature.</summary>
public PublicKeyAlgorithmTag KeyAlgorithm
{
get { return sigPck.KeyAlgorithm; }
}
/// <summary>The hash algorithm associated with this signature.</summary>
public HashAlgorithmTag HashAlgorithm
{
get { return sigPck.HashAlgorithm; }
}
public void InitVerify(
PgpPublicKey pubKey)
{
lastb = 0;
if (sig == null)
{
GetSig();
}
try
{
sig.Init(false, pubKey.GetKey());
}
catch (InvalidKeyException e)
{
throw new PgpException("invalid key.", e);
}
}
public void Update(
byte b)
{
if (signatureType == CanonicalTextDocument)
{
doCanonicalUpdateByte(b);
}
else
{
sig.Update(b);
}
}
private void doCanonicalUpdateByte(
byte b)
{
if (b == '\r')
{
doUpdateCRLF();
}
else if (b == '\n')
{
if (lastb != '\r')
{
doUpdateCRLF();
}
}
else
{
sig.Update(b);
}
lastb = b;
}
private void doUpdateCRLF()
{
sig.Update((byte)'\r');
sig.Update((byte)'\n');
}
public void Update(
params byte[] bytes)
{
Update(bytes, 0, bytes.Length);
}
public void Update(
byte[] bytes,
int off,
int length)
{
if (signatureType == CanonicalTextDocument)
{
int finish = off + length;
for (int i = off; i != finish; i++)
{
doCanonicalUpdateByte(bytes[i]);
}
}
else
{
sig.BlockUpdate(bytes, off, length);
}
}
public bool Verify()
{
byte[] trailer = GetSignatureTrailer();
sig.BlockUpdate(trailer, 0, trailer.Length);
return sig.VerifySignature(GetSignature());
}
private void UpdateWithIdData(
int header,
byte[] idBytes)
{
this.Update(
(byte) header,
(byte)(idBytes.Length >> 24),
(byte)(idBytes.Length >> 16),
(byte)(idBytes.Length >> 8),
(byte)(idBytes.Length));
this.Update(idBytes);
}
private void UpdateWithPublicKey(
PgpPublicKey key)
{
byte[] keyBytes = GetEncodedPublicKey(key);
this.Update(
(byte) 0x99,
(byte)(keyBytes.Length >> 8),
(byte)(keyBytes.Length));
this.Update(keyBytes);
}
/// <summary>
/// Verify the signature as certifying the passed in public key as associated
/// with the passed in user attributes.
/// </summary>
/// <param name="userAttributes">User attributes the key was stored under.</param>
/// <param name="key">The key to be verified.</param>
/// <returns>True, if the signature matches, false otherwise.</returns>
public bool VerifyCertification(
PgpUserAttributeSubpacketVector userAttributes,
PgpPublicKey key)
{
UpdateWithPublicKey(key);
//
// hash in the userAttributes
//
try
{
MemoryStream bOut = new MemoryStream();
foreach (UserAttributeSubpacket packet in userAttributes.ToSubpacketArray())
{
packet.Encode(bOut);
}
UpdateWithIdData(0xd1, bOut.ToArray());
}
catch (IOException e)
{
throw new PgpException("cannot encode subpacket array", e);
}
this.Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(this.GetSignature());
}
/// <summary>
/// Verify the signature as certifying the passed in public key as associated
/// with the passed in ID.
/// </summary>
/// <param name="id">ID the key was stored under.</param>
/// <param name="key">The key to be verified.</param>
/// <returns>True, if the signature matches, false otherwise.</returns>
public bool VerifyCertification(
string id,
PgpPublicKey key)
{
UpdateWithPublicKey(key);
//
// hash in the id
//
UpdateWithIdData(0xb4, Strings.ToByteArray(id));
Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(GetSignature());
}
/// <summary>Verify a certification for the passed in key against the passed in master key.</summary>
/// <param name="masterKey">The key we are verifying against.</param>
/// <param name="pubKey">The key we are verifying.</param>
/// <returns>True, if the certification is valid, false otherwise.</returns>
public bool VerifyCertification(
PgpPublicKey masterKey,
PgpPublicKey pubKey)
{
UpdateWithPublicKey(masterKey);
UpdateWithPublicKey(pubKey);
Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(GetSignature());
}
/// <summary>Verify a key certification, such as revocation, for the passed in key.</summary>
/// <param name="pubKey">The key we are checking.</param>
/// <returns>True, if the certification is valid, false otherwise.</returns>
public bool VerifyCertification(
PgpPublicKey pubKey)
{
if (SignatureType != KeyRevocation
&& SignatureType != SubkeyRevocation)
{
throw new InvalidOperationException("signature is not a key signature");
}
UpdateWithPublicKey(pubKey);
Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(GetSignature());
}
public int SignatureType
{
get { return sigPck.SignatureType; }
}
/// <summary>The ID of the key that created the signature.</summary>
public long KeyId
{
get { return sigPck.KeyId; }
}
[Obsolete("Use 'CreationTime' property instead")]
public DateTime GetCreationTime()
{
return CreationTime;
}
/// <summary>The creation time of this signature.</summary>
public DateTime CreationTime
{
get { return DateTimeUtilities.UnixMsToDateTime(sigPck.CreationTime); }
}
public byte[] GetSignatureTrailer()
{
return sigPck.GetSignatureTrailer();
}
/// <summary>
/// Return true if the signature has either hashed or unhashed subpackets.
/// </summary>
public bool HasSubpackets
{
get
{
return sigPck.GetHashedSubPackets() != null
|| sigPck.GetUnhashedSubPackets() != null;
}
}
public PgpSignatureSubpacketVector GetHashedSubPackets()
{
return createSubpacketVector(sigPck.GetHashedSubPackets());
}
public PgpSignatureSubpacketVector GetUnhashedSubPackets()
{
return createSubpacketVector(sigPck.GetUnhashedSubPackets());
}
private PgpSignatureSubpacketVector createSubpacketVector(SignatureSubpacket[] pcks)
{
return pcks == null ? null : new PgpSignatureSubpacketVector(pcks);
}
public byte[] GetSignature()
{
MPInteger[] sigValues = sigPck.GetSignature();
byte[] signature;
if (sigValues != null)
{
if (sigValues.Length == 1) // an RSA signature
{
signature = sigValues[0].Value.ToByteArrayUnsigned();
}
else
{
try
{
signature = new DerSequence(
new DerInteger(sigValues[0].Value),
new DerInteger(sigValues[1].Value)).GetEncoded();
}
catch (IOException e)
{
throw new PgpException("exception encoding DSA sig.", e);
}
}
}
else
{
signature = sigPck.GetSignatureBytes();
}
return signature;
}
// TODO Handle the encoding stuff by subclassing BcpgObject?
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStream)
{
BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStream);
bcpgOut.WritePacket(sigPck);
if (trustPck != null)
{
bcpgOut.WritePacket(trustPck);
}
}
private byte[] GetEncodedPublicKey(
PgpPublicKey pubKey)
{
try
{
return pubKey.publicPk.GetEncodedContents();
}
catch (IOException e)
{
throw new PgpException("exception preparing key.", e);
}
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Date;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>A PGP signature object.</remarks>
public class PgpSignature
{
public const int BinaryDocument = 0x00;
public const int CanonicalTextDocument = 0x01;
public const int StandAlone = 0x02;
public const int DefaultCertification = 0x10;
public const int NoCertification = 0x11;
public const int CasualCertification = 0x12;
public const int PositiveCertification = 0x13;
public const int SubkeyBinding = 0x18;
public const int PrimaryKeyBinding = 0x19;
public const int DirectKey = 0x1f;
public const int KeyRevocation = 0x20;
public const int SubkeyRevocation = 0x28;
public const int CertificationRevocation = 0x30;
public const int Timestamp = 0x40;
private readonly SignaturePacket sigPck;
private readonly int signatureType;
private readonly TrustPacket trustPck;
private ISigner sig;
private byte lastb; // Initial value anything but '\r'
internal PgpSignature(
BcpgInputStream bcpgInput)
: this((SignaturePacket)bcpgInput.ReadPacket())
{
}
internal PgpSignature(
SignaturePacket sigPacket)
: this(sigPacket, null)
{
}
internal PgpSignature(
SignaturePacket sigPacket,
TrustPacket trustPacket)
{
if (sigPacket == null)
throw new ArgumentNullException("sigPacket");
this.sigPck = sigPacket;
this.signatureType = sigPck.SignatureType;
this.trustPck = trustPacket;
}
private void GetSig()
{
this.sig = SignerUtilities.GetSigner(
PgpUtilities.GetSignatureName(sigPck.KeyAlgorithm, sigPck.HashAlgorithm));
}
/// <summary>The OpenPGP version number for this signature.</summary>
public int Version
{
get { return sigPck.Version; }
}
/// <summary>The key algorithm associated with this signature.</summary>
public PublicKeyAlgorithmTag KeyAlgorithm
{
get { return sigPck.KeyAlgorithm; }
}
/// <summary>The hash algorithm associated with this signature.</summary>
public HashAlgorithmTag HashAlgorithm
{
get { return sigPck.HashAlgorithm; }
}
public void InitVerify(
PgpPublicKey pubKey)
{
lastb = 0;
if (sig == null)
{
GetSig();
}
try
{
sig.Init(false, pubKey.GetKey());
}
catch (InvalidKeyException e)
{
throw new PgpException("invalid key.", e);
}
}
public void Update(
byte b)
{
if (signatureType == CanonicalTextDocument)
{
doCanonicalUpdateByte(b);
}
else
{
sig.Update(b);
}
}
private void doCanonicalUpdateByte(
byte b)
{
if (b == '\r')
{
doUpdateCRLF();
}
else if (b == '\n')
{
if (lastb != '\r')
{
doUpdateCRLF();
}
}
else
{
sig.Update(b);
}
lastb = b;
}
private void doUpdateCRLF()
{
sig.Update((byte)'\r');
sig.Update((byte)'\n');
}
public void Update(
params byte[] bytes)
{
Update(bytes, 0, bytes.Length);
}
public void Update(
byte[] bytes,
int off,
int length)
{
if (signatureType == CanonicalTextDocument)
{
int finish = off + length;
for (int i = off; i != finish; i++)
{
doCanonicalUpdateByte(bytes[i]);
}
}
else
{
sig.BlockUpdate(bytes, off, length);
}
}
public bool Verify()
{
byte[] trailer = GetSignatureTrailer();
sig.BlockUpdate(trailer, 0, trailer.Length);
return sig.VerifySignature(GetSignature());
}
private void UpdateWithIdData(
int header,
byte[] idBytes)
{
this.Update(
(byte) header,
(byte)(idBytes.Length >> 24),
(byte)(idBytes.Length >> 16),
(byte)(idBytes.Length >> 8),
(byte)(idBytes.Length));
this.Update(idBytes);
}
private void UpdateWithPublicKey(
PgpPublicKey key)
{
byte[] keyBytes = GetEncodedPublicKey(key);
this.Update(
(byte) 0x99,
(byte)(keyBytes.Length >> 8),
(byte)(keyBytes.Length));
this.Update(keyBytes);
}
/// <summary>
/// Verify the signature as certifying the passed in public key as associated
/// with the passed in user attributes.
/// </summary>
/// <param name="userAttributes">User attributes the key was stored under.</param>
/// <param name="key">The key to be verified.</param>
/// <returns>True, if the signature matches, false otherwise.</returns>
public bool VerifyCertification(
PgpUserAttributeSubpacketVector userAttributes,
PgpPublicKey key)
{
UpdateWithPublicKey(key);
//
// hash in the userAttributes
//
try
{
MemoryStream bOut = new MemoryStream();
foreach (UserAttributeSubpacket packet in userAttributes.ToSubpacketArray())
{
packet.Encode(bOut);
}
UpdateWithIdData(0xd1, bOut.ToArray());
}
catch (IOException e)
{
throw new PgpException("cannot encode subpacket array", e);
}
this.Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(this.GetSignature());
}
/// <summary>
/// Verify the signature as certifying the passed in public key as associated
/// with the passed in ID.
/// </summary>
/// <param name="id">ID the key was stored under.</param>
/// <param name="key">The key to be verified.</param>
/// <returns>True, if the signature matches, false otherwise.</returns>
public bool VerifyCertification(
string id,
PgpPublicKey key)
{
UpdateWithPublicKey(key);
//
// hash in the id
//
UpdateWithIdData(0xb4, Strings.ToByteArray(id));
Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(GetSignature());
}
/// <summary>Verify a certification for the passed in key against the passed in master key.</summary>
/// <param name="masterKey">The key we are verifying against.</param>
/// <param name="pubKey">The key we are verifying.</param>
/// <returns>True, if the certification is valid, false otherwise.</returns>
public bool VerifyCertification(
PgpPublicKey masterKey,
PgpPublicKey pubKey)
{
UpdateWithPublicKey(masterKey);
UpdateWithPublicKey(pubKey);
Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(GetSignature());
}
/// <summary>Verify a key certification, such as revocation, for the passed in key.</summary>
/// <param name="pubKey">The key we are checking.</param>
/// <returns>True, if the certification is valid, false otherwise.</returns>
public bool VerifyCertification(
PgpPublicKey pubKey)
{
if (SignatureType != KeyRevocation
&& SignatureType != SubkeyRevocation)
{
throw new InvalidOperationException("signature is not a key signature");
}
UpdateWithPublicKey(pubKey);
Update(sigPck.GetSignatureTrailer());
return sig.VerifySignature(GetSignature());
}
public int SignatureType
{
get { return sigPck.SignatureType; }
}
/// <summary>The ID of the key that created the signature.</summary>
public long KeyId
{
get { return sigPck.KeyId; }
}
[Obsolete("Use 'CreationTime' property instead")]
public DateTime GetCreationTime()
{
return CreationTime;
}
/// <summary>The creation time of this signature.</summary>
public DateTime CreationTime
{
get { return DateTimeUtilities.UnixMsToDateTime(sigPck.CreationTime); }
}
public byte[] GetSignatureTrailer()
{
return sigPck.GetSignatureTrailer();
}
/// <summary>
/// Return true if the signature has either hashed or unhashed subpackets.
/// </summary>
public bool HasSubpackets
{
get
{
return sigPck.GetHashedSubPackets() != null
|| sigPck.GetUnhashedSubPackets() != null;
}
}
public PgpSignatureSubpacketVector GetHashedSubPackets()
{
return createSubpacketVector(sigPck.GetHashedSubPackets());
}
public PgpSignatureSubpacketVector GetUnhashedSubPackets()
{
return createSubpacketVector(sigPck.GetUnhashedSubPackets());
}
private PgpSignatureSubpacketVector createSubpacketVector(SignatureSubpacket[] pcks)
{
return pcks == null ? null : new PgpSignatureSubpacketVector(pcks);
}
public byte[] GetSignature()
{
MPInteger[] sigValues = sigPck.GetSignature();
byte[] signature;
if (sigValues != null)
{
if (sigValues.Length == 1) // an RSA signature
{
signature = sigValues[0].Value.ToByteArrayUnsigned();
}
else
{
try
{
signature = new DerSequence(
new DerInteger(sigValues[0].Value),
new DerInteger(sigValues[1].Value)).GetEncoded();
}
catch (IOException e)
{
throw new PgpException("exception encoding DSA sig.", e);
}
}
}
else
{
signature = sigPck.GetSignatureBytes();
}
return signature;
}
// TODO Handle the encoding stuff by subclassing BcpgObject?
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Encode(bOut);
return bOut.ToArray();
}
public void Encode(
Stream outStream)
{
BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStream);
bcpgOut.WritePacket(sigPck);
if (trustPck != null)
{
bcpgOut.WritePacket(trustPck);
}
}
private byte[] GetEncodedPublicKey(
PgpPublicKey pubKey)
{
try
{
return pubKey.publicPk.GetEncodedContents();
}
catch (IOException e)
{
throw new PgpException("exception preparing key.", e);
}
}
}
}

View File

@ -1,141 +1,163 @@
using System;
using System.Collections;
using Org.BouncyCastle.Bcpg.Sig;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>Generator for signature subpackets.</remarks>
public class PgpSignatureSubpacketGenerator
{
private ArrayList list = new ArrayList();
public void SetRevocable(
bool isCritical,
bool isRevocable)
{
list.Add(new Revocable(isCritical, isRevocable));
}
public void SetExportable(
bool isCritical,
bool isExportable)
{
list.Add(new Exportable(isCritical, isExportable));
}
/// <summary>
/// Add a TrustSignature packet to the signature. The values for depth and trust are largely
/// installation dependent but there are some guidelines in RFC 4880 - 5.2.3.13.
/// </summary>
/// <param name="isCritical">true if the packet is critical.</param>
/// <param name="depth">depth level.</param>
/// <param name="trustAmount">trust amount.</param>
public void SetTrust(
bool isCritical,
int depth,
int trustAmount)
{
list.Add(new TrustSignature(isCritical, depth, trustAmount));
}
/// <summary>
/// Set the number of seconds a key is valid for after the time of its creation.
/// A value of zero means the key never expires.
/// </summary>
/// <param name="isCritical">True, if should be treated as critical, false otherwise.</param>
/// <param name="seconds">The number of seconds the key is valid, or zero if no expiry.</param>
public void SetKeyExpirationTime(
bool isCritical,
long seconds)
{
list.Add(new KeyExpirationTime(isCritical, seconds));
}
/// <summary>
/// Set the number of seconds a signature is valid for after the time of its creation.
/// A value of zero means the signature never expires.
/// </summary>
/// <param name="isCritical">True, if should be treated as critical, false otherwise.</param>
/// <param name="seconds">The number of seconds the signature is valid, or zero if no expiry.</param>
public void SetSignatureExpirationTime(
bool isCritical,
long seconds)
{
list.Add(new SignatureExpirationTime(isCritical, seconds));
}
/// <summary>
/// Set the creation time for the signature.
/// <p>
/// Note: this overrides the generation of a creation time when the signature
/// is generated.</p>
/// </summary>
public void SetSignatureCreationTime(
bool isCritical,
DateTime date)
{
list.Add(new SignatureCreationTime(isCritical, date));
}
public void SetPreferredHashAlgorithms(
bool isCritical,
int[] algorithms)
{
list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredHashAlgorithms, isCritical, algorithms));
}
public void SetPreferredSymmetricAlgorithms(
bool isCritical,
int[] algorithms)
{
list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredSymmetricAlgorithms, isCritical, algorithms));
}
public void SetPreferredCompressionAlgorithms(
bool isCritical,
int[] algorithms)
{
list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredCompressionAlgorithms, isCritical, algorithms));
}
public void SetKeyFlags(
bool isCritical,
int flags)
{
list.Add(new KeyFlags(isCritical, flags));
}
public void SetSignerUserId(
bool isCritical,
string userId)
{
if (userId == null)
throw new ArgumentNullException("userId");
list.Add(new SignerUserId(isCritical, userId));
}
public void SetPrimaryUserId(
bool isCritical,
bool isPrimaryUserId)
{
list.Add(new PrimaryUserId(isCritical, isPrimaryUserId));
}
public void SetNotationData(
bool isCritical,
bool isHumanReadable,
string notationName,
string notationValue)
{
list.Add(new NotationData(isCritical, isHumanReadable, notationName, notationValue));
}
public PgpSignatureSubpacketVector Generate()
{
return new PgpSignatureSubpacketVector(
(SignatureSubpacket[]) list.ToArray(typeof(SignatureSubpacket)));
}
}
}
using System;
using System.Collections;
using Org.BouncyCastle.Bcpg.Sig;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>Generator for signature subpackets.</remarks>
public class PgpSignatureSubpacketGenerator
{
private ArrayList list = new ArrayList();
public void SetRevocable(
bool isCritical,
bool isRevocable)
{
list.Add(new Revocable(isCritical, isRevocable));
}
public void SetExportable(
bool isCritical,
bool isExportable)
{
list.Add(new Exportable(isCritical, isExportable));
}
/// <summary>
/// Add a TrustSignature packet to the signature. The values for depth and trust are largely
/// installation dependent but there are some guidelines in RFC 4880 - 5.2.3.13.
/// </summary>
/// <param name="isCritical">true if the packet is critical.</param>
/// <param name="depth">depth level.</param>
/// <param name="trustAmount">trust amount.</param>
public void SetTrust(
bool isCritical,
int depth,
int trustAmount)
{
list.Add(new TrustSignature(isCritical, depth, trustAmount));
}
/// <summary>
/// Set the number of seconds a key is valid for after the time of its creation.
/// A value of zero means the key never expires.
/// </summary>
/// <param name="isCritical">True, if should be treated as critical, false otherwise.</param>
/// <param name="seconds">The number of seconds the key is valid, or zero if no expiry.</param>
public void SetKeyExpirationTime(
bool isCritical,
long seconds)
{
list.Add(new KeyExpirationTime(isCritical, seconds));
}
/// <summary>
/// Set the number of seconds a signature is valid for after the time of its creation.
/// A value of zero means the signature never expires.
/// </summary>
/// <param name="isCritical">True, if should be treated as critical, false otherwise.</param>
/// <param name="seconds">The number of seconds the signature is valid, or zero if no expiry.</param>
public void SetSignatureExpirationTime(
bool isCritical,
long seconds)
{
list.Add(new SignatureExpirationTime(isCritical, seconds));
}
/// <summary>
/// Set the creation time for the signature.
/// <p>
/// Note: this overrides the generation of a creation time when the signature
/// is generated.</p>
/// </summary>
public void SetSignatureCreationTime(
bool isCritical,
DateTime date)
{
list.Add(new SignatureCreationTime(isCritical, date));
}
public void SetPreferredHashAlgorithms(
bool isCritical,
int[] algorithms)
{
list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredHashAlgorithms, isCritical, algorithms));
}
public void SetPreferredSymmetricAlgorithms(
bool isCritical,
int[] algorithms)
{
list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredSymmetricAlgorithms, isCritical, algorithms));
}
public void SetPreferredCompressionAlgorithms(
bool isCritical,
int[] algorithms)
{
list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredCompressionAlgorithms, isCritical, algorithms));
}
public void SetKeyFlags(
bool isCritical,
int flags)
{
list.Add(new KeyFlags(isCritical, flags));
}
public void SetSignerUserId(
bool isCritical,
string userId)
{
if (userId == null)
throw new ArgumentNullException("userId");
list.Add(new SignerUserId(isCritical, userId));
}
public void SetEmbeddedSignature(
bool isCritical,
PgpSignature pgpSignature)
{
byte[] sig = pgpSignature.GetEncoded();
byte[] data;
// TODO Should be >= ?
if (sig.Length - 1 > 256)
{
data = new byte[sig.Length - 3];
}
else
{
data = new byte[sig.Length - 2];
}
Array.Copy(sig, sig.Length - data.Length, data, 0, data.Length);
list.Add(new EmbeddedSignature(isCritical, data));
}
public void SetPrimaryUserId(
bool isCritical,
bool isPrimaryUserId)
{
list.Add(new PrimaryUserId(isCritical, isPrimaryUserId));
}
public void SetNotationData(
bool isCritical,
bool isHumanReadable,
string notationName,
string notationValue)
{
list.Add(new NotationData(isCritical, isHumanReadable, notationName, notationValue));
}
public PgpSignatureSubpacketVector Generate()
{
return new PgpSignatureSubpacketVector(
(SignatureSubpacket[]) list.ToArray(typeof(SignatureSubpacket)));
}
}
}

View File

@ -1,75 +1,75 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Pkcs
{
public sealed class EncryptedPrivateKeyInfoFactory
{
private EncryptedPrivateKeyInfoFactory()
{
}
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
DerObjectIdentifier algorithm,
char[] passPhrase,
byte[] salt,
int iterationCount,
AsymmetricKeyParameter key)
{
return CreateEncryptedPrivateKeyInfo(
algorithm.Id, passPhrase, salt, iterationCount,
PrivateKeyInfoFactory.CreatePrivateKeyInfo(key));
}
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
string algorithm,
char[] passPhrase,
byte[] salt,
int iterationCount,
AsymmetricKeyParameter key)
{
return CreateEncryptedPrivateKeyInfo(
algorithm, passPhrase, salt, iterationCount,
PrivateKeyInfoFactory.CreatePrivateKeyInfo(key));
}
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
string algorithm,
char[] passPhrase,
byte[] salt,
int iterationCount,
PrivateKeyInfo keyInfo)
{
if (!PbeUtilities.IsPbeAlgorithm(algorithm))
throw new ArgumentException("attempt to use non-Pbe algorithm with Pbe EncryptedPrivateKeyInfo generation");
IBufferedCipher cipher = PbeUtilities.CreateEngine(algorithm) as IBufferedCipher;
if (cipher == null)
{
// TODO Throw exception?
}
Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters(
algorithm, salt, iterationCount);
ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters(
algorithm, passPhrase, parameters);
cipher.Init(true, keyParameters);
byte[] keyBytes = keyInfo.GetEncoded();
byte[] encoding = cipher.DoFinal(keyBytes);
DerObjectIdentifier oid = PbeUtilities.GetObjectIdentifier(algorithm);
AlgorithmIdentifier algID = new AlgorithmIdentifier(oid, parameters);
return new EncryptedPrivateKeyInfo(algID, encoding);
}
}
}
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Pkcs
{
public sealed class EncryptedPrivateKeyInfoFactory
{
private EncryptedPrivateKeyInfoFactory()
{
}
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
DerObjectIdentifier algorithm,
char[] passPhrase,
byte[] salt,
int iterationCount,
AsymmetricKeyParameter key)
{
return CreateEncryptedPrivateKeyInfo(
algorithm.Id, passPhrase, salt, iterationCount,
PrivateKeyInfoFactory.CreatePrivateKeyInfo(key));
}
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
string algorithm,
char[] passPhrase,
byte[] salt,
int iterationCount,
AsymmetricKeyParameter key)
{
return CreateEncryptedPrivateKeyInfo(
algorithm, passPhrase, salt, iterationCount,
PrivateKeyInfoFactory.CreatePrivateKeyInfo(key));
}
public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
string algorithm,
char[] passPhrase,
byte[] salt,
int iterationCount,
PrivateKeyInfo keyInfo)
{
if (!PbeUtilities.IsPbeAlgorithm(algorithm))
throw new ArgumentException("attempt to use non-PBE algorithm with PBE EncryptedPrivateKeyInfo generation");
IBufferedCipher cipher = PbeUtilities.CreateEngine(algorithm) as IBufferedCipher;
if (cipher == null)
{
// TODO Throw exception?
}
Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters(
algorithm, salt, iterationCount);
ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters(
algorithm, passPhrase, parameters);
cipher.Init(true, keyParameters);
byte[] keyBytes = keyInfo.GetEncoded();
byte[] encoding = cipher.DoFinal(keyBytes);
DerObjectIdentifier oid = PbeUtilities.GetObjectIdentifier(algorithm);
AlgorithmIdentifier algID = new AlgorithmIdentifier(oid, parameters);
return new EncryptedPrivateKeyInfo(algID, encoding);
}
}
}

View File

@ -1,99 +1,100 @@
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Agreement.Kdf;
using Org.BouncyCastle.Crypto.Digests;
namespace Org.BouncyCastle.Security
{
/// <remarks>
/// Utility class for creating IBasicAgreement objects from their names/Oids
/// </remarks>
public sealed class AgreementUtilities
{
private AgreementUtilities()
{
}
private static readonly Hashtable algorithms = new Hashtable();
// private static readonly Hashtable oids = new Hashtable();
static AgreementUtilities()
{
//algorithms[X9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.Id] = ?;
algorithms[X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id] = "DHWITHSHA1KDF";
//algorithms[X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id] = ?;
}
public static IBasicAgreement GetBasicAgreement(
DerObjectIdentifier oid)
{
return GetBasicAgreement(oid.Id);
}
public static IBasicAgreement GetBasicAgreement(
string algorithm)
{
string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "DH":
return new DHBasicAgreement();
case "ECDH":
return new ECDHBasicAgreement();
case "ECDHC":
return new ECDHCBasicAgreement();
}
throw new SecurityUtilityException("Basic Agreement " + algorithm + " not recognised.");
}
public static IBasicAgreement GetBasicAgreementWithKdf(
DerObjectIdentifier oid,
string wrapAlgorithm)
{
return GetBasicAgreementWithKdf(oid.Id, wrapAlgorithm);
}
public static IBasicAgreement GetBasicAgreementWithKdf(
string agreeAlgorithm,
string wrapAlgorithm)
{
string upper = agreeAlgorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "DHWITHSHA1KDF":
return new ECDHWithKdfBasicAgreement(
wrapAlgorithm,
new ECDHKekGenerator(
new Sha1Digest()));
}
throw new SecurityUtilityException("Basic Agreement (with KDF) " + agreeAlgorithm + " not recognised.");
}
public static string GetAlgorithmName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
}
}
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Agreement.Kdf;
using Org.BouncyCastle.Crypto.Digests;
namespace Org.BouncyCastle.Security
{
/// <remarks>
/// Utility class for creating IBasicAgreement objects from their names/Oids
/// </remarks>
public sealed class AgreementUtilities
{
private AgreementUtilities()
{
}
private static readonly Hashtable algorithms = new Hashtable();
// private static readonly Hashtable oids = new Hashtable();
static AgreementUtilities()
{
//algorithms[X9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.Id] = ?;
algorithms[X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id] = "DHWITHSHA1KDF";
//algorithms[X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id] = ?;
}
public static IBasicAgreement GetBasicAgreement(
DerObjectIdentifier oid)
{
return GetBasicAgreement(oid.Id);
}
public static IBasicAgreement GetBasicAgreement(
string algorithm)
{
string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "DH":
case "DIFFIEHELLMAN":
return new DHBasicAgreement();
case "ECDH":
return new ECDHBasicAgreement();
case "ECDHC":
return new ECDHCBasicAgreement();
}
throw new SecurityUtilityException("Basic Agreement " + algorithm + " not recognised.");
}
public static IBasicAgreement GetBasicAgreementWithKdf(
DerObjectIdentifier oid,
string wrapAlgorithm)
{
return GetBasicAgreementWithKdf(oid.Id, wrapAlgorithm);
}
public static IBasicAgreement GetBasicAgreementWithKdf(
string agreeAlgorithm,
string wrapAlgorithm)
{
string upper = agreeAlgorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "DHWITHSHA1KDF":
return new ECDHWithKdfBasicAgreement(
wrapAlgorithm,
new ECDHKekGenerator(
new Sha1Digest()));
}
throw new SecurityUtilityException("Basic Agreement (with KDF) " + agreeAlgorithm + " not recognised.");
}
public static string GetAlgorithmName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
}
}

View File

@ -1,352 +1,353 @@
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Iana;
using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
namespace Org.BouncyCastle.Security
{
public sealed class GeneratorUtilities
{
private GeneratorUtilities()
{
}
private static readonly Hashtable kgAlgorithms = new Hashtable();
private static readonly Hashtable kpgAlgorithms = new Hashtable();
static GeneratorUtilities()
{
//
// key generators.
//
AddKgAlgorithm("AES",
"AESWRAP");
AddKgAlgorithm("AES128",
"2.16.840.1.101.3.4.2",
NistObjectIdentifiers.IdAes128Cbc,
NistObjectIdentifiers.IdAes128Cfb,
NistObjectIdentifiers.IdAes128Ecb,
NistObjectIdentifiers.IdAes128Ofb,
NistObjectIdentifiers.IdAes128Wrap);
AddKgAlgorithm("AES192",
"2.16.840.1.101.3.4.22",
NistObjectIdentifiers.IdAes192Cbc,
NistObjectIdentifiers.IdAes192Cfb,
NistObjectIdentifiers.IdAes192Ecb,
NistObjectIdentifiers.IdAes192Ofb,
NistObjectIdentifiers.IdAes192Wrap);
AddKgAlgorithm("AES256",
"2.16.840.1.101.3.4.42",
NistObjectIdentifiers.IdAes256Cbc,
NistObjectIdentifiers.IdAes256Cfb,
NistObjectIdentifiers.IdAes256Ecb,
NistObjectIdentifiers.IdAes256Ofb,
NistObjectIdentifiers.IdAes256Wrap);
AddKgAlgorithm("BLOWFISH");
AddKgAlgorithm("CAMELLIA",
"CAMELLIAWRAP");
AddKgAlgorithm("CAMELLIA128",
NttObjectIdentifiers.IdCamellia128Cbc,
NttObjectIdentifiers.IdCamellia128Wrap);
AddKgAlgorithm("CAMELLIA192",
NttObjectIdentifiers.IdCamellia192Cbc,
NttObjectIdentifiers.IdCamellia192Wrap);
AddKgAlgorithm("CAMELLIA256",
NttObjectIdentifiers.IdCamellia256Cbc,
NttObjectIdentifiers.IdCamellia256Wrap);
AddKgAlgorithm("CAST5",
"1.2.840.113533.7.66.10");
AddKgAlgorithm("CAST6");
AddKgAlgorithm("DES",
OiwObjectIdentifiers.DesCbc);
AddKgAlgorithm("DESEDE",
"DESEDEWRAP",
PkcsObjectIdentifiers.IdAlgCms3DesWrap);
AddKgAlgorithm("DESEDE3",
PkcsObjectIdentifiers.DesEde3Cbc);
AddKgAlgorithm("GOST28147",
"GOST",
"GOST-28147",
CryptoProObjectIdentifiers.GostR28147Cbc);
AddKgAlgorithm("HC128");
AddKgAlgorithm("HC256");
AddKgAlgorithm("IDEA",
"1.3.6.1.4.1.188.7.1.1.2");
AddKgAlgorithm("NOEKEON");
AddKgAlgorithm("RC2",
PkcsObjectIdentifiers.RC2Cbc,
PkcsObjectIdentifiers.IdAlgCmsRC2Wrap);
AddKgAlgorithm("RC4",
"ARC4",
"1.2.840.113549.3.4");
AddKgAlgorithm("RC5",
"RC5-32");
AddKgAlgorithm("RC5-64");
AddKgAlgorithm("RC6");
AddKgAlgorithm("RIJNDAEL");
AddKgAlgorithm("SALSA20");
AddKgAlgorithm("SEED",
KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap,
KisaObjectIdentifiers.IdSeedCbc);
AddKgAlgorithm("SERPENT");
AddKgAlgorithm("SKIPJACK");
AddKgAlgorithm("TEA");
AddKgAlgorithm("TWOFISH");
AddKgAlgorithm("VMPC");
AddKgAlgorithm("VMPC-KSA3");
AddKgAlgorithm("XTEA");
//
// HMac key generators
//
AddHMacKeyGenerator("MD2");
AddHMacKeyGenerator("MD4");
AddHMacKeyGenerator("MD5",
IanaObjectIdentifiers.HmacMD5);
AddHMacKeyGenerator("SHA1",
PkcsObjectIdentifiers.IdHmacWithSha1,
IanaObjectIdentifiers.HmacSha1);
AddHMacKeyGenerator("SHA224",
PkcsObjectIdentifiers.IdHmacWithSha224);
AddHMacKeyGenerator("SHA256",
PkcsObjectIdentifiers.IdHmacWithSha256);
AddHMacKeyGenerator("SHA384",
PkcsObjectIdentifiers.IdHmacWithSha384);
AddHMacKeyGenerator("SHA512",
PkcsObjectIdentifiers.IdHmacWithSha512);
AddHMacKeyGenerator("RIPEMD128");
AddHMacKeyGenerator("RIPEMD160",
IanaObjectIdentifiers.HmacRipeMD160);
AddHMacKeyGenerator("TIGER",
IanaObjectIdentifiers.HmacTiger);
//
// key pair generators.
//
AddKpgAlgorithm("DH");
AddKpgAlgorithm("DSA");
AddKpgAlgorithm("EC");
AddKpgAlgorithm("ECDH",
"ECIES");
AddKpgAlgorithm("ECDHC");
AddKpgAlgorithm("ECDSA");
AddKpgAlgorithm("ECGOST3410",
"ECGOST-3410",
"GOST-3410-2001");
AddKpgAlgorithm("ELGAMAL");
AddKpgAlgorithm("GOST3410",
"GOST-3410",
"GOST-3410-94");
AddKpgAlgorithm("RSA",
"1.2.840.113549.1.1.1");
}
private static void AddKgAlgorithm(
string canonicalName,
params object[] aliases)
{
kgAlgorithms[canonicalName] = canonicalName;
foreach (object alias in aliases)
{
kgAlgorithms[alias.ToString()] = canonicalName;
}
}
private static void AddKpgAlgorithm(
string canonicalName,
params object[] aliases)
{
kpgAlgorithms[canonicalName] = canonicalName;
foreach (object alias in aliases)
{
kpgAlgorithms[alias.ToString()] = canonicalName;
}
}
private static void AddHMacKeyGenerator(
string algorithm,
params object[] aliases)
{
string mainName = "HMAC" + algorithm;
kgAlgorithms[mainName] = mainName;
kgAlgorithms["HMAC-" + algorithm] = mainName;
kgAlgorithms["HMAC/" + algorithm] = mainName;
foreach (object alias in aliases)
{
kgAlgorithms[alias.ToString()] = mainName;
}
}
// TODO Consider making this public
internal static string GetCanonicalKeyGeneratorAlgorithm(
string algorithm)
{
return (string) kgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
}
// TODO Consider making this public
internal static string GetCanonicalKeyPairGeneratorAlgorithm(
string algorithm)
{
return (string) kpgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
}
public static CipherKeyGenerator GetKeyGenerator(
DerObjectIdentifier oid)
{
return GetKeyGenerator(oid.Id);
}
public static CipherKeyGenerator GetKeyGenerator(
string algorithm)
{
string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm);
if (canonicalName == null)
throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised.");
switch (canonicalName)
{
case "DES":
return new DesKeyGenerator(64);
case "DESEDE":
return new DesEdeKeyGenerator(128);
case "DESEDE3":
return new DesEdeKeyGenerator(192);
case "AES":
return new CipherKeyGenerator(192);
case "AES128":
return new CipherKeyGenerator(128);
case "AES192":
return new CipherKeyGenerator(192);
case "AES256":
return new CipherKeyGenerator(256);
case "BLOWFISH":
return new CipherKeyGenerator(448);
case "CAMELLIA":
return new CipherKeyGenerator(256);
case "CAMELLIA128":
return new CipherKeyGenerator(128);
case "CAMELLIA192":
return new CipherKeyGenerator(192);
case "CAMELLIA256":
return new CipherKeyGenerator(256);
case "CAST5":
return new CipherKeyGenerator(128);
case "CAST6":
return new CipherKeyGenerator(256);
case "GOST28147":
return new CipherKeyGenerator(256);
case "HC128":
return new CipherKeyGenerator(128);
case "HC256":
return new CipherKeyGenerator(256);
case "HMACMD2":
case "HMACMD4":
case "HMACMD5":
return new CipherKeyGenerator(128);
case "HMACSHA1":
return new CipherKeyGenerator(160);
case "HMACSHA224":
return new CipherKeyGenerator(224);
case "HMACSHA256":
return new CipherKeyGenerator(256);
case "HMACSHA384":
return new CipherKeyGenerator(384);
case "HMACSHA512":
return new CipherKeyGenerator(512);
case "HMACRIPEMD128":
return new CipherKeyGenerator(128);
case "HMACRIPEMD160":
return new CipherKeyGenerator(160);
case "HMACTIGER":
return new CipherKeyGenerator(192);
case "IDEA":
return new CipherKeyGenerator(128);
case "NOEKEON":
return new CipherKeyGenerator(128);
case "RC2":
case "RC4":
case "RC5":
return new CipherKeyGenerator(128);
case "RC5-64":
case "RC6":
return new CipherKeyGenerator(256);
case "RIJNDAEL":
return new CipherKeyGenerator(192);
case "SALSA20":
return new CipherKeyGenerator(128);
case "SEED":
return new CipherKeyGenerator(128);
case "SERPENT":
return new CipherKeyGenerator(192);
case "SKIPJACK":
return new CipherKeyGenerator(80);
case "TEA":
case "XTEA":
return new CipherKeyGenerator(128);
case "TWOFISH":
return new CipherKeyGenerator(256);
case "VMPC":
case "VMPC-KSA3":
return new CipherKeyGenerator(128);
}
throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised.");
}
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
DerObjectIdentifier oid)
{
return GetKeyPairGenerator(oid.Id);
}
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
string algorithm)
{
string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm);
if (canonicalName == null)
throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised.");
switch (canonicalName)
{
case "DH":
return new DHKeyPairGenerator();
case "DSA":
return new DsaKeyPairGenerator();
case "EC":
case "ECDH":
case "ECDHC":
case "ECDSA":
case "ECGOST3410":
return new ECKeyPairGenerator(canonicalName);
case "ELGAMAL":
return new ElGamalKeyPairGenerator();
case "GOST3410":
return new Gost3410KeyPairGenerator();
case "RSA":
return new RsaKeyPairGenerator();
default:
break;
}
throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised.");
}
}
}
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Iana;
using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
namespace Org.BouncyCastle.Security
{
public sealed class GeneratorUtilities
{
private GeneratorUtilities()
{
}
private static readonly Hashtable kgAlgorithms = new Hashtable();
private static readonly Hashtable kpgAlgorithms = new Hashtable();
static GeneratorUtilities()
{
//
// key generators.
//
AddKgAlgorithm("AES",
"AESWRAP");
AddKgAlgorithm("AES128",
"2.16.840.1.101.3.4.2",
NistObjectIdentifiers.IdAes128Cbc,
NistObjectIdentifiers.IdAes128Cfb,
NistObjectIdentifiers.IdAes128Ecb,
NistObjectIdentifiers.IdAes128Ofb,
NistObjectIdentifiers.IdAes128Wrap);
AddKgAlgorithm("AES192",
"2.16.840.1.101.3.4.22",
NistObjectIdentifiers.IdAes192Cbc,
NistObjectIdentifiers.IdAes192Cfb,
NistObjectIdentifiers.IdAes192Ecb,
NistObjectIdentifiers.IdAes192Ofb,
NistObjectIdentifiers.IdAes192Wrap);
AddKgAlgorithm("AES256",
"2.16.840.1.101.3.4.42",
NistObjectIdentifiers.IdAes256Cbc,
NistObjectIdentifiers.IdAes256Cfb,
NistObjectIdentifiers.IdAes256Ecb,
NistObjectIdentifiers.IdAes256Ofb,
NistObjectIdentifiers.IdAes256Wrap);
AddKgAlgorithm("BLOWFISH");
AddKgAlgorithm("CAMELLIA",
"CAMELLIAWRAP");
AddKgAlgorithm("CAMELLIA128",
NttObjectIdentifiers.IdCamellia128Cbc,
NttObjectIdentifiers.IdCamellia128Wrap);
AddKgAlgorithm("CAMELLIA192",
NttObjectIdentifiers.IdCamellia192Cbc,
NttObjectIdentifiers.IdCamellia192Wrap);
AddKgAlgorithm("CAMELLIA256",
NttObjectIdentifiers.IdCamellia256Cbc,
NttObjectIdentifiers.IdCamellia256Wrap);
AddKgAlgorithm("CAST5",
"1.2.840.113533.7.66.10");
AddKgAlgorithm("CAST6");
AddKgAlgorithm("DES",
OiwObjectIdentifiers.DesCbc);
AddKgAlgorithm("DESEDE",
"DESEDEWRAP",
PkcsObjectIdentifiers.IdAlgCms3DesWrap);
AddKgAlgorithm("DESEDE3",
PkcsObjectIdentifiers.DesEde3Cbc);
AddKgAlgorithm("GOST28147",
"GOST",
"GOST-28147",
CryptoProObjectIdentifiers.GostR28147Cbc);
AddKgAlgorithm("HC128");
AddKgAlgorithm("HC256");
AddKgAlgorithm("IDEA",
"1.3.6.1.4.1.188.7.1.1.2");
AddKgAlgorithm("NOEKEON");
AddKgAlgorithm("RC2",
PkcsObjectIdentifiers.RC2Cbc,
PkcsObjectIdentifiers.IdAlgCmsRC2Wrap);
AddKgAlgorithm("RC4",
"ARC4",
"1.2.840.113549.3.4");
AddKgAlgorithm("RC5",
"RC5-32");
AddKgAlgorithm("RC5-64");
AddKgAlgorithm("RC6");
AddKgAlgorithm("RIJNDAEL");
AddKgAlgorithm("SALSA20");
AddKgAlgorithm("SEED",
KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap,
KisaObjectIdentifiers.IdSeedCbc);
AddKgAlgorithm("SERPENT");
AddKgAlgorithm("SKIPJACK");
AddKgAlgorithm("TEA");
AddKgAlgorithm("TWOFISH");
AddKgAlgorithm("VMPC");
AddKgAlgorithm("VMPC-KSA3");
AddKgAlgorithm("XTEA");
//
// HMac key generators
//
AddHMacKeyGenerator("MD2");
AddHMacKeyGenerator("MD4");
AddHMacKeyGenerator("MD5",
IanaObjectIdentifiers.HmacMD5);
AddHMacKeyGenerator("SHA1",
PkcsObjectIdentifiers.IdHmacWithSha1,
IanaObjectIdentifiers.HmacSha1);
AddHMacKeyGenerator("SHA224",
PkcsObjectIdentifiers.IdHmacWithSha224);
AddHMacKeyGenerator("SHA256",
PkcsObjectIdentifiers.IdHmacWithSha256);
AddHMacKeyGenerator("SHA384",
PkcsObjectIdentifiers.IdHmacWithSha384);
AddHMacKeyGenerator("SHA512",
PkcsObjectIdentifiers.IdHmacWithSha512);
AddHMacKeyGenerator("RIPEMD128");
AddHMacKeyGenerator("RIPEMD160",
IanaObjectIdentifiers.HmacRipeMD160);
AddHMacKeyGenerator("TIGER",
IanaObjectIdentifiers.HmacTiger);
//
// key pair generators.
//
AddKpgAlgorithm("DH",
"DIFFIEHELLMAN");
AddKpgAlgorithm("DSA");
AddKpgAlgorithm("EC");
AddKpgAlgorithm("ECDH",
"ECIES");
AddKpgAlgorithm("ECDHC");
AddKpgAlgorithm("ECDSA");
AddKpgAlgorithm("ECGOST3410",
"ECGOST-3410",
"GOST-3410-2001");
AddKpgAlgorithm("ELGAMAL");
AddKpgAlgorithm("GOST3410",
"GOST-3410",
"GOST-3410-94");
AddKpgAlgorithm("RSA",
"1.2.840.113549.1.1.1");
}
private static void AddKgAlgorithm(
string canonicalName,
params object[] aliases)
{
kgAlgorithms[canonicalName] = canonicalName;
foreach (object alias in aliases)
{
kgAlgorithms[alias.ToString()] = canonicalName;
}
}
private static void AddKpgAlgorithm(
string canonicalName,
params object[] aliases)
{
kpgAlgorithms[canonicalName] = canonicalName;
foreach (object alias in aliases)
{
kpgAlgorithms[alias.ToString()] = canonicalName;
}
}
private static void AddHMacKeyGenerator(
string algorithm,
params object[] aliases)
{
string mainName = "HMAC" + algorithm;
kgAlgorithms[mainName] = mainName;
kgAlgorithms["HMAC-" + algorithm] = mainName;
kgAlgorithms["HMAC/" + algorithm] = mainName;
foreach (object alias in aliases)
{
kgAlgorithms[alias.ToString()] = mainName;
}
}
// TODO Consider making this public
internal static string GetCanonicalKeyGeneratorAlgorithm(
string algorithm)
{
return (string) kgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
}
// TODO Consider making this public
internal static string GetCanonicalKeyPairGeneratorAlgorithm(
string algorithm)
{
return (string) kpgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
}
public static CipherKeyGenerator GetKeyGenerator(
DerObjectIdentifier oid)
{
return GetKeyGenerator(oid.Id);
}
public static CipherKeyGenerator GetKeyGenerator(
string algorithm)
{
string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm);
if (canonicalName == null)
throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised.");
switch (canonicalName)
{
case "DES":
return new DesKeyGenerator(64);
case "DESEDE":
return new DesEdeKeyGenerator(128);
case "DESEDE3":
return new DesEdeKeyGenerator(192);
case "AES":
return new CipherKeyGenerator(192);
case "AES128":
return new CipherKeyGenerator(128);
case "AES192":
return new CipherKeyGenerator(192);
case "AES256":
return new CipherKeyGenerator(256);
case "BLOWFISH":
return new CipherKeyGenerator(448);
case "CAMELLIA":
return new CipherKeyGenerator(256);
case "CAMELLIA128":
return new CipherKeyGenerator(128);
case "CAMELLIA192":
return new CipherKeyGenerator(192);
case "CAMELLIA256":
return new CipherKeyGenerator(256);
case "CAST5":
return new CipherKeyGenerator(128);
case "CAST6":
return new CipherKeyGenerator(256);
case "GOST28147":
return new CipherKeyGenerator(256);
case "HC128":
return new CipherKeyGenerator(128);
case "HC256":
return new CipherKeyGenerator(256);
case "HMACMD2":
case "HMACMD4":
case "HMACMD5":
return new CipherKeyGenerator(128);
case "HMACSHA1":
return new CipherKeyGenerator(160);
case "HMACSHA224":
return new CipherKeyGenerator(224);
case "HMACSHA256":
return new CipherKeyGenerator(256);
case "HMACSHA384":
return new CipherKeyGenerator(384);
case "HMACSHA512":
return new CipherKeyGenerator(512);
case "HMACRIPEMD128":
return new CipherKeyGenerator(128);
case "HMACRIPEMD160":
return new CipherKeyGenerator(160);
case "HMACTIGER":
return new CipherKeyGenerator(192);
case "IDEA":
return new CipherKeyGenerator(128);
case "NOEKEON":
return new CipherKeyGenerator(128);
case "RC2":
case "RC4":
case "RC5":
return new CipherKeyGenerator(128);
case "RC5-64":
case "RC6":
return new CipherKeyGenerator(256);
case "RIJNDAEL":
return new CipherKeyGenerator(192);
case "SALSA20":
return new CipherKeyGenerator(128);
case "SEED":
return new CipherKeyGenerator(128);
case "SERPENT":
return new CipherKeyGenerator(192);
case "SKIPJACK":
return new CipherKeyGenerator(80);
case "TEA":
case "XTEA":
return new CipherKeyGenerator(128);
case "TWOFISH":
return new CipherKeyGenerator(256);
case "VMPC":
case "VMPC-KSA3":
return new CipherKeyGenerator(128);
}
throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised.");
}
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
DerObjectIdentifier oid)
{
return GetKeyPairGenerator(oid.Id);
}
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
string algorithm)
{
string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm);
if (canonicalName == null)
throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised.");
switch (canonicalName)
{
case "DH":
return new DHKeyPairGenerator();
case "DSA":
return new DsaKeyPairGenerator();
case "EC":
case "ECDH":
case "ECDHC":
case "ECDSA":
case "ECGOST3410":
return new ECKeyPairGenerator(canonicalName);
case "ELGAMAL":
return new ElGamalKeyPairGenerator();
case "GOST3410":
return new Gost3410KeyPairGenerator();
case "RSA":
return new RsaKeyPairGenerator();
default:
break;
}
throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised.");
}
}
}

View File

@ -1,181 +1,210 @@
using System;
using System.Collections;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Security
{
public sealed class PrivateKeyFactory
{
private PrivateKeyFactory()
{
}
public static AsymmetricKeyParameter CreateKey(
byte[] privateKeyInfoData)
{
return CreateKey(
PrivateKeyInfo.GetInstance(
Asn1Object.FromByteArray(privateKeyInfoData)));
}
public static AsymmetricKeyParameter CreateKey(
Stream inStr)
{
return CreateKey(
PrivateKeyInfo.GetInstance(
Asn1Object.FromStream(inStr)));
}
public static AsymmetricKeyParameter CreateKey(
PrivateKeyInfo keyInfo)
{
AlgorithmIdentifier algID = keyInfo.AlgorithmID;
DerObjectIdentifier algOid = algID.ObjectID;
if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption))
{
RsaPrivateKeyStructure keyStructure = new RsaPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
return new RsaPrivateCrtKeyParameters(
keyStructure.Modulus,
keyStructure.PublicExponent,
keyStructure.PrivateExponent,
keyStructure.Prime1,
keyStructure.Prime2,
keyStructure.Exponent1,
keyStructure.Exponent2,
keyStructure.Coefficient);
}
else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
{
DHParameter para = new DHParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derX = (DerInteger)keyInfo.PrivateKey;
return new DHPrivateKeyParameters(
derX.Value,
new DHParameters(para.P, para.G));
}
else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
{
ElGamalParameter para = new ElGamalParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derX = (DerInteger)keyInfo.PrivateKey;
return new ElGamalPrivateKeyParameters(
derX.Value,
new ElGamalParameters(para.P, para.G));
}
else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
{
DerInteger derX = (DerInteger) keyInfo.PrivateKey;
Asn1Encodable ae = algID.Parameters;
DsaParameters parameters = null;
if (ae != null)
{
DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
parameters = new DsaParameters(para.P, para.Q, para.G);
}
return new DsaPrivateKeyParameters(derX.Value, parameters);
}
else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
{
X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object());
X9ECParameters ecP;
if (para.IsNamedCurve)
{
// TODO ECGost3410NamedCurves support (returns ECDomainParameters though)
DerObjectIdentifier oid = (DerObjectIdentifier) para.Parameters;
ecP = X962NamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = SecNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = NistNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = TeleTrusTNamedCurves.GetByOid(oid);
}
}
}
}
else
{
ecP = new X9ECParameters((Asn1Sequence) para.Parameters);
}
ECDomainParameters dParams = new ECDomainParameters(
ecP.Curve,
ecP.G,
ecP.N,
ecP.H,
ecP.GetSeed());
ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
return new ECPrivateKeyParameters(ec.GetKey(), dParams);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
{
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
if (ecP == null)
return null;
return new ECPrivateKeyParameters(ec.GetKey(), gostParams.PublicKeyParamSet);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
{
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerOctetString derX = (DerOctetString) keyInfo.PrivateKey;
byte[] keyEnc = derX.GetOctets();
byte[] keyBytes = new byte[keyEnc.Length];
for (int i = 0; i != keyEnc.Length; i++)
{
keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian
}
BigInteger x = new BigInteger(1, keyBytes);
return new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet);
}
else
{
throw new SecurityUtilityException("algorithm identifier in key not recognised");
}
}
}
}
using System;
using System.Collections;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
namespace Org.BouncyCastle.Security
{
public sealed class PrivateKeyFactory
{
private PrivateKeyFactory()
{
}
public static AsymmetricKeyParameter CreateKey(
byte[] privateKeyInfoData)
{
return CreateKey(
PrivateKeyInfo.GetInstance(
Asn1Object.FromByteArray(privateKeyInfoData)));
}
public static AsymmetricKeyParameter CreateKey(
Stream inStr)
{
return CreateKey(
PrivateKeyInfo.GetInstance(
Asn1Object.FromStream(inStr)));
}
public static AsymmetricKeyParameter CreateKey(
PrivateKeyInfo keyInfo)
{
AlgorithmIdentifier algID = keyInfo.AlgorithmID;
DerObjectIdentifier algOid = algID.ObjectID;
if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption))
{
RsaPrivateKeyStructure keyStructure = new RsaPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
return new RsaPrivateCrtKeyParameters(
keyStructure.Modulus,
keyStructure.PublicExponent,
keyStructure.PrivateExponent,
keyStructure.Prime1,
keyStructure.Prime2,
keyStructure.Exponent1,
keyStructure.Exponent2,
keyStructure.Coefficient);
}
else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
{
DHParameter para = new DHParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derX = (DerInteger)keyInfo.PrivateKey;
return new DHPrivateKeyParameters(
derX.Value,
new DHParameters(para.P, para.G));
}
else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
{
ElGamalParameter para = new ElGamalParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derX = (DerInteger)keyInfo.PrivateKey;
return new ElGamalPrivateKeyParameters(
derX.Value,
new ElGamalParameters(para.P, para.G));
}
else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
{
DerInteger derX = (DerInteger) keyInfo.PrivateKey;
Asn1Encodable ae = algID.Parameters;
DsaParameters parameters = null;
if (ae != null)
{
DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
parameters = new DsaParameters(para.P, para.Q, para.G);
}
return new DsaPrivateKeyParameters(derX.Value, parameters);
}
else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
{
X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object());
X9ECParameters ecP;
if (para.IsNamedCurve)
{
// TODO ECGost3410NamedCurves support (returns ECDomainParameters though)
DerObjectIdentifier oid = (DerObjectIdentifier) para.Parameters;
ecP = X962NamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = SecNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = NistNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = TeleTrusTNamedCurves.GetByOid(oid);
}
}
}
}
else
{
ecP = new X9ECParameters((Asn1Sequence) para.Parameters);
}
ECDomainParameters dParams = new ECDomainParameters(
ecP.Curve,
ecP.G,
ecP.N,
ecP.H,
ecP.GetSeed());
ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
return new ECPrivateKeyParameters(ec.GetKey(), dParams);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
{
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
if (ecP == null)
return null;
return new ECPrivateKeyParameters(ec.GetKey(), gostParams.PublicKeyParamSet);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
{
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerOctetString derX = (DerOctetString) keyInfo.PrivateKey;
byte[] keyEnc = derX.GetOctets();
byte[] keyBytes = new byte[keyEnc.Length];
for (int i = 0; i != keyEnc.Length; i++)
{
keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian
}
BigInteger x = new BigInteger(1, keyBytes);
return new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet);
}
else
{
throw new SecurityUtilityException("algorithm identifier in key not recognised");
}
}
public static AsymmetricKeyParameter DecryptKey(
char[] passPhrase,
EncryptedPrivateKeyInfo encInfo)
{
return CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(passPhrase, encInfo));
}
public static AsymmetricKeyParameter DecryptKey(
char[] passPhrase,
byte[] encryptedPrivateKeyInfoData)
{
return DecryptKey(passPhrase, Asn1Object.FromByteArray(encryptedPrivateKeyInfoData));
}
public static AsymmetricKeyParameter DecryptKey(
char[] passPhrase,
Stream encryptedPrivateKeyInfoStream)
{
return DecryptKey(passPhrase, Asn1Object.FromStream(encryptedPrivateKeyInfoStream));
}
private static AsymmetricKeyParameter DecryptKey(
char[] passPhrase,
Asn1Object asn1Object)
{
return DecryptKey(passPhrase, EncryptedPrivateKeyInfo.GetInstance(asn1Object));
}
}
}

View File

@ -1,94 +1,94 @@
using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.X509
{
class PemParser
{
private readonly string _header1;
private readonly string _header2;
private readonly string _footer1;
private readonly string _footer2;
internal PemParser(
string type)
{
_header1 = "-----BEGIN " + type + "-----";
_header2 = "-----BEGIN X509 " + type + "-----";
_footer1 = "-----END " + type + "-----";
_footer2 = "-----END X509 " + type + "-----";
}
private string ReadLine(
Stream inStream)
{
int c;
StringBuilder l = new StringBuilder();
do
{
while (((c = inStream.ReadByte()) != '\r') && c != '\n' && (c >= 0))
{
if (c == '\r')
{
continue;
}
l.Append((char)c);
}
}
while (c >= 0 && l.Length == 0);
if (c < 0)
{
return null;
}
return l.ToString();
}
internal Asn1Sequence ReadPemObject(
Stream inStream)
{
string line;
StringBuilder pemBuf = new StringBuilder();
while ((line = ReadLine(inStream)) != null)
{
if (line.Equals(_header1) || line.Equals(_header2))
{
break;
}
}
while ((line = ReadLine(inStream)) != null)
{
if (line.Equals(_footer1) || line.Equals(_footer2))
{
break;
}
pemBuf.Append(line);
}
if (pemBuf.Length != 0)
{
Asn1Object o = Asn1Object.FromByteArray(Base64.Decode(pemBuf.ToString()));
if (!(o is Asn1Sequence))
{
throw new IOException("malformed PEM data encountered");
}
return (Asn1Sequence) o;
}
return null;
}
}
}
using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.X509
{
class PemParser
{
private readonly string _header1;
private readonly string _header2;
private readonly string _footer1;
private readonly string _footer2;
internal PemParser(
string type)
{
_header1 = "-----BEGIN " + type + "-----";
_header2 = "-----BEGIN X509 " + type + "-----";
_footer1 = "-----END " + type + "-----";
_footer2 = "-----END X509 " + type + "-----";
}
private string ReadLine(
Stream inStream)
{
int c;
StringBuilder l = new StringBuilder();
do
{
while (((c = inStream.ReadByte()) != '\r') && c != '\n' && (c >= 0))
{
if (c == '\r')
{
continue;
}
l.Append((char)c);
}
}
while (c >= 0 && l.Length == 0);
if (c < 0)
{
return null;
}
return l.ToString();
}
internal Asn1Sequence ReadPemObject(
Stream inStream)
{
string line;
StringBuilder pemBuf = new StringBuilder();
while ((line = ReadLine(inStream)) != null)
{
if (line.StartsWith(_header1) || line.StartsWith(_header2))
{
break;
}
}
while ((line = ReadLine(inStream)) != null)
{
if (line.StartsWith(_footer1) || line.StartsWith(_footer2))
{
break;
}
pemBuf.Append(line);
}
if (pemBuf.Length != 0)
{
Asn1Object o = Asn1Object.FromByteArray(Base64.Decode(pemBuf.ToString()));
if (!(o is Asn1Sequence))
{
throw new IOException("malformed PEM data encountered");
}
return (Asn1Sequence) o;
}
return null;
}
}
}

View File

@ -1,337 +1,337 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.Utilities.Date;
using Org.BouncyCastle.X509.Extension;
namespace Org.BouncyCastle.X509.Store
{
public class X509CertStoreSelector
: IX509Selector
{
// TODO Missing criteria?
private byte[] authorityKeyIdentifier;
private int basicConstraints = -1;
private X509Certificate certificate;
private DateTimeObject certificateValid;
private ISet extendedKeyUsage;
private X509Name issuer;
private bool[] keyUsage;
private ISet policy;
private DateTimeObject privateKeyValid;
private BigInteger serialNumber;
private X509Name subject;
private byte[] subjectKeyIdentifier;
private SubjectPublicKeyInfo subjectPublicKey;
private DerObjectIdentifier subjectPublicKeyAlgID;
public X509CertStoreSelector()
{
}
public X509CertStoreSelector(
X509CertStoreSelector o)
{
this.authorityKeyIdentifier = o.AuthorityKeyIdentifier;
this.basicConstraints = o.BasicConstraints;
this.certificate = o.Certificate;
this.certificateValid = o.CertificateValid;
this.extendedKeyUsage = o.ExtendedKeyUsage;
this.issuer = o.Issuer;
this.keyUsage = o.KeyUsage;
this.policy = o.Policy;
this.privateKeyValid = o.PrivateKeyValid;
this.serialNumber = o.SerialNumber;
this.subject = o.Subject;
this.subjectKeyIdentifier = o.SubjectKeyIdentifier;
this.subjectPublicKey = o.SubjectPublicKey;
this.subjectPublicKeyAlgID = o.SubjectPublicKeyAlgID;
}
public virtual object Clone()
{
return new X509CertStoreSelector(this);
}
public byte[] AuthorityKeyIdentifier
{
get { return Arrays.Clone(authorityKeyIdentifier); }
set { authorityKeyIdentifier = Arrays.Clone(value); }
}
public int BasicConstraints
{
get { return basicConstraints; }
set
{
if (value < -2)
throw new ArgumentException("value can't be less than -2", "value");
basicConstraints = value;
}
}
public X509Certificate Certificate
{
get { return certificate; }
set { this.certificate = value; }
}
public DateTimeObject CertificateValid
{
get { return certificateValid; }
set { certificateValid = value; }
}
public ISet ExtendedKeyUsage
{
get { return CopySet(extendedKeyUsage); }
set { extendedKeyUsage = CopySet(value); }
}
public X509Name Issuer
{
get { return issuer; }
set { issuer = value; }
}
[Obsolete("Avoid working with X509Name objects in string form")]
public string IssuerAsString
{
get { return issuer != null ? issuer.ToString() : null; }
}
public bool[] KeyUsage
{
get { return CopyBoolArray(keyUsage); }
set { keyUsage = CopyBoolArray(value); }
}
/// <summary>
/// An <code>ISet</code> of <code>DerObjectIdentifier</code> objects.
/// </summary>
public ISet Policy
{
get { return CopySet(policy); }
set { policy = CopySet(value); }
}
public DateTimeObject PrivateKeyValid
{
get { return privateKeyValid; }
set { privateKeyValid = value; }
}
public BigInteger SerialNumber
{
get { return serialNumber; }
set { serialNumber = value; }
}
public X509Name Subject
{
get { return subject; }
set { subject = value; }
}
public string SubjectAsString
{
get { return subject != null ? subject.ToString() : null; }
}
public byte[] SubjectKeyIdentifier
{
get { return Arrays.Clone(subjectKeyIdentifier); }
set { subjectKeyIdentifier = Arrays.Clone(value); }
}
public SubjectPublicKeyInfo SubjectPublicKey
{
get { return subjectPublicKey; }
set { subjectPublicKey = value; }
}
public DerObjectIdentifier SubjectPublicKeyAlgID
{
get { return subjectPublicKeyAlgID; }
set { subjectPublicKeyAlgID = value; }
}
public virtual bool Match(
object obj)
{
X509Certificate c = obj as X509Certificate;
if (c == null)
return false;
if (!MatchExtension(authorityKeyIdentifier, c, X509Extensions.AuthorityKeyIdentifier))
return false;
if (basicConstraints != -1)
{
int bc = c.GetBasicConstraints();
if (basicConstraints == -2)
{
if (bc != -1)
return false;
}
else
{
if (bc < basicConstraints)
return false;
}
}
if (certificate != null && !certificate.Equals(c))
return false;
if (certificateValid != null && !c.IsValid(certificateValid.Value))
return false;
if (extendedKeyUsage != null)
{
IList eku = c.GetExtendedKeyUsage();
// Note: if no extended key usage set, all key purposes are implicitly allowed
if (eku != null)
{
foreach (DerObjectIdentifier oid in extendedKeyUsage)
{
if (!eku.Contains(oid.Id))
return false;
}
}
}
if (issuer != null && !issuer.Equivalent(c.IssuerDN))
return false;
if (keyUsage != null)
{
bool[] ku = c.GetKeyUsage();
// Note: if no key usage set, all key purposes are implicitly allowed
if (ku != null)
{
for (int i = 0; i < 9; ++i)
{
if (keyUsage[i] && !ku[i])
return false;
}
}
}
if (policy != null)
{
Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CertificatePolicies);
if (extVal == null)
return false;
Asn1Sequence certPolicies = Asn1Sequence.GetInstance(
X509ExtensionUtilities.FromExtensionValue(extVal));
if (policy.Count < 1 && certPolicies.Count < 1)
return false;
bool found = false;
foreach (PolicyInformation pi in certPolicies)
{
if (policy.Contains(pi.PolicyIdentifier))
{
found = true;
break;
}
}
if (!found)
return false;
}
if (privateKeyValid != null)
{
Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.PrivateKeyUsagePeriod);
if (extVal == null)
return false;
PrivateKeyUsagePeriod pkup = PrivateKeyUsagePeriod.GetInstance(
X509ExtensionUtilities.FromExtensionValue(extVal));
DateTime dt = privateKeyValid.Value;
DateTime notAfter = pkup.NotAfter.ToDateTime();
DateTime notBefore = pkup.NotBefore.ToDateTime();
if (dt.CompareTo(notAfter) > 0 || dt.CompareTo(notBefore) < 0)
return false;
}
if (serialNumber != null && !serialNumber.Equals(c.SerialNumber))
return false;
if (subject != null && !subject.Equivalent(c.SubjectDN))
return false;
if (!MatchExtension(subjectKeyIdentifier, c, X509Extensions.SubjectKeyIdentifier))
return false;
if (subjectPublicKey != null && !subjectPublicKey.Equals(GetSubjectPublicKey(c)))
return false;
if (subjectPublicKeyAlgID != null
&& !subjectPublicKeyAlgID.Equals(GetSubjectPublicKey(c).AlgorithmID))
return false;
return true;
}
internal static bool IssuersMatch(
X509Name a,
X509Name b)
{
return a == null ? b == null : a.Equivalent(b);
}
private static bool[] CopyBoolArray(
bool[] b)
{
return b == null ? null : (bool[]) b.Clone();
}
private static ISet CopySet(
ISet s)
{
return s == null ? null : new HashSet(s);
}
private static SubjectPublicKeyInfo GetSubjectPublicKey(
X509Certificate c)
{
return SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(c.GetPublicKey());
}
private static bool MatchExtension(
byte[] b,
X509Certificate c,
DerObjectIdentifier oid)
{
if (b == null)
return true;
Asn1OctetString extVal = c.GetExtensionValue(oid);
if (extVal == null)
return false;
return extVal != null && Arrays.AreEqual(b, extVal.GetEncoded());
}
}
}
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.Utilities.Date;
using Org.BouncyCastle.X509.Extension;
namespace Org.BouncyCastle.X509.Store
{
public class X509CertStoreSelector
: IX509Selector
{
// TODO Missing criteria?
private byte[] authorityKeyIdentifier;
private int basicConstraints = -1;
private X509Certificate certificate;
private DateTimeObject certificateValid;
private ISet extendedKeyUsage;
private X509Name issuer;
private bool[] keyUsage;
private ISet policy;
private DateTimeObject privateKeyValid;
private BigInteger serialNumber;
private X509Name subject;
private byte[] subjectKeyIdentifier;
private SubjectPublicKeyInfo subjectPublicKey;
private DerObjectIdentifier subjectPublicKeyAlgID;
public X509CertStoreSelector()
{
}
public X509CertStoreSelector(
X509CertStoreSelector o)
{
this.authorityKeyIdentifier = o.AuthorityKeyIdentifier;
this.basicConstraints = o.BasicConstraints;
this.certificate = o.Certificate;
this.certificateValid = o.CertificateValid;
this.extendedKeyUsage = o.ExtendedKeyUsage;
this.issuer = o.Issuer;
this.keyUsage = o.KeyUsage;
this.policy = o.Policy;
this.privateKeyValid = o.PrivateKeyValid;
this.serialNumber = o.SerialNumber;
this.subject = o.Subject;
this.subjectKeyIdentifier = o.SubjectKeyIdentifier;
this.subjectPublicKey = o.SubjectPublicKey;
this.subjectPublicKeyAlgID = o.SubjectPublicKeyAlgID;
}
public virtual object Clone()
{
return new X509CertStoreSelector(this);
}
public byte[] AuthorityKeyIdentifier
{
get { return Arrays.Clone(authorityKeyIdentifier); }
set { authorityKeyIdentifier = Arrays.Clone(value); }
}
public int BasicConstraints
{
get { return basicConstraints; }
set
{
if (value < -2)
throw new ArgumentException("value can't be less than -2", "value");
basicConstraints = value;
}
}
public X509Certificate Certificate
{
get { return certificate; }
set { this.certificate = value; }
}
public DateTimeObject CertificateValid
{
get { return certificateValid; }
set { certificateValid = value; }
}
public ISet ExtendedKeyUsage
{
get { return CopySet(extendedKeyUsage); }
set { extendedKeyUsage = CopySet(value); }
}
public X509Name Issuer
{
get { return issuer; }
set { issuer = value; }
}
[Obsolete("Avoid working with X509Name objects in string form")]
public string IssuerAsString
{
get { return issuer != null ? issuer.ToString() : null; }
}
public bool[] KeyUsage
{
get { return CopyBoolArray(keyUsage); }
set { keyUsage = CopyBoolArray(value); }
}
/// <summary>
/// An <code>ISet</code> of <code>DerObjectIdentifier</code> objects.
/// </summary>
public ISet Policy
{
get { return CopySet(policy); }
set { policy = CopySet(value); }
}
public DateTimeObject PrivateKeyValid
{
get { return privateKeyValid; }
set { privateKeyValid = value; }
}
public BigInteger SerialNumber
{
get { return serialNumber; }
set { serialNumber = value; }
}
public X509Name Subject
{
get { return subject; }
set { subject = value; }
}
public string SubjectAsString
{
get { return subject != null ? subject.ToString() : null; }
}
public byte[] SubjectKeyIdentifier
{
get { return Arrays.Clone(subjectKeyIdentifier); }
set { subjectKeyIdentifier = Arrays.Clone(value); }
}
public SubjectPublicKeyInfo SubjectPublicKey
{
get { return subjectPublicKey; }
set { subjectPublicKey = value; }
}
public DerObjectIdentifier SubjectPublicKeyAlgID
{
get { return subjectPublicKeyAlgID; }
set { subjectPublicKeyAlgID = value; }
}
public virtual bool Match(
object obj)
{
X509Certificate c = obj as X509Certificate;
if (c == null)
return false;
if (!MatchExtension(authorityKeyIdentifier, c, X509Extensions.AuthorityKeyIdentifier))
return false;
if (basicConstraints != -1)
{
int bc = c.GetBasicConstraints();
if (basicConstraints == -2)
{
if (bc != -1)
return false;
}
else
{
if (bc < basicConstraints)
return false;
}
}
if (certificate != null && !certificate.Equals(c))
return false;
if (certificateValid != null && !c.IsValid(certificateValid.Value))
return false;
if (extendedKeyUsage != null)
{
IList eku = c.GetExtendedKeyUsage();
// Note: if no extended key usage set, all key purposes are implicitly allowed
if (eku != null)
{
foreach (DerObjectIdentifier oid in extendedKeyUsage)
{
if (!eku.Contains(oid.Id))
return false;
}
}
}
if (issuer != null && !issuer.Equivalent(c.IssuerDN, true))
return false;
if (keyUsage != null)
{
bool[] ku = c.GetKeyUsage();
// Note: if no key usage set, all key purposes are implicitly allowed
if (ku != null)
{
for (int i = 0; i < 9; ++i)
{
if (keyUsage[i] && !ku[i])
return false;
}
}
}
if (policy != null)
{
Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CertificatePolicies);
if (extVal == null)
return false;
Asn1Sequence certPolicies = Asn1Sequence.GetInstance(
X509ExtensionUtilities.FromExtensionValue(extVal));
if (policy.Count < 1 && certPolicies.Count < 1)
return false;
bool found = false;
foreach (PolicyInformation pi in certPolicies)
{
if (policy.Contains(pi.PolicyIdentifier))
{
found = true;
break;
}
}
if (!found)
return false;
}
if (privateKeyValid != null)
{
Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.PrivateKeyUsagePeriod);
if (extVal == null)
return false;
PrivateKeyUsagePeriod pkup = PrivateKeyUsagePeriod.GetInstance(
X509ExtensionUtilities.FromExtensionValue(extVal));
DateTime dt = privateKeyValid.Value;
DateTime notAfter = pkup.NotAfter.ToDateTime();
DateTime notBefore = pkup.NotBefore.ToDateTime();
if (dt.CompareTo(notAfter) > 0 || dt.CompareTo(notBefore) < 0)
return false;
}
if (serialNumber != null && !serialNumber.Equals(c.SerialNumber))
return false;
if (subject != null && !subject.Equivalent(c.SubjectDN, true))
return false;
if (!MatchExtension(subjectKeyIdentifier, c, X509Extensions.SubjectKeyIdentifier))
return false;
if (subjectPublicKey != null && !subjectPublicKey.Equals(GetSubjectPublicKey(c)))
return false;
if (subjectPublicKeyAlgID != null
&& !subjectPublicKeyAlgID.Equals(GetSubjectPublicKey(c).AlgorithmID))
return false;
return true;
}
internal static bool IssuersMatch(
X509Name a,
X509Name b)
{
return a == null ? b == null : a.Equivalent(b, true);
}
private static bool[] CopyBoolArray(
bool[] b)
{
return b == null ? null : (bool[]) b.Clone();
}
private static ISet CopySet(
ISet s)
{
return s == null ? null : new HashSet(s);
}
private static SubjectPublicKeyInfo GetSubjectPublicKey(
X509Certificate c)
{
return SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(c.GetPublicKey());
}
private static bool MatchExtension(
byte[] b,
X509Certificate c,
DerObjectIdentifier oid)
{
if (b == null)
return true;
Asn1OctetString extVal = c.GetExtensionValue(oid);
if (extVal == null)
return false;
return Arrays.AreEqual(b, extVal.GetOctets());
}
}
}

View File

@ -1,283 +1,283 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Date;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
namespace Org.BouncyCastle.X509.Store
{
public class X509CrlStoreSelector
: IX509Selector
{
// TODO Missing criteria?
private X509Certificate certificateChecking;
private DateTimeObject dateAndTime;
private ICollection issuers;
private BigInteger maxCrlNumber;
private BigInteger minCrlNumber;
private IX509AttributeCertificate attrCertChecking;
private bool completeCrlEnabled;
private bool deltaCrlIndicatorEnabled;
private byte[] issuingDistributionPoint;
private bool issuingDistributionPointEnabled;
private BigInteger maxBaseCrlNumber;
public X509CrlStoreSelector()
{
}
public X509CrlStoreSelector(
X509CrlStoreSelector o)
{
this.certificateChecking = o.CertificateChecking;
this.dateAndTime = o.DateAndTime;
this.issuers = o.Issuers;
this.maxCrlNumber = o.MaxCrlNumber;
this.minCrlNumber = o.MinCrlNumber;
this.deltaCrlIndicatorEnabled = o.DeltaCrlIndicatorEnabled;
this.completeCrlEnabled = o.CompleteCrlEnabled;
this.maxBaseCrlNumber = o.MaxBaseCrlNumber;
this.attrCertChecking = o.AttrCertChecking;
this.issuingDistributionPointEnabled = o.IssuingDistributionPointEnabled;
this.issuingDistributionPoint = o.IssuingDistributionPoint;
}
public virtual object Clone()
{
return new X509CrlStoreSelector(this);
}
public X509Certificate CertificateChecking
{
get { return certificateChecking; }
set { certificateChecking = value; }
}
public DateTimeObject DateAndTime
{
get { return dateAndTime; }
set { dateAndTime = value; }
}
/// <summary>
/// An <code>ICollection</code> of <code>X509Name</code> objects
/// </summary>
public ICollection Issuers
{
get { return new ArrayList(issuers); }
set { issuers = new ArrayList(value); }
}
public BigInteger MaxCrlNumber
{
get { return maxCrlNumber; }
set { maxCrlNumber = value; }
}
public BigInteger MinCrlNumber
{
get { return minCrlNumber; }
set { minCrlNumber = value; }
}
/**
* The attribute certificate being checked. This is not a criterion.
* Rather, it is optional information that may help a {@link X509Store} find
* CRLs that would be relevant when checking revocation for the specified
* attribute certificate. If <code>null</code> is specified, then no such
* optional information is provided.
*
* @param attrCert the <code>IX509AttributeCertificate</code> being checked (or
* <code>null</code>)
* @see #getAttrCertificateChecking()
*/
public IX509AttributeCertificate AttrCertChecking
{
get { return attrCertChecking; }
set { this.attrCertChecking = value; }
}
/**
* If <code>true</code> only complete CRLs are returned. Defaults to
* <code>false</code>.
*
* @return <code>true</code> if only complete CRLs are returned.
*/
public bool CompleteCrlEnabled
{
get { return completeCrlEnabled; }
set { this.completeCrlEnabled = value; }
}
/**
* Returns if this selector must match CRLs with the delta CRL indicator
* extension set. Defaults to <code>false</code>.
*
* @return Returns <code>true</code> if only CRLs with the delta CRL
* indicator extension are selected.
*/
public bool DeltaCrlIndicatorEnabled
{
get { return deltaCrlIndicatorEnabled; }
set { this.deltaCrlIndicatorEnabled = value; }
}
/**
* The issuing distribution point.
* <p>
* The issuing distribution point extension is a CRL extension which
* identifies the scope and the distribution point of a CRL. The scope
* contains among others information about revocation reasons contained in
* the CRL. Delta CRLs and complete CRLs must have matching issuing
* distribution points.</p>
* <p>
* The byte array is cloned to protect against subsequent modifications.</p>
* <p>
* You must also enable or disable this criteria with
* {@link #setIssuingDistributionPointEnabled(bool)}.</p>
*
* @param issuingDistributionPoint The issuing distribution point to set.
* This is the DER encoded OCTET STRING extension value.
* @see #getIssuingDistributionPoint()
*/
public byte[] IssuingDistributionPoint
{
get { return Arrays.Clone(issuingDistributionPoint); }
set { this.issuingDistributionPoint = Arrays.Clone(value); }
}
/**
* Whether the issuing distribution point criteria should be applied.
* Defaults to <code>false</code>.
* <p>
* You may also set the issuing distribution point criteria if not a missing
* issuing distribution point should be assumed.</p>
*
* @return Returns if the issuing distribution point check is enabled.
*/
public bool IssuingDistributionPointEnabled
{
get { return issuingDistributionPointEnabled; }
set { this.issuingDistributionPointEnabled = value; }
}
/**
* The maximum base CRL number. Defaults to <code>null</code>.
*
* @return Returns the maximum base CRL number.
* @see #setMaxBaseCRLNumber(BigInteger)
*/
public BigInteger MaxBaseCrlNumber
{
get { return maxBaseCrlNumber; }
set { this.maxBaseCrlNumber = value; }
}
public virtual bool Match(
object obj)
{
X509Crl c = obj as X509Crl;
if (c == null)
return false;
if (dateAndTime != null)
{
DateTime dt = dateAndTime.Value;
DateTime tu = c.ThisUpdate;
DateTimeObject nu = c.NextUpdate;
if (dt.CompareTo(tu) < 0 || nu == null || dt.CompareTo(nu.Value) >= 0)
return false;
}
if (issuers != null)
{
X509Name i = c.IssuerDN;
bool found = false;
foreach (X509Name issuer in issuers)
{
if (issuer.Equivalent(i))
{
found = true;
break;
}
}
if (!found)
return false;
}
if (maxCrlNumber != null || minCrlNumber != null)
{
Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CrlNumber);
if (extVal == null)
return false;
BigInteger cn = CrlNumber.GetInstance(
X509ExtensionUtilities.FromExtensionValue(extVal)).PositiveValue;
if (maxCrlNumber != null && cn.CompareTo(maxCrlNumber) > 0)
return false;
if (minCrlNumber != null && cn.CompareTo(minCrlNumber) < 0)
return false;
}
DerInteger dci = null;
try
{
Asn1OctetString bytes = c.GetExtensionValue(X509Extensions.DeltaCrlIndicator);
if (bytes != null)
{
dci = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(bytes));
}
}
catch (Exception)
{
return false;
}
if (dci == null)
{
if (DeltaCrlIndicatorEnabled)
return false;
}
else
{
if (CompleteCrlEnabled)
return false;
if (maxBaseCrlNumber != null && dci.PositiveValue.CompareTo(maxBaseCrlNumber) > 0)
return false;
}
if (issuingDistributionPointEnabled)
{
Asn1OctetString idp = c.GetExtensionValue(X509Extensions.IssuingDistributionPoint);
if (issuingDistributionPoint == null)
{
if (idp != null)
return false;
}
else
{
if (!Arrays.AreEqual(idp.GetOctets(), issuingDistributionPoint))
return false;
}
}
return true;
}
}
}
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Date;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
namespace Org.BouncyCastle.X509.Store
{
public class X509CrlStoreSelector
: IX509Selector
{
// TODO Missing criteria?
private X509Certificate certificateChecking;
private DateTimeObject dateAndTime;
private ICollection issuers;
private BigInteger maxCrlNumber;
private BigInteger minCrlNumber;
private IX509AttributeCertificate attrCertChecking;
private bool completeCrlEnabled;
private bool deltaCrlIndicatorEnabled;
private byte[] issuingDistributionPoint;
private bool issuingDistributionPointEnabled;
private BigInteger maxBaseCrlNumber;
public X509CrlStoreSelector()
{
}
public X509CrlStoreSelector(
X509CrlStoreSelector o)
{
this.certificateChecking = o.CertificateChecking;
this.dateAndTime = o.DateAndTime;
this.issuers = o.Issuers;
this.maxCrlNumber = o.MaxCrlNumber;
this.minCrlNumber = o.MinCrlNumber;
this.deltaCrlIndicatorEnabled = o.DeltaCrlIndicatorEnabled;
this.completeCrlEnabled = o.CompleteCrlEnabled;
this.maxBaseCrlNumber = o.MaxBaseCrlNumber;
this.attrCertChecking = o.AttrCertChecking;
this.issuingDistributionPointEnabled = o.IssuingDistributionPointEnabled;
this.issuingDistributionPoint = o.IssuingDistributionPoint;
}
public virtual object Clone()
{
return new X509CrlStoreSelector(this);
}
public X509Certificate CertificateChecking
{
get { return certificateChecking; }
set { certificateChecking = value; }
}
public DateTimeObject DateAndTime
{
get { return dateAndTime; }
set { dateAndTime = value; }
}
/// <summary>
/// An <code>ICollection</code> of <code>X509Name</code> objects
/// </summary>
public ICollection Issuers
{
get { return new ArrayList(issuers); }
set { issuers = new ArrayList(value); }
}
public BigInteger MaxCrlNumber
{
get { return maxCrlNumber; }
set { maxCrlNumber = value; }
}
public BigInteger MinCrlNumber
{
get { return minCrlNumber; }
set { minCrlNumber = value; }
}
/**
* The attribute certificate being checked. This is not a criterion.
* Rather, it is optional information that may help a {@link X509Store} find
* CRLs that would be relevant when checking revocation for the specified
* attribute certificate. If <code>null</code> is specified, then no such
* optional information is provided.
*
* @param attrCert the <code>IX509AttributeCertificate</code> being checked (or
* <code>null</code>)
* @see #getAttrCertificateChecking()
*/
public IX509AttributeCertificate AttrCertChecking
{
get { return attrCertChecking; }
set { this.attrCertChecking = value; }
}
/**
* If <code>true</code> only complete CRLs are returned. Defaults to
* <code>false</code>.
*
* @return <code>true</code> if only complete CRLs are returned.
*/
public bool CompleteCrlEnabled
{
get { return completeCrlEnabled; }
set { this.completeCrlEnabled = value; }
}
/**
* Returns if this selector must match CRLs with the delta CRL indicator
* extension set. Defaults to <code>false</code>.
*
* @return Returns <code>true</code> if only CRLs with the delta CRL
* indicator extension are selected.
*/
public bool DeltaCrlIndicatorEnabled
{
get { return deltaCrlIndicatorEnabled; }
set { this.deltaCrlIndicatorEnabled = value; }
}
/**
* The issuing distribution point.
* <p>
* The issuing distribution point extension is a CRL extension which
* identifies the scope and the distribution point of a CRL. The scope
* contains among others information about revocation reasons contained in
* the CRL. Delta CRLs and complete CRLs must have matching issuing
* distribution points.</p>
* <p>
* The byte array is cloned to protect against subsequent modifications.</p>
* <p>
* You must also enable or disable this criteria with
* {@link #setIssuingDistributionPointEnabled(bool)}.</p>
*
* @param issuingDistributionPoint The issuing distribution point to set.
* This is the DER encoded OCTET STRING extension value.
* @see #getIssuingDistributionPoint()
*/
public byte[] IssuingDistributionPoint
{
get { return Arrays.Clone(issuingDistributionPoint); }
set { this.issuingDistributionPoint = Arrays.Clone(value); }
}
/**
* Whether the issuing distribution point criteria should be applied.
* Defaults to <code>false</code>.
* <p>
* You may also set the issuing distribution point criteria if not a missing
* issuing distribution point should be assumed.</p>
*
* @return Returns if the issuing distribution point check is enabled.
*/
public bool IssuingDistributionPointEnabled
{
get { return issuingDistributionPointEnabled; }
set { this.issuingDistributionPointEnabled = value; }
}
/**
* The maximum base CRL number. Defaults to <code>null</code>.
*
* @return Returns the maximum base CRL number.
* @see #setMaxBaseCRLNumber(BigInteger)
*/
public BigInteger MaxBaseCrlNumber
{
get { return maxBaseCrlNumber; }
set { this.maxBaseCrlNumber = value; }
}
public virtual bool Match(
object obj)
{
X509Crl c = obj as X509Crl;
if (c == null)
return false;
if (dateAndTime != null)
{
DateTime dt = dateAndTime.Value;
DateTime tu = c.ThisUpdate;
DateTimeObject nu = c.NextUpdate;
if (dt.CompareTo(tu) < 0 || nu == null || dt.CompareTo(nu.Value) >= 0)
return false;
}
if (issuers != null)
{
X509Name i = c.IssuerDN;
bool found = false;
foreach (X509Name issuer in issuers)
{
if (issuer.Equivalent(i, true))
{
found = true;
break;
}
}
if (!found)
return false;
}
if (maxCrlNumber != null || minCrlNumber != null)
{
Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CrlNumber);
if (extVal == null)
return false;
BigInteger cn = CrlNumber.GetInstance(
X509ExtensionUtilities.FromExtensionValue(extVal)).PositiveValue;
if (maxCrlNumber != null && cn.CompareTo(maxCrlNumber) > 0)
return false;
if (minCrlNumber != null && cn.CompareTo(minCrlNumber) < 0)
return false;
}
DerInteger dci = null;
try
{
Asn1OctetString bytes = c.GetExtensionValue(X509Extensions.DeltaCrlIndicator);
if (bytes != null)
{
dci = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(bytes));
}
}
catch (Exception)
{
return false;
}
if (dci == null)
{
if (DeltaCrlIndicatorEnabled)
return false;
}
else
{
if (CompleteCrlEnabled)
return false;
if (maxBaseCrlNumber != null && dci.PositiveValue.CompareTo(maxBaseCrlNumber) > 0)
return false;
}
if (issuingDistributionPointEnabled)
{
Asn1OctetString idp = c.GetExtensionValue(X509Extensions.IssuingDistributionPoint);
if (issuingDistributionPoint == null)
{
if (idp != null)
return false;
}
else
{
if (!Arrays.AreEqual(idp.GetOctets(), issuingDistributionPoint))
return false;
}
}
return true;
}
}
}

View File

@ -1,44 +1,61 @@
using System;
using System.Globalization;
namespace Org.BouncyCastle.X509.Store
{
public sealed class X509StoreFactory
{
private X509StoreFactory()
{
}
public static IX509Store Create(
string type,
IX509StoreParameters parameters)
{
if (type == null)
throw new ArgumentNullException("type");
string[] parts = type.ToUpper(CultureInfo.InvariantCulture).Split('/');
if (parts.Length < 2)
throw new ArgumentException("type");
switch (parts[0])
{
case "ATTRIBUTECERTIFICATE":
case "CERTIFICATE":
case "CERTIFICATEPAIR":
case "CRL":
{
if (parts[1] == "COLLECTION")
{
X509CollectionStoreParameters p = (X509CollectionStoreParameters) parameters;
return new X509CollectionStore(p.GetCollection());
}
break;
}
}
throw new NoSuchStoreException("X.509 store type '" + type + "' not available.");
}
}
}
using System;
using System.Collections;
using System.Globalization;
namespace Org.BouncyCastle.X509.Store
{
public sealed class X509StoreFactory
{
private X509StoreFactory()
{
}
public static IX509Store Create(
string type,
IX509StoreParameters parameters)
{
if (type == null)
throw new ArgumentNullException("type");
string[] parts = type.ToUpper(CultureInfo.InvariantCulture).Split('/');
if (parts.Length < 2)
throw new ArgumentException("type");
if (parts[1] != "COLLECTION")
throw new NoSuchStoreException("X.509 store type '" + type + "' not available.");
X509CollectionStoreParameters p = (X509CollectionStoreParameters) parameters;
ICollection coll = p.GetCollection();
switch (parts[0])
{
case "ATTRIBUTECERTIFICATE":
checkCorrectType(coll, typeof(IX509AttributeCertificate));
break;
case "CERTIFICATE":
checkCorrectType(coll, typeof(X509Certificate));
break;
case "CERTIFICATEPAIR":
checkCorrectType(coll, typeof(X509CertificatePair));
break;
case "CRL":
checkCorrectType(coll, typeof(X509Crl));
break;
default:
throw new NoSuchStoreException("X.509 store type '" + type + "' not available.");
}
return new X509CollectionStore(coll);
}
private static void checkCorrectType(ICollection coll, Type t)
{
foreach (object o in coll)
{
if (!t.IsInstanceOfType(o))
throw new InvalidCastException("Can't cast object to type: " + t.FullName);
}
}
}
}