diff options
Diffstat (limited to 'crypto/src/asn1/pkcs')
27 files changed, 2555 insertions, 0 deletions
diff --git a/crypto/src/asn1/pkcs/Attribute.cs b/crypto/src/asn1/pkcs/Attribute.cs new file mode 100644 index 000000000..ceec115bd --- /dev/null +++ b/crypto/src/asn1/pkcs/Attribute.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class AttributePkcs + : Asn1Encodable + { + private readonly DerObjectIdentifier attrType; + private readonly Asn1Set attrValues; + + /** + * return an Attribute object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static AttributePkcs GetInstance( + object obj) + { + AttributePkcs attr = obj as AttributePkcs; + if (obj == null || attr != null) + { + return attr; + } + + Asn1Sequence seq = obj as Asn1Sequence; + if (seq != null) + { + return new AttributePkcs(seq); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + private AttributePkcs( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + attrType = DerObjectIdentifier.GetInstance(seq[0]); + attrValues = Asn1Set.GetInstance(seq[1]); + } + + public AttributePkcs( + DerObjectIdentifier attrType, + Asn1Set attrValues) + { + this.attrType = attrType; + this.attrValues = attrValues; + } + + public DerObjectIdentifier AttrType + { + get { return attrType; } + } + + public Asn1Set AttrValues + { + get { return attrValues; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * <pre> + * Attr ::= Sequence { + * attrType OBJECT IDENTIFIER, + * attrValues Set OF AttributeValue + * } + * </pre> + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(attrType, attrValues); + } + } +} diff --git a/crypto/src/asn1/pkcs/AuthenticatedSafe.cs b/crypto/src/asn1/pkcs/AuthenticatedSafe.cs new file mode 100644 index 000000000..f3dabb89c --- /dev/null +++ b/crypto/src/asn1/pkcs/AuthenticatedSafe.cs @@ -0,0 +1,37 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class AuthenticatedSafe + : Asn1Encodable + { + private readonly ContentInfo[] info; + + public AuthenticatedSafe( + Asn1Sequence seq) + { + info = new ContentInfo[seq.Count]; + + for (int i = 0; i != info.Length; i++) + { + info[i] = ContentInfo.GetInstance(seq[i]); + } + } + + public AuthenticatedSafe( + ContentInfo[] info) + { + this.info = (ContentInfo[]) info.Clone(); + } + + public ContentInfo[] GetContentInfo() + { + return (ContentInfo[]) info.Clone(); + } + + public override Asn1Object ToAsn1Object() + { + return new BerSequence(info); + } + } +} diff --git a/crypto/src/asn1/pkcs/CertBag.cs b/crypto/src/asn1/pkcs/CertBag.cs new file mode 100644 index 000000000..b6f4c8a30 --- /dev/null +++ b/crypto/src/asn1/pkcs/CertBag.cs @@ -0,0 +1,46 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class CertBag + : Asn1Encodable + { +// private readonly Asn1Sequence seq; + private readonly DerObjectIdentifier certID; + private readonly Asn1Object certValue; + + public CertBag( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + +// this.seq = seq; + this.certID = DerObjectIdentifier.GetInstance(seq[0]); + this.certValue = DerTaggedObject.GetInstance(seq[1]).GetObject(); + } + + public CertBag( + DerObjectIdentifier certID, + Asn1Object certValue) + { + this.certID = certID; + this.certValue = certValue; + } + + public DerObjectIdentifier CertID + { + get { return certID; } + } + + public Asn1Object CertValue + { + get { return certValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(certID, new DerTaggedObject(0, certValue)); + } + } +} diff --git a/crypto/src/asn1/pkcs/CertificationRequest.cs b/crypto/src/asn1/pkcs/CertificationRequest.cs new file mode 100644 index 000000000..32b1612d2 --- /dev/null +++ b/crypto/src/asn1/pkcs/CertificationRequest.cs @@ -0,0 +1,81 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * Pkcs10 Certfication request object. + * <pre> + * CertificationRequest ::= Sequence { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + * signature BIT STRING + * } + * </pre> + */ + public class CertificationRequest + : Asn1Encodable + { + protected CertificationRequestInfo reqInfo; + protected AlgorithmIdentifier sigAlgId; + protected DerBitString sigBits; + + public static CertificationRequest GetInstance( + object obj) + { + if (obj is CertificationRequest) + return (CertificationRequest)obj; + + if (obj != null) + return new CertificationRequest((Asn1Sequence)obj); + + return null; + } + + protected CertificationRequest() + { + } + + public CertificationRequest( + CertificationRequestInfo requestInfo, + AlgorithmIdentifier algorithm, + DerBitString signature) + { + this.reqInfo = requestInfo; + this.sigAlgId = algorithm; + this.sigBits = signature; + } + + public CertificationRequest( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + reqInfo = CertificationRequestInfo.GetInstance(seq[0]); + sigAlgId = AlgorithmIdentifier.GetInstance(seq[1]); + sigBits = DerBitString.GetInstance(seq[2]); + } + + public CertificationRequestInfo GetCertificationRequestInfo() + { + return reqInfo; + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return sigAlgId; } + } + + public DerBitString Signature + { + get { return sigBits; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(reqInfo, sigAlgId, sigBits); + } + } +} diff --git a/crypto/src/asn1/pkcs/CertificationRequestInfo.cs b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs new file mode 100644 index 000000000..690d06878 --- /dev/null +++ b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs @@ -0,0 +1,123 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * Pkcs10 CertificationRequestInfo object. + * <pre> + * CertificationRequestInfo ::= Sequence { + * version Integer { v1(0) } (v1,...), + * subject Name, + * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, + * attributes [0] Attributes{{ CRIAttributes }} + * } + * + * Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }} + * + * Attr { ATTRIBUTE:IOSet } ::= Sequence { + * type ATTRIBUTE.&id({IOSet}), + * values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) + * } + * </pre> + */ + public class CertificationRequestInfo + : Asn1Encodable + { + internal DerInteger version = new DerInteger(0); + internal X509Name subject; + internal SubjectPublicKeyInfo subjectPKInfo; + internal Asn1Set attributes; + + public static CertificationRequestInfo GetInstance( + object obj) + { + if (obj is CertificationRequestInfo) + { + return (CertificationRequestInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new CertificationRequestInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + public CertificationRequestInfo( + X509Name subject, + SubjectPublicKeyInfo pkInfo, + Asn1Set attributes) + { + this.subject = subject; + this.subjectPKInfo = pkInfo; + this.attributes = attributes; + + if (subject == null || version == null || subjectPKInfo == null) + { + throw new ArgumentException( + "Not all mandatory fields set in CertificationRequestInfo generator."); + } + } + + private CertificationRequestInfo( + Asn1Sequence seq) + { + version = (DerInteger) seq[0]; + + subject = X509Name.GetInstance(seq[1]); + subjectPKInfo = SubjectPublicKeyInfo.GetInstance(seq[2]); + + // + // some CertificationRequestInfo objects seem to treat this field + // as optional. + // + if (seq.Count > 3) + { + DerTaggedObject tagobj = (DerTaggedObject) seq[3]; + attributes = Asn1Set.GetInstance(tagobj, false); + } + + if (subject == null || version == null || subjectPKInfo == null) + { + throw new ArgumentException( + "Not all mandatory fields set in CertificationRequestInfo generator."); + } + } + + public DerInteger Version + { + get { return version; } + } + + public X509Name Subject + { + get { return subject; } + } + + public SubjectPublicKeyInfo SubjectPublicKeyInfo + { + get { return subjectPKInfo; } + } + + public Asn1Set Attributes + { + get { return attributes; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + version, subject, subjectPKInfo); + + if (attributes != null) + { + v.Add(new DerTaggedObject(false, 0, attributes)); + } + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/ContentInfo.cs b/crypto/src/asn1/pkcs/ContentInfo.cs new file mode 100644 index 000000000..526a3c48e --- /dev/null +++ b/crypto/src/asn1/pkcs/ContentInfo.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class ContentInfo + : Asn1Encodable + { + private readonly DerObjectIdentifier contentType; + private readonly Asn1Encodable content; + + public static ContentInfo GetInstance(object obj) + { + if (obj == null) + return null; + ContentInfo existing = obj as ContentInfo; + if (existing != null) + return existing; + return new ContentInfo(Asn1Sequence.GetInstance(obj)); + } + + private ContentInfo( + Asn1Sequence seq) + { + contentType = (DerObjectIdentifier) seq[0]; + + if (seq.Count > 1) + { + content = ((Asn1TaggedObject) seq[1]).GetObject(); + } + } + + public ContentInfo( + DerObjectIdentifier contentType, + Asn1Encodable content) + { + this.contentType = contentType; + this.content = content; + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public Asn1Encodable Content + { + get { return content; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * <pre> + * ContentInfo ::= Sequence { + * contentType ContentType, + * content + * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } + * </pre> + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(contentType); + + if (content != null) + { + v.Add(new BerTaggedObject(0, content)); + } + + return new BerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/DHParameter.cs b/crypto/src/asn1/pkcs/DHParameter.cs new file mode 100644 index 000000000..25a091a97 --- /dev/null +++ b/crypto/src/asn1/pkcs/DHParameter.cs @@ -0,0 +1,72 @@ +using Org.BouncyCastle.Asn1; +using System; +using System.Collections; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class DHParameter + : Asn1Encodable + { + internal DerInteger p, g, l; + + public DHParameter( + BigInteger p, + BigInteger g, + int l) + { + this.p = new DerInteger(p); + this.g = new DerInteger(g); + + if (l != 0) + { + this.l = new DerInteger(l); + } + } + + public DHParameter( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + p = (DerInteger)e.Current; + + e.MoveNext(); + g = (DerInteger)e.Current; + + if (e.MoveNext()) + { + l = (DerInteger) e.Current; + } + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger G + { + get { return g.PositiveValue; } + } + + public BigInteger L + { + get { return l == null ? null : l.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(p, g); + + if (this.l != null) + { + v.Add(l); + } + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/EncryptedData.cs b/crypto/src/asn1/pkcs/EncryptedData.cs new file mode 100644 index 000000000..912064ace --- /dev/null +++ b/crypto/src/asn1/pkcs/EncryptedData.cs @@ -0,0 +1,104 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * The EncryptedData object. + * <pre> + * EncryptedData ::= Sequence { + * version Version, + * encryptedContentInfo EncryptedContentInfo + * } + * + * + * EncryptedContentInfo ::= Sequence { + * contentType ContentType, + * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, + * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL + * } + * + * EncryptedContent ::= OCTET STRING + * </pre> + */ + public class EncryptedData + : Asn1Encodable + { + private readonly Asn1Sequence data; +// private readonly DerObjectIdentifier bagId; +// private readonly Asn1Object bagValue; + + public static EncryptedData GetInstance( + object obj) + { + if (obj is EncryptedData) + { + return (EncryptedData) obj; + } + + if (obj is Asn1Sequence) + { + return new EncryptedData((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + private EncryptedData( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + int version = ((DerInteger) seq[0]).Value.IntValue; + if (version != 0) + { + throw new ArgumentException("sequence not version 0"); + } + + this.data = (Asn1Sequence) seq[1]; + } + + public EncryptedData( + DerObjectIdentifier contentType, + AlgorithmIdentifier encryptionAlgorithm, + Asn1Encodable content) + { + data = new BerSequence( + contentType, + encryptionAlgorithm.ToAsn1Object(), + new BerTaggedObject(false, 0, content)); + } + + public DerObjectIdentifier ContentType + { + get { return (DerObjectIdentifier) data[0]; } + } + + public AlgorithmIdentifier EncryptionAlgorithm + { + get { return AlgorithmIdentifier.GetInstance(data[1]); } + } + + public Asn1OctetString Content + { + get + { + if (data.Count == 3) + { + DerTaggedObject o = (DerTaggedObject) data[2]; + + return Asn1OctetString.GetInstance(o, false); + } + + return null; + } + } + + public override Asn1Object ToAsn1Object() + { + return new BerSequence(new DerInteger(0), data); + } + } +} diff --git a/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs new file mode 100644 index 000000000..b97b8f5ea --- /dev/null +++ b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class EncryptedPrivateKeyInfo + : Asn1Encodable + { + private readonly AlgorithmIdentifier algId; + private readonly Asn1OctetString data; + + private EncryptedPrivateKeyInfo( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + algId = AlgorithmIdentifier.GetInstance(seq[0]); + data = Asn1OctetString.GetInstance(seq[1]); + } + + public EncryptedPrivateKeyInfo( + AlgorithmIdentifier algId, + byte[] encoding) + { + this.algId = algId; + this.data = new DerOctetString(encoding); + } + + public static EncryptedPrivateKeyInfo GetInstance( + object obj) + { + if (obj is EncryptedPrivateKeyInfo) + { + return (EncryptedPrivateKeyInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new EncryptedPrivateKeyInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + public AlgorithmIdentifier EncryptionAlgorithm + { + get { return algId; } + } + + public byte[] GetEncryptedData() + { + return data.GetOctets(); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * <pre> + * EncryptedPrivateKeyInfo ::= Sequence { + * encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}}, + * encryptedData EncryptedData + * } + * + * EncryptedData ::= OCTET STRING + * + * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= { + * ... -- For local profiles + * } + * </pre> + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algId, data); + } + } +} diff --git a/crypto/src/asn1/pkcs/EncryptionScheme.cs b/crypto/src/asn1/pkcs/EncryptionScheme.cs new file mode 100644 index 000000000..5b64d6f67 --- /dev/null +++ b/crypto/src/asn1/pkcs/EncryptionScheme.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class EncryptionScheme + : AlgorithmIdentifier + { + public EncryptionScheme( + DerObjectIdentifier objectID, + Asn1Encodable parameters) + : base(objectID, parameters) + { + } + + internal EncryptionScheme( + Asn1Sequence seq) + : this((DerObjectIdentifier)seq[0], seq[1]) + { + } + + public new static EncryptionScheme GetInstance(object obj) + { + if (obj is EncryptionScheme) + { + return (EncryptionScheme)obj; + } + + if (obj is Asn1Sequence) + { + return new EncryptionScheme((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + public Asn1Object Asn1Object + { + get { return Parameters.ToAsn1Object(); } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(ObjectID, Parameters); + } + } +} diff --git a/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs b/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs new file mode 100644 index 000000000..ff608f15b --- /dev/null +++ b/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs @@ -0,0 +1,71 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class IssuerAndSerialNumber + : Asn1Encodable + { + private readonly X509Name name; + private readonly DerInteger certSerialNumber; + + public static IssuerAndSerialNumber GetInstance( + object obj) + { + if (obj is IssuerAndSerialNumber) + { + return (IssuerAndSerialNumber) obj; + } + + if (obj is Asn1Sequence) + { + return new IssuerAndSerialNumber((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + private IssuerAndSerialNumber( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.name = X509Name.GetInstance(seq[0]); + this.certSerialNumber = DerInteger.GetInstance(seq[1]); + } + + public IssuerAndSerialNumber( + X509Name name, + BigInteger certSerialNumber) + { + this.name = name; + this.certSerialNumber = new DerInteger(certSerialNumber); + } + + public IssuerAndSerialNumber( + X509Name name, + DerInteger certSerialNumber) + { + this.name = name; + this.certSerialNumber = certSerialNumber; + } + + public X509Name Name + { + get { return name; } + } + + public DerInteger CertificateSerialNumber + { + get { return certSerialNumber; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(name, certSerialNumber); + } + } +} diff --git a/crypto/src/asn1/pkcs/KeyDerivationFunc.cs b/crypto/src/asn1/pkcs/KeyDerivationFunc.cs new file mode 100644 index 000000000..9fc89853b --- /dev/null +++ b/crypto/src/asn1/pkcs/KeyDerivationFunc.cs @@ -0,0 +1,21 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class KeyDerivationFunc + : AlgorithmIdentifier + { + internal KeyDerivationFunc(Asn1Sequence seq) + : base(seq) + { + } + + public KeyDerivationFunc( + DerObjectIdentifier id, + Asn1Encodable parameters) + : base(id, parameters) + { + } + } +} \ No newline at end of file diff --git a/crypto/src/asn1/pkcs/MacData.cs b/crypto/src/asn1/pkcs/MacData.cs new file mode 100644 index 000000000..780b24153 --- /dev/null +++ b/crypto/src/asn1/pkcs/MacData.cs @@ -0,0 +1,96 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class MacData + : Asn1Encodable + { + internal DigestInfo digInfo; + internal byte[] salt; + internal BigInteger iterationCount; + + public static MacData GetInstance( + object obj) + { + if (obj is MacData) + { + return (MacData) obj; + } + + if (obj is Asn1Sequence) + { + return new MacData((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + private MacData( + Asn1Sequence seq) + { + this.digInfo = DigestInfo.GetInstance(seq[0]); + this.salt = ((Asn1OctetString) seq[1]).GetOctets(); + + if (seq.Count == 3) + { + this.iterationCount = ((DerInteger) seq[2]).Value; + } + else + { + this.iterationCount = BigInteger.One; + } + } + + public MacData( + DigestInfo digInfo, + byte[] salt, + int iterationCount) + { + this.digInfo = digInfo; + this.salt = (byte[]) salt.Clone(); + this.iterationCount = BigInteger.ValueOf(iterationCount); + } + + public DigestInfo Mac + { + get { return digInfo; } + } + + public byte[] GetSalt() + { + return (byte[]) salt.Clone(); + } + + public BigInteger IterationCount + { + get { return iterationCount; } + } + + /** + * <pre> + * MacData ::= SEQUENCE { + * mac DigestInfo, + * macSalt OCTET STRING, + * iterations INTEGER DEFAULT 1 + * -- Note: The default is for historic reasons and its use is deprecated. A + * -- higher value, like 1024 is recommended. + * </pre> + * @return the basic DERObject construction. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(digInfo, new DerOctetString(salt)); + + if (!iterationCount.Equals(BigInteger.One)) + { + v.Add(new DerInteger(iterationCount)); + } + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/PBEParameter.cs b/crypto/src/asn1/pkcs/PBEParameter.cs new file mode 100644 index 000000000..80d5ec3e1 --- /dev/null +++ b/crypto/src/asn1/pkcs/PBEParameter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class PbeParameter + : Asn1Encodable + { + private readonly Asn1OctetString salt; + private readonly DerInteger iterationCount; + + public static PbeParameter GetInstance(object obj) + { + if (obj is PbeParameter || obj == null) + { + return (PbeParameter) obj; + } + + if (obj is Asn1Sequence) + { + return new PbeParameter((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + private PbeParameter(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + salt = Asn1OctetString.GetInstance(seq[0]); + iterationCount = DerInteger.GetInstance(seq[1]); + } + + public PbeParameter(byte[] salt, int iterationCount) + { + this.salt = new DerOctetString(salt); + this.iterationCount = new DerInteger(iterationCount); + } + + public byte[] GetSalt() + { + return salt.GetOctets(); + } + + public BigInteger IterationCount + { + get { return iterationCount.Value; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(salt, iterationCount); + } + } +} diff --git a/crypto/src/asn1/pkcs/PBES2Parameters.cs b/crypto/src/asn1/pkcs/PBES2Parameters.cs new file mode 100644 index 000000000..fc6904eed --- /dev/null +++ b/crypto/src/asn1/pkcs/PBES2Parameters.cs @@ -0,0 +1,65 @@ +using System; + +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) + return null; + PbeS2Parameters existing = obj as PbeS2Parameters; + if (existing != null) + return existing; + return new PbeS2Parameters(Asn1Sequence.GetInstance(obj)); + } + + public PbeS2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme) + { + this.func = keyDevFunc; + this.scheme = encScheme; + } + + [Obsolete("Use GetInstance() instead")] + public PbeS2Parameters( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + Asn1Sequence funcSeq = (Asn1Sequence)seq[0].ToAsn1Object(); + + // 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 = EncryptionScheme.GetInstance(seq[1].ToAsn1Object()); + } + + public KeyDerivationFunc KeyDerivationFunc + { + get { return func; } + } + + public EncryptionScheme EncryptionScheme + { + get { return scheme; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(func, scheme); + } + } +} diff --git a/crypto/src/asn1/pkcs/PBKDF2Params.cs b/crypto/src/asn1/pkcs/PBKDF2Params.cs new file mode 100644 index 000000000..1351b94cf --- /dev/null +++ b/crypto/src/asn1/pkcs/PBKDF2Params.cs @@ -0,0 +1,86 @@ +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 Pbkdf2Params( + byte[] salt, + int iterationCount, + int keyLength) + : this(salt, iterationCount) + { + this.keyLength = new DerInteger(keyLength); + } + + 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); + } + } +} diff --git a/crypto/src/asn1/pkcs/PKCS12PBEParams.cs b/crypto/src/asn1/pkcs/PKCS12PBEParams.cs new file mode 100644 index 000000000..7521f93ea --- /dev/null +++ b/crypto/src/asn1/pkcs/PKCS12PBEParams.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class Pkcs12PbeParams + : Asn1Encodable + { + private readonly DerInteger iterations; + private readonly Asn1OctetString iv; + + public Pkcs12PbeParams( + byte[] salt, + int iterations) + { + this.iv = new DerOctetString(salt); + this.iterations = new DerInteger(iterations); + } + + private Pkcs12PbeParams( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + iv = Asn1OctetString.GetInstance(seq[0]); + iterations = DerInteger.GetInstance(seq[1]); + } + + public static Pkcs12PbeParams GetInstance( + object obj) + { + if (obj is Pkcs12PbeParams) + { + return (Pkcs12PbeParams) obj; + } + + if (obj is Asn1Sequence) + { + return new Pkcs12PbeParams((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + public BigInteger Iterations + { + get { return iterations.Value; } + } + + public byte[] GetIV() + { + return iv.GetOctets(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(iv, iterations); + } + } +} diff --git a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs new file mode 100644 index 000000000..0b2ffa0d1 --- /dev/null +++ b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs @@ -0,0 +1,256 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public abstract class PkcsObjectIdentifiers + { + // + // pkcs-1 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } + // + public const string Pkcs1 = "1.2.840.113549.1.1"; + + public static readonly DerObjectIdentifier RsaEncryption = new DerObjectIdentifier(Pkcs1 + ".1"); + public static readonly DerObjectIdentifier MD2WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".2"); + public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".3"); + public static readonly DerObjectIdentifier MD5WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".4"); + public static readonly DerObjectIdentifier Sha1WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".5"); + public static readonly DerObjectIdentifier SrsaOaepEncryptionSet = new DerObjectIdentifier(Pkcs1 + ".6"); + public static readonly DerObjectIdentifier IdRsaesOaep = new DerObjectIdentifier(Pkcs1 + ".7"); + public static readonly DerObjectIdentifier IdMgf1 = new DerObjectIdentifier(Pkcs1 + ".8"); + public static readonly DerObjectIdentifier IdPSpecified = new DerObjectIdentifier(Pkcs1 + ".9"); + public static readonly DerObjectIdentifier IdRsassaPss = new DerObjectIdentifier(Pkcs1 + ".10"); + public static readonly DerObjectIdentifier Sha256WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".11"); + public static readonly DerObjectIdentifier Sha384WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".12"); + public static readonly DerObjectIdentifier Sha512WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".13"); + public static readonly DerObjectIdentifier Sha224WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".14"); + + // + // pkcs-3 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 } + // + public const string Pkcs3 = "1.2.840.113549.1.3"; + + public static readonly DerObjectIdentifier DhKeyAgreement = new DerObjectIdentifier(Pkcs3 + ".1"); + + // + // pkcs-5 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } + // + public const string Pkcs5 = "1.2.840.113549.1.5"; + + public static readonly DerObjectIdentifier PbeWithMD2AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".1"); + public static readonly DerObjectIdentifier PbeWithMD2AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".4"); + public static readonly DerObjectIdentifier PbeWithMD5AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".3"); + public static readonly DerObjectIdentifier PbeWithMD5AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".6"); + public static readonly DerObjectIdentifier PbeWithSha1AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".10"); + public static readonly DerObjectIdentifier PbeWithSha1AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".11"); + + public static readonly DerObjectIdentifier IdPbeS2 = new DerObjectIdentifier(Pkcs5 + ".13"); + public static readonly DerObjectIdentifier IdPbkdf2 = new DerObjectIdentifier(Pkcs5 + ".12"); + + // + // encryptionAlgorithm OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) 3 } + // + public const string EncryptionAlgorithm = "1.2.840.113549.3"; + + public static readonly DerObjectIdentifier DesEde3Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".7"); + public static readonly DerObjectIdentifier RC2Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".2"); + + // + // object identifiers for digests + // + public const string DigestAlgorithm = "1.2.840.113549.2"; + + // + // md2 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 2} + // + public static readonly DerObjectIdentifier MD2 = new DerObjectIdentifier(DigestAlgorithm + ".2"); + + // + // md4 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 4} + // + public static readonly DerObjectIdentifier MD4 = new DerObjectIdentifier(DigestAlgorithm + ".4"); + + // + // md5 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 5} + // + public static readonly DerObjectIdentifier MD5 = new DerObjectIdentifier(DigestAlgorithm + ".5"); + + public static readonly DerObjectIdentifier IdHmacWithSha1 = new DerObjectIdentifier(DigestAlgorithm + ".7"); + public static readonly DerObjectIdentifier IdHmacWithSha224 = new DerObjectIdentifier(DigestAlgorithm + ".8"); + public static readonly DerObjectIdentifier IdHmacWithSha256 = new DerObjectIdentifier(DigestAlgorithm + ".9"); + public static readonly DerObjectIdentifier IdHmacWithSha384 = new DerObjectIdentifier(DigestAlgorithm + ".10"); + public static readonly DerObjectIdentifier IdHmacWithSha512 = new DerObjectIdentifier(DigestAlgorithm + ".11"); + + // + // pkcs-7 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } + // + public const string Pkcs7 = "1.2.840.113549.1.7"; + + public static readonly DerObjectIdentifier Data = new DerObjectIdentifier(Pkcs7 + ".1"); + public static readonly DerObjectIdentifier SignedData = new DerObjectIdentifier(Pkcs7 + ".2"); + public static readonly DerObjectIdentifier EnvelopedData = new DerObjectIdentifier(Pkcs7 + ".3"); + public static readonly DerObjectIdentifier SignedAndEnvelopedData = new DerObjectIdentifier(Pkcs7 + ".4"); + public static readonly DerObjectIdentifier DigestedData = new DerObjectIdentifier(Pkcs7 + ".5"); + public static readonly DerObjectIdentifier EncryptedData = new DerObjectIdentifier(Pkcs7 + ".6"); + + // + // pkcs-9 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } + // + public const string Pkcs9 = "1.2.840.113549.1.9"; + + public static readonly DerObjectIdentifier Pkcs9AtEmailAddress = new DerObjectIdentifier(Pkcs9 + ".1"); + public static readonly DerObjectIdentifier Pkcs9AtUnstructuredName = new DerObjectIdentifier(Pkcs9 + ".2"); + public static readonly DerObjectIdentifier Pkcs9AtContentType = new DerObjectIdentifier(Pkcs9 + ".3"); + public static readonly DerObjectIdentifier Pkcs9AtMessageDigest = new DerObjectIdentifier(Pkcs9 + ".4"); + public static readonly DerObjectIdentifier Pkcs9AtSigningTime = new DerObjectIdentifier(Pkcs9 + ".5"); + public static readonly DerObjectIdentifier Pkcs9AtCounterSignature = new DerObjectIdentifier(Pkcs9 + ".6"); + public static readonly DerObjectIdentifier Pkcs9AtChallengePassword = new DerObjectIdentifier(Pkcs9 + ".7"); + public static readonly DerObjectIdentifier Pkcs9AtUnstructuredAddress = new DerObjectIdentifier(Pkcs9 + ".8"); + public static readonly DerObjectIdentifier Pkcs9AtExtendedCertificateAttributes = new DerObjectIdentifier(Pkcs9 + ".9"); + public static readonly DerObjectIdentifier Pkcs9AtSigningDescription = new DerObjectIdentifier(Pkcs9 + ".13"); + public static readonly DerObjectIdentifier Pkcs9AtExtensionRequest = new DerObjectIdentifier(Pkcs9 + ".14"); + public static readonly DerObjectIdentifier Pkcs9AtSmimeCapabilities = new DerObjectIdentifier(Pkcs9 + ".15"); + public static readonly DerObjectIdentifier Pkcs9AtFriendlyName = new DerObjectIdentifier(Pkcs9 + ".20"); + public static readonly DerObjectIdentifier Pkcs9AtLocalKeyID = new DerObjectIdentifier(Pkcs9 + ".21"); + + [Obsolete("Use X509Certificate instead")] + public static readonly DerObjectIdentifier X509CertType = new DerObjectIdentifier(Pkcs9 + ".22.1"); + + public const string CertTypes = Pkcs9 + ".22"; + public static readonly DerObjectIdentifier X509Certificate = new DerObjectIdentifier(CertTypes + ".1"); + public static readonly DerObjectIdentifier SdsiCertificate = new DerObjectIdentifier(CertTypes + ".2"); + + public const string CrlTypes = Pkcs9 + ".23"; + public static readonly DerObjectIdentifier X509Crl = new DerObjectIdentifier(CrlTypes + ".1"); + + public static readonly DerObjectIdentifier IdAlgPwriKek = new DerObjectIdentifier(Pkcs9 + ".16.3.9"); + + // + // SMIME capability sub oids. + // + public static readonly DerObjectIdentifier PreferSignedData = new DerObjectIdentifier(Pkcs9 + ".15.1"); + public static readonly DerObjectIdentifier CannotDecryptAny = new DerObjectIdentifier(Pkcs9 + ".15.2"); + public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = new DerObjectIdentifier(Pkcs9 + ".15.3"); + + // + // other SMIME attributes + // + public static readonly DerObjectIdentifier IdAAReceiptRequest = new DerObjectIdentifier(Pkcs9 + ".16.2.1"); + + // + // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)} + // + public const string IdCT = "1.2.840.113549.1.9.16.1"; + + public static readonly DerObjectIdentifier IdCTAuthData = new DerObjectIdentifier(IdCT + ".2"); + public static readonly DerObjectIdentifier IdCTTstInfo = new DerObjectIdentifier(IdCT + ".4"); + public static readonly DerObjectIdentifier IdCTCompressedData = new DerObjectIdentifier(IdCT + ".9"); + public static readonly DerObjectIdentifier IdCTAuthEnvelopedData = new DerObjectIdentifier(IdCT + ".23"); + public static readonly DerObjectIdentifier IdCTTimestampedData = new DerObjectIdentifier(IdCT + ".31"); + + // + // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)} + // + public const string IdCti = "1.2.840.113549.1.9.16.6"; + + public static readonly DerObjectIdentifier IdCtiEtsProofOfOrigin = new DerObjectIdentifier(IdCti + ".1"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfReceipt = new DerObjectIdentifier(IdCti + ".2"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfDelivery = new DerObjectIdentifier(IdCti + ".3"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfSender = new DerObjectIdentifier(IdCti + ".4"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfApproval = new DerObjectIdentifier(IdCti + ".5"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfCreation = new DerObjectIdentifier(IdCti + ".6"); + + // + // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)} + // + public const string IdAA = "1.2.840.113549.1.9.16.2"; + + public static readonly DerObjectIdentifier IdAAContentHint = new DerObjectIdentifier(IdAA + ".4"); // See RFC 2634 + public static readonly DerObjectIdentifier IdAAMsgSigDigest = new DerObjectIdentifier(IdAA + ".5"); + public static readonly DerObjectIdentifier IdAAContentReference = new DerObjectIdentifier(IdAA + ".10"); + + /* + * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11} + * + */ + public static readonly DerObjectIdentifier IdAAEncrypKeyPref = new DerObjectIdentifier(IdAA + ".11"); + public static readonly DerObjectIdentifier IdAASigningCertificate = new DerObjectIdentifier(IdAA + ".12"); + public static readonly DerObjectIdentifier IdAASigningCertificateV2 = new DerObjectIdentifier(IdAA + ".47"); + + public static readonly DerObjectIdentifier IdAAContentIdentifier = new DerObjectIdentifier(IdAA + ".7"); // See RFC 2634 + + /* + * RFC 3126 + */ + public static readonly DerObjectIdentifier IdAASignatureTimeStampToken = new DerObjectIdentifier(IdAA + ".14"); + + public static readonly DerObjectIdentifier IdAAEtsSigPolicyID = new DerObjectIdentifier(IdAA + ".15"); + public static readonly DerObjectIdentifier IdAAEtsCommitmentType = new DerObjectIdentifier(IdAA + ".16"); + public static readonly DerObjectIdentifier IdAAEtsSignerLocation = new DerObjectIdentifier(IdAA + ".17"); + public static readonly DerObjectIdentifier IdAAEtsSignerAttr = new DerObjectIdentifier(IdAA + ".18"); + public static readonly DerObjectIdentifier IdAAEtsOtherSigCert = new DerObjectIdentifier(IdAA + ".19"); + public static readonly DerObjectIdentifier IdAAEtsContentTimestamp = new DerObjectIdentifier(IdAA + ".20"); + public static readonly DerObjectIdentifier IdAAEtsCertificateRefs = new DerObjectIdentifier(IdAA + ".21"); + public static readonly DerObjectIdentifier IdAAEtsRevocationRefs = new DerObjectIdentifier(IdAA + ".22"); + public static readonly DerObjectIdentifier IdAAEtsCertValues = new DerObjectIdentifier(IdAA + ".23"); + public static readonly DerObjectIdentifier IdAAEtsRevocationValues = new DerObjectIdentifier(IdAA + ".24"); + public static readonly DerObjectIdentifier IdAAEtsEscTimeStamp = new DerObjectIdentifier(IdAA + ".25"); + public static readonly DerObjectIdentifier IdAAEtsCertCrlTimestamp = new DerObjectIdentifier(IdAA + ".26"); + public static readonly DerObjectIdentifier IdAAEtsArchiveTimestamp = new DerObjectIdentifier(IdAA + ".27"); + + [Obsolete("Use 'IdAAEtsSigPolicyID' instead")] + public static readonly DerObjectIdentifier IdAASigPolicyID = IdAAEtsSigPolicyID; + [Obsolete("Use 'IdAAEtsCommitmentType' instead")] + public static readonly DerObjectIdentifier IdAACommitmentType = IdAAEtsCommitmentType; + [Obsolete("Use 'IdAAEtsSignerLocation' instead")] + public static readonly DerObjectIdentifier IdAASignerLocation = IdAAEtsSignerLocation; + [Obsolete("Use 'IdAAEtsOtherSigCert' instead")] + public static readonly DerObjectIdentifier IdAAOtherSigCert = IdAAEtsOtherSigCert; + + // + // id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)} + // + public const string IdSpq = "1.2.840.113549.1.9.16.5"; + + public static readonly DerObjectIdentifier IdSpqEtsUri = new DerObjectIdentifier(IdSpq + ".1"); + public static readonly DerObjectIdentifier IdSpqEtsUNotice = new DerObjectIdentifier(IdSpq + ".2"); + + // + // pkcs-12 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } + // + public const string Pkcs12 = "1.2.840.113549.1.12"; + public const string BagTypes = Pkcs12 + ".10.1"; + + public static readonly DerObjectIdentifier KeyBag = new DerObjectIdentifier(BagTypes + ".1"); + public static readonly DerObjectIdentifier Pkcs8ShroudedKeyBag = new DerObjectIdentifier(BagTypes + ".2"); + public static readonly DerObjectIdentifier CertBag = new DerObjectIdentifier(BagTypes + ".3"); + public static readonly DerObjectIdentifier CrlBag = new DerObjectIdentifier(BagTypes + ".4"); + public static readonly DerObjectIdentifier SecretBag = new DerObjectIdentifier(BagTypes + ".5"); + public static readonly DerObjectIdentifier SafeContentsBag = new DerObjectIdentifier(BagTypes + ".6"); + + public const string Pkcs12PbeIds = Pkcs12 + ".1"; + + public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".1"); + public static readonly DerObjectIdentifier PbeWithShaAnd40BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".2"); + public static readonly DerObjectIdentifier PbeWithShaAnd3KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".3"); + public static readonly DerObjectIdentifier PbeWithShaAnd2KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".4"); + public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".5"); + public static readonly DerObjectIdentifier PbewithShaAnd40BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".6"); + + public static readonly DerObjectIdentifier IdAlgCms3DesWrap = new DerObjectIdentifier("1.2.840.113549.1.9.16.3.6"); + public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = new DerObjectIdentifier("1.2.840.113549.1.9.16.3.7"); + } +} diff --git a/crypto/src/asn1/pkcs/Pfx.cs b/crypto/src/asn1/pkcs/Pfx.cs new file mode 100644 index 000000000..9676f64fc --- /dev/null +++ b/crypto/src/asn1/pkcs/Pfx.cs @@ -0,0 +1,65 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * the infamous Pfx from Pkcs12 + */ + public class Pfx + : Asn1Encodable + { + private ContentInfo contentInfo; + private MacData macData; + + public Pfx( + Asn1Sequence seq) + { + BigInteger version = ((DerInteger) seq[0]).Value; + if (version.IntValue != 3) + { + throw new ArgumentException("wrong version for PFX PDU"); + } + + contentInfo = ContentInfo.GetInstance(seq[1]); + + if (seq.Count == 3) + { + macData = MacData.GetInstance(seq[2]); + } + } + + public Pfx( + ContentInfo contentInfo, + MacData macData) + { + this.contentInfo = contentInfo; + this.macData = macData; + } + + public ContentInfo AuthSafe + { + get { return contentInfo; } + } + + public MacData MacData + { + get { return macData; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(3), contentInfo); + + if (macData != null) + { + v.Add(macData); + } + + return new BerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs new file mode 100644 index 000000000..91b6fb456 --- /dev/null +++ b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class PrivateKeyInfo + : Asn1Encodable + { + private readonly Asn1Object privKey; + private readonly AlgorithmIdentifier algID; + private readonly Asn1Set attributes; + + public static PrivateKeyInfo GetInstance( + object obj) + { + if (obj is PrivateKeyInfo) + return (PrivateKeyInfo) obj; + + if (obj != null) + return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public PrivateKeyInfo( + AlgorithmIdentifier algID, + Asn1Object privateKey) + : this(algID, privateKey, null) + { + } + + public PrivateKeyInfo( + AlgorithmIdentifier algID, + Asn1Object privateKey, + Asn1Set attributes) + { + this.privKey = privateKey; + this.algID = algID; + this.attributes = attributes; + } + + private PrivateKeyInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + BigInteger version = ((DerInteger) e.Current).Value; + if (version.IntValue != 0) + { + throw new ArgumentException("wrong version for private key info: " + version.IntValue); + } + + e.MoveNext(); + algID = AlgorithmIdentifier.GetInstance(e.Current); + + try + { + e.MoveNext(); + Asn1OctetString data = (Asn1OctetString) e.Current; + + privKey = Asn1Object.FromByteArray(data.GetOctets()); + } + catch (IOException) + { + throw new ArgumentException("Error recoverying private key from sequence"); + } + + if (e.MoveNext()) + { + attributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false); + } + } + + public AlgorithmIdentifier AlgorithmID + { + get { return algID; } + } + + public Asn1Object PrivateKey + { + get { return privKey; } + } + + public Asn1Set Attributes + { + get { return attributes; } + } + + /** + * write out an RSA private key with its associated information + * as described in Pkcs8. + * <pre> + * PrivateKeyInfo ::= Sequence { + * version Version, + * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}}, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL + * } + * Version ::= Integer {v1(0)} (v1,...) + * + * PrivateKey ::= OCTET STRING + * + * Attributes ::= Set OF Attr + * </pre> + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(0), + algID, + new DerOctetString(privKey)); + + if (attributes != null) + { + v.Add(new DerTaggedObject(false, 0, attributes)); + } + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/RC2CBCParameter.cs b/crypto/src/asn1/pkcs/RC2CBCParameter.cs new file mode 100644 index 000000000..f5355d012 --- /dev/null +++ b/crypto/src/asn1/pkcs/RC2CBCParameter.cs @@ -0,0 +1,81 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RC2CbcParameter + : Asn1Encodable + { + internal DerInteger version; + internal Asn1OctetString iv; + + public static RC2CbcParameter GetInstance( + object obj) + { + if (obj is Asn1Sequence) + { + return new RC2CbcParameter((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + public RC2CbcParameter( + byte[] iv) + { + this.iv = new DerOctetString(iv); + } + + public RC2CbcParameter( + int parameterVersion, + byte[] iv) + { + this.version = new DerInteger(parameterVersion); + this.iv = new DerOctetString(iv); + } + + private RC2CbcParameter( + Asn1Sequence seq) + { + if (seq.Count == 1) + { + iv = (Asn1OctetString)seq[0]; + } + else + { + version = (DerInteger)seq[0]; + iv = (Asn1OctetString)seq[1]; + } + } + + public BigInteger RC2ParameterVersion + { + get + { + return version == null ? null : version.Value; + } + } + + public byte[] GetIV() + { + return Arrays.Clone(iv.GetOctets()); + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (version != null) + { + v.Add(version); + } + + v.Add(iv); + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/RSAESOAEPparams.cs b/crypto/src/asn1/pkcs/RSAESOAEPparams.cs new file mode 100644 index 000000000..5ecb394fd --- /dev/null +++ b/crypto/src/asn1/pkcs/RSAESOAEPparams.cs @@ -0,0 +1,145 @@ +using System; + +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RsaesOaepParameters + : Asn1Encodable + { + private AlgorithmIdentifier hashAlgorithm; + private AlgorithmIdentifier maskGenAlgorithm; + private AlgorithmIdentifier pSourceAlgorithm; + + public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm); + public readonly static AlgorithmIdentifier DefaultPSourceAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0])); + + public static RsaesOaepParameters GetInstance( + object obj) + { + if (obj is RsaesOaepParameters) + { + return (RsaesOaepParameters)obj; + } + else if (obj is Asn1Sequence) + { + return new RsaesOaepParameters((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + /** + * The default version + */ + public RsaesOaepParameters() + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + pSourceAlgorithm = DefaultPSourceAlgorithm; + } + + public RsaesOaepParameters( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm, + AlgorithmIdentifier pSourceAlgorithm) + { + this.hashAlgorithm = hashAlgorithm; + this.maskGenAlgorithm = maskGenAlgorithm; + this.pSourceAlgorithm = pSourceAlgorithm; + } + + public RsaesOaepParameters( + Asn1Sequence seq) + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + pSourceAlgorithm = DefaultPSourceAlgorithm; + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject o = (Asn1TaggedObject)seq[i]; + + switch (o.TagNo) + { + case 0: + hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 1: + maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 2: + pSourceAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + default: + throw new ArgumentException("unknown tag"); + } + } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public AlgorithmIdentifier MaskGenAlgorithm + { + get { return maskGenAlgorithm; } + } + + public AlgorithmIdentifier PSourceAlgorithm + { + get { return pSourceAlgorithm; } + } + + /** + * <pre> + * RSAES-OAEP-params ::= SEQUENCE { + * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1, + * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1, + * pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty + * } + * + * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-sha1 PARAMETERS NULL }| + * { OID id-sha256 PARAMETERS NULL }| + * { OID id-sha384 PARAMETERS NULL }| + * { OID id-sha512 PARAMETERS NULL }, + * ... -- Allows for future expansion -- + * } + * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms }, + * ... -- Allows for future expansion -- + * } + * PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-pSpecified PARAMETERS OCTET STRING }, + * ... -- Allows for future expansion -- + * } + * </pre> + * @return the asn1 primitive representing the parameters. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (!hashAlgorithm.Equals(DefaultHashAlgorithm)) + { + v.Add(new DerTaggedObject(true, 0, hashAlgorithm)); + } + + if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction)) + { + v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm)); + } + + if (!pSourceAlgorithm.Equals(DefaultPSourceAlgorithm)) + { + v.Add(new DerTaggedObject(true, 2, pSourceAlgorithm)); + } + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs b/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs new file mode 100644 index 000000000..dbb07c744 --- /dev/null +++ b/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RsaPrivateKeyStructure + : Asn1Encodable + { + private readonly BigInteger modulus; + private readonly BigInteger publicExponent; + private readonly BigInteger privateExponent; + private readonly BigInteger prime1; + private readonly BigInteger prime2; + private readonly BigInteger exponent1; + private readonly BigInteger exponent2; + private readonly BigInteger coefficient; + + public RsaPrivateKeyStructure( + BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger prime1, + BigInteger prime2, + BigInteger exponent1, + BigInteger exponent2, + BigInteger coefficient) + { + this.modulus = modulus; + this.publicExponent = publicExponent; + this.privateExponent = privateExponent; + this.prime1 = prime1; + this.prime2 = prime2; + this.exponent1 = exponent1; + this.exponent2 = exponent2; + this.coefficient = coefficient; + } + + public RsaPrivateKeyStructure( + Asn1Sequence seq) + { + BigInteger version = ((DerInteger) seq[0]).Value; + if (version.IntValue != 0) + throw new ArgumentException("wrong version for RSA private key"); + + modulus = ((DerInteger) seq[1]).Value; + publicExponent = ((DerInteger) seq[2]).Value; + privateExponent = ((DerInteger) seq[3]).Value; + prime1 = ((DerInteger) seq[4]).Value; + prime2 = ((DerInteger) seq[5]).Value; + exponent1 = ((DerInteger) seq[6]).Value; + exponent2 = ((DerInteger) seq[7]).Value; + coefficient = ((DerInteger) seq[8]).Value; + } + + public BigInteger Modulus + { + get { return modulus; } + } + + public BigInteger PublicExponent + { + get { return publicExponent; } + } + + public BigInteger PrivateExponent + { + get { return privateExponent; } + } + + public BigInteger Prime1 + { + get { return prime1; } + } + + public BigInteger Prime2 + { + get { return prime2; } + } + + public BigInteger Exponent1 + { + get { return exponent1; } + } + + public BigInteger Exponent2 + { + get { return exponent2; } + } + + public BigInteger Coefficient + { + get { return coefficient; } + } + + /** + * This outputs the key in Pkcs1v2 format. + * <pre> + * RsaPrivateKey ::= Sequence { + * version Version, + * modulus Integer, -- n + * publicExponent Integer, -- e + * privateExponent Integer, -- d + * prime1 Integer, -- p + * prime2 Integer, -- q + * exponent1 Integer, -- d mod (p-1) + * exponent2 Integer, -- d mod (q-1) + * coefficient Integer -- (inverse of q) mod p + * } + * + * Version ::= Integer + * </pre> + * <p>This routine is written to output Pkcs1 version 0, private keys.</p> + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence( + new DerInteger(0), // version + new DerInteger(Modulus), + new DerInteger(PublicExponent), + new DerInteger(PrivateExponent), + new DerInteger(Prime1), + new DerInteger(Prime2), + new DerInteger(Exponent1), + new DerInteger(Exponent2), + new DerInteger(Coefficient)); + } + } +} diff --git a/crypto/src/asn1/pkcs/RSASSAPSSparams.cs b/crypto/src/asn1/pkcs/RSASSAPSSparams.cs new file mode 100644 index 000000000..941620761 --- /dev/null +++ b/crypto/src/asn1/pkcs/RSASSAPSSparams.cs @@ -0,0 +1,165 @@ +using System; + +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RsassaPssParameters + : Asn1Encodable + { + private AlgorithmIdentifier hashAlgorithm; + private AlgorithmIdentifier maskGenAlgorithm; + private DerInteger saltLength; + private DerInteger trailerField; + + public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm); + public readonly static DerInteger DefaultSaltLength = new DerInteger(20); + public readonly static DerInteger DefaultTrailerField = new DerInteger(1); + + public static RsassaPssParameters GetInstance( + object obj) + { + if (obj == null || obj is RsassaPssParameters) + { + return (RsassaPssParameters)obj; + } + + if (obj is Asn1Sequence) + { + return new RsassaPssParameters((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + /** + * The default version + */ + public RsassaPssParameters() + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + saltLength = DefaultSaltLength; + trailerField = DefaultTrailerField; + } + + public RsassaPssParameters( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm, + DerInteger saltLength, + DerInteger trailerField) + { + this.hashAlgorithm = hashAlgorithm; + this.maskGenAlgorithm = maskGenAlgorithm; + this.saltLength = saltLength; + this.trailerField = trailerField; + } + + public RsassaPssParameters( + Asn1Sequence seq) + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + saltLength = DefaultSaltLength; + trailerField = DefaultTrailerField; + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject o = (Asn1TaggedObject)seq[i]; + + switch (o.TagNo) + { + case 0: + hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 1: + maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 2: + saltLength = DerInteger.GetInstance(o, true); + break; + case 3: + trailerField = DerInteger.GetInstance(o, true); + break; + default: + throw new ArgumentException("unknown tag"); + } + } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public AlgorithmIdentifier MaskGenAlgorithm + { + get { return maskGenAlgorithm; } + } + + public DerInteger SaltLength + { + get { return saltLength; } + } + + public DerInteger TrailerField + { + get { return trailerField; } + } + + /** + * <pre> + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1, + * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] TrailerField DEFAULT trailerFieldBC + * } + * + * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-sha1 PARAMETERS NULL }| + * { OID id-sha256 PARAMETERS NULL }| + * { OID id-sha384 PARAMETERS NULL }| + * { OID id-sha512 PARAMETERS NULL }, + * ... -- Allows for future expansion -- + * } + * + * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms }, + * ... -- Allows for future expansion -- + * } + * + * TrailerField ::= INTEGER { trailerFieldBC(1) } + * </pre> + * @return the asn1 primitive representing the parameters. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (!hashAlgorithm.Equals(DefaultHashAlgorithm)) + { + v.Add(new DerTaggedObject(true, 0, hashAlgorithm)); + } + + if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction)) + { + v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm)); + } + + if (!saltLength.Equals(DefaultSaltLength)) + { + v.Add(new DerTaggedObject(true, 2, saltLength)); + } + + if (!trailerField.Equals(DefaultTrailerField)) + { + v.Add(new DerTaggedObject(true, 3, trailerField)); + } + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/SafeBag.cs b/crypto/src/asn1/pkcs/SafeBag.cs new file mode 100644 index 000000000..4b9350bac --- /dev/null +++ b/crypto/src/asn1/pkcs/SafeBag.cs @@ -0,0 +1,70 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class SafeBag + : Asn1Encodable + { + private readonly DerObjectIdentifier bagID; + private readonly Asn1Object bagValue; + private readonly Asn1Set bagAttributes; + + public SafeBag( + DerObjectIdentifier oid, + Asn1Object obj) + { + this.bagID = oid; + this.bagValue = obj; + this.bagAttributes = null; + } + + public SafeBag( + DerObjectIdentifier oid, + Asn1Object obj, + Asn1Set bagAttributes) + { + this.bagID = oid; + this.bagValue = obj; + this.bagAttributes = bagAttributes; + } + + public SafeBag( + Asn1Sequence seq) + { + this.bagID = (DerObjectIdentifier) seq[0]; + this.bagValue = ((DerTaggedObject) seq[1]).GetObject(); + if (seq.Count == 3) + { + this.bagAttributes = (Asn1Set) seq[2]; + } + } + + public DerObjectIdentifier BagID + { + get { return bagID; } + } + + public Asn1Object BagValue + { + get { return bagValue; } + } + + public Asn1Set BagAttributes + { + get { return bagAttributes; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + bagID, new DerTaggedObject(0, bagValue)); + + if (bagAttributes != null) + { + v.Add(bagAttributes); + } + + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/SignedData.cs b/crypto/src/asn1/pkcs/SignedData.cs new file mode 100644 index 000000000..6e72bd0a9 --- /dev/null +++ b/crypto/src/asn1/pkcs/SignedData.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * a Pkcs#7 signed data object. + */ + public class SignedData + : Asn1Encodable + { + private readonly DerInteger version; + private readonly Asn1Set digestAlgorithms; + private readonly ContentInfo contentInfo; + private readonly Asn1Set certificates; + private readonly Asn1Set crls; + private readonly Asn1Set signerInfos; + + public static SignedData GetInstance(object obj) + { + if (obj == null) + return null; + SignedData existing = obj as SignedData; + if (existing != null) + return existing; + return new SignedData(Asn1Sequence.GetInstance(obj)); + } + + public SignedData( + DerInteger _version, + Asn1Set _digestAlgorithms, + ContentInfo _contentInfo, + Asn1Set _certificates, + Asn1Set _crls, + Asn1Set _signerInfos) + { + version = _version; + digestAlgorithms = _digestAlgorithms; + contentInfo = _contentInfo; + certificates = _certificates; + crls = _crls; + signerInfos = _signerInfos; + } + + private SignedData( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + version = (DerInteger) e.Current; + + e.MoveNext(); + digestAlgorithms = (Asn1Set) e.Current; + + e.MoveNext(); + contentInfo = ContentInfo.GetInstance(e.Current); + + while (e.MoveNext()) + { + Asn1Object o = (Asn1Object) e.Current; + + // + // an interesting feature of SignedData is that there appear to be varying implementations... + // for the moment we ignore anything which doesn't fit. + // + if (o is DerTaggedObject) + { + DerTaggedObject tagged = (DerTaggedObject) o; + + switch (tagged.TagNo) + { + case 0: + certificates = Asn1Set.GetInstance(tagged, false); + break; + case 1: + crls = Asn1Set.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag value " + tagged.TagNo); + } + } + else + { + signerInfos = (Asn1Set) o; + } + } + } + + public DerInteger Version + { + get { return version; } + } + + public Asn1Set DigestAlgorithms + { + get { return digestAlgorithms; } + } + + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + public Asn1Set Certificates + { + get { return certificates; } + } + + public Asn1Set Crls + { + get { return crls; } + } + + public Asn1Set SignerInfos + { + get { return signerInfos; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * <pre> + * SignedData ::= Sequence { + * version Version, + * digestAlgorithms DigestAlgorithmIdentifiers, + * contentInfo ContentInfo, + * certificates + * [0] IMPLICIT ExtendedCertificatesAndCertificates + * OPTIONAL, + * crls + * [1] IMPLICIT CertificateRevocationLists OPTIONAL, + * signerInfos SignerInfos } + * </pre> + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + version, digestAlgorithms, contentInfo); + + if (certificates != null) + { + v.Add(new DerTaggedObject(false, 0, certificates)); + } + + if (crls != null) + { + v.Add(new DerTaggedObject(false, 1, crls)); + } + + v.Add(signerInfos); + + return new BerSequence(v); + } + } +} diff --git a/crypto/src/asn1/pkcs/SignerInfo.cs b/crypto/src/asn1/pkcs/SignerInfo.cs new file mode 100644 index 000000000..1e4694547 --- /dev/null +++ b/crypto/src/asn1/pkcs/SignerInfo.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * a Pkcs#7 signer info object. + */ + public class SignerInfo + : Asn1Encodable + { + private DerInteger version; + private IssuerAndSerialNumber issuerAndSerialNumber; + private AlgorithmIdentifier digAlgorithm; + private Asn1Set authenticatedAttributes; + private AlgorithmIdentifier digEncryptionAlgorithm; + private Asn1OctetString encryptedDigest; + private Asn1Set unauthenticatedAttributes; + + public static SignerInfo GetInstance( + object obj) + { + if (obj is SignerInfo) + { + return (SignerInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new SignerInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + public SignerInfo( + DerInteger version, + IssuerAndSerialNumber issuerAndSerialNumber, + AlgorithmIdentifier digAlgorithm, + Asn1Set authenticatedAttributes, + AlgorithmIdentifier digEncryptionAlgorithm, + Asn1OctetString encryptedDigest, + Asn1Set unauthenticatedAttributes) + { + this.version = version; + this.issuerAndSerialNumber = issuerAndSerialNumber; + this.digAlgorithm = digAlgorithm; + this.authenticatedAttributes = authenticatedAttributes; + this.digEncryptionAlgorithm = digEncryptionAlgorithm; + this.encryptedDigest = encryptedDigest; + this.unauthenticatedAttributes = unauthenticatedAttributes; + } + + public SignerInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + version = (DerInteger) e.Current; + + e.MoveNext(); + issuerAndSerialNumber = IssuerAndSerialNumber.GetInstance(e.Current); + + e.MoveNext(); + digAlgorithm = AlgorithmIdentifier.GetInstance(e.Current); + + e.MoveNext(); + object obj = e.Current; + + if (obj is Asn1TaggedObject) + { + authenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) obj, false); + + e.MoveNext(); + digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(e.Current); + } + else + { + authenticatedAttributes = null; + digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(obj); + } + + e.MoveNext(); + encryptedDigest = DerOctetString.GetInstance(e.Current); + + if (e.MoveNext()) + { + unauthenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject)e.Current, false); + } + else + { + unauthenticatedAttributes = null; + } + } + + public DerInteger Version { get { return version; } } + + public IssuerAndSerialNumber IssuerAndSerialNumber { get { return issuerAndSerialNumber; } } + + public Asn1Set AuthenticatedAttributes { get { return authenticatedAttributes; } } + + public AlgorithmIdentifier DigestAlgorithm { get { return digAlgorithm; } } + + public Asn1OctetString EncryptedDigest { get { return encryptedDigest; } } + + public AlgorithmIdentifier DigestEncryptionAlgorithm { get { return digEncryptionAlgorithm; } } + + public Asn1Set UnauthenticatedAttributes { get { return unauthenticatedAttributes; } } + + /** + * Produce an object suitable for an Asn1OutputStream. + * <pre> + * SignerInfo ::= Sequence { + * version Version, + * issuerAndSerialNumber IssuerAndSerialNumber, + * digestAlgorithm DigestAlgorithmIdentifier, + * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, + * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, + * encryptedDigest EncryptedDigest, + * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL + * } + * + * EncryptedDigest ::= OCTET STRING + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier + * </pre> + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + version, issuerAndSerialNumber, digAlgorithm); + + if (authenticatedAttributes != null) + { + v.Add(new DerTaggedObject(false, 0, authenticatedAttributes)); + } + + v.Add(digEncryptionAlgorithm, encryptedDigest); + + if (unauthenticatedAttributes != null) + { + v.Add(new DerTaggedObject(false, 1, unauthenticatedAttributes)); + } + + return new DerSequence(v); + } + } +} |