diff options
Diffstat (limited to 'core/src/main/java/org/bouncycastle/asn1/pkcs')
31 files changed, 3516 insertions, 0 deletions
diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java new file mode 100644 index 00000000..6374c980 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java @@ -0,0 +1,88 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.DERSequence; + +public class Attribute + extends ASN1Object +{ + private ASN1ObjectIdentifier attrType; + private ASN1Set attrValues; + + /** + * return an Attribute object from the given object. + * + * @param o the object we want converted. + * @exception IllegalArgumentException if the object cannot be converted. + */ + public static Attribute getInstance( + Object o) + { + if (o == null || o instanceof Attribute) + { + return (Attribute)o; + } + + if (o instanceof ASN1Sequence) + { + return new Attribute((ASN1Sequence)o); + } + + throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); + } + + public Attribute( + ASN1Sequence seq) + { + attrType = (ASN1ObjectIdentifier)seq.getObjectAt(0); + attrValues = (ASN1Set)seq.getObjectAt(1); + } + + public Attribute( + ASN1ObjectIdentifier attrType, + ASN1Set attrValues) + { + this.attrType = attrType; + this.attrValues = attrValues; + } + + public ASN1ObjectIdentifier getAttrType() + { + return attrType; + } + + public ASN1Set getAttrValues() + { + return attrValues; + } + + public ASN1Encodable[] getAttributeValues() + { + return attrValues.toArray(); + } + + /** + * Produce an object suitable for an ASN1OutputStream. + * <pre> + * Attribute ::= SEQUENCE { + * attrType OBJECT IDENTIFIER, + * attrValues SET OF AttributeValue + * } + * </pre> + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(attrType); + v.add(attrValues); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java new file mode 100644 index 00000000..ea4779bb --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java @@ -0,0 +1,74 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.BERSequence; +import org.bouncycastle.asn1.DLSequence; + +public class AuthenticatedSafe + extends ASN1Object +{ + private ContentInfo[] info; + private boolean isBer = true; + + private AuthenticatedSafe( + ASN1Sequence seq) + { + info = new ContentInfo[seq.size()]; + + for (int i = 0; i != info.length; i++) + { + info[i] = ContentInfo.getInstance(seq.getObjectAt(i)); + } + + isBer = seq instanceof BERSequence; + } + + public static AuthenticatedSafe getInstance( + Object o) + { + if (o instanceof AuthenticatedSafe) + { + return (AuthenticatedSafe)o; + } + + if (o != null) + { + return new AuthenticatedSafe(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public AuthenticatedSafe( + ContentInfo[] info) + { + this.info = info; + } + + public ContentInfo[] getContentInfo() + { + return info; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (int i = 0; i != info.length; i++) + { + v.add(info[i]); + } + + if (isBer) + { + return new BERSequence(v); + } + else + { + return new DLSequence(v); + } + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java new file mode 100644 index 00000000..b91c1a59 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java @@ -0,0 +1,82 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; + +public class CRLBag + extends ASN1Object +{ + private ASN1ObjectIdentifier crlId; + private ASN1Encodable crlValue; + + private CRLBag( + ASN1Sequence seq) + { + this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0); + this.crlValue = ((DERTaggedObject)seq.getObjectAt(1)).getObject(); + } + + public static CRLBag getInstance(Object o) + { + if (o instanceof CRLBag) + { + return (CRLBag)o; + } + else if (o != null) + { + return new CRLBag(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CRLBag( + ASN1ObjectIdentifier crlId, + ASN1Encodable crlValue) + { + this.crlId = crlId; + this.crlValue = crlValue; + } + + public ASN1ObjectIdentifier getcrlId() + { + return crlId; + } + + public ASN1Encodable getCRLValue() + { + return crlValue; + } + + /** + * <pre> + CRLBag ::= SEQUENCE { + crlId BAG-TYPE.&id ({CRLTypes}), + crlValue [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId}) + } + + x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1} + -- DER-encoded X.509 CRL stored in OCTET STRING + + CRLTypes BAG-TYPE ::= { + x509CRL, + ... -- For future extensions + } + </pre> + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(crlId); + v.add(new DERTaggedObject(0, crlValue)); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java new file mode 100644 index 00000000..4a730286 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java @@ -0,0 +1,66 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; + +public class CertBag + extends ASN1Object +{ + private ASN1ObjectIdentifier certId; + private ASN1Encodable certValue; + + private CertBag( + ASN1Sequence seq) + { + this.certId = (ASN1ObjectIdentifier)seq.getObjectAt(0); + this.certValue = ((DERTaggedObject)seq.getObjectAt(1)).getObject(); + } + + public static CertBag getInstance(Object o) + { + if (o instanceof CertBag) + { + return (CertBag)o; + } + else if (o != null) + { + return new CertBag(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CertBag( + ASN1ObjectIdentifier certId, + ASN1Encodable certValue) + { + this.certId = certId; + this.certValue = certValue; + } + + public ASN1ObjectIdentifier getCertId() + { + return certId; + } + + public ASN1Encodable getCertValue() + { + return certValue; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(certId); + v.add(new DERTaggedObject(0, certValue)); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java new file mode 100644 index 00000000..987d4eba --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java @@ -0,0 +1,91 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * PKCS10 Certification request object. + * <pre> + * CertificationRequest ::= SEQUENCE { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + * signature BIT STRING + * } + * </pre> + */ +public class CertificationRequest + extends ASN1Object +{ + protected CertificationRequestInfo reqInfo = null; + protected AlgorithmIdentifier sigAlgId = null; + protected DERBitString sigBits = null; + + public static CertificationRequest getInstance(Object o) + { + if (o instanceof CertificationRequest) + { + return (CertificationRequest)o; + } + + if (o != null) + { + return new CertificationRequest(ASN1Sequence.getInstance(o)); + } + + 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) + { + reqInfo = CertificationRequestInfo.getInstance(seq.getObjectAt(0)); + sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); + sigBits = (DERBitString)seq.getObjectAt(2); + } + + public CertificationRequestInfo getCertificationRequestInfo() + { + return reqInfo; + } + + public AlgorithmIdentifier getSignatureAlgorithm() + { + return sigAlgId; + } + + public DERBitString getSignature() + { + return sigBits; + } + + public ASN1Primitive toASN1Primitive() + { + // Construct the CertificateRequest + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(reqInfo); + v.add(sigAlgId); + v.add(sigBits); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java new file mode 100644 index 00000000..c9c14fe4 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java @@ -0,0 +1,164 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x509.X509Name; + +/** + * 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 Attribute{{ IOSet }} + * + * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { + * type ATTRIBUTE.&id({IOSet}), + * values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) + * } + * </pre> + */ +public class CertificationRequestInfo + extends ASN1Object +{ + ASN1Integer version = new ASN1Integer(0); + X500Name subject; + SubjectPublicKeyInfo subjectPKInfo; + ASN1Set attributes = null; + + public static CertificationRequestInfo getInstance( + Object obj) + { + if (obj instanceof CertificationRequestInfo) + { + return (CertificationRequestInfo)obj; + } + else if (obj != null) + { + return new CertificationRequestInfo(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + /** + * Basic constructor. + * <p> + * Note: Early on a lot of CAs would only accept messages with attributes missing. As the ASN.1 def shows + * the attributes field is not optional so should always at least contain an empty set. If a fully compliant + * request is required, pass in an empty set, the class will otherwise interpret a null as it should + * encode the request with the field missing. + * </p> + * + * @param subject subject to be associated with the public key + * @param pkInfo public key to be associated with subject + * @param attributes any attributes to be associated with the request. + */ + public CertificationRequestInfo( + X500Name subject, + SubjectPublicKeyInfo pkInfo, + ASN1Set attributes) + { + this.subject = subject; + this.subjectPKInfo = pkInfo; + this.attributes = attributes; + + if ((subject == null) || (version == null) || (subjectPKInfo == null)) + { + throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); + } + } + + /** + * @deprecated use X500Name method. + */ + public CertificationRequestInfo( + X509Name subject, + SubjectPublicKeyInfo pkInfo, + ASN1Set attributes) + { + this.subject = X500Name.getInstance(subject.toASN1Primitive()); + this.subjectPKInfo = pkInfo; + this.attributes = attributes; + + if ((subject == null) || (version == null) || (subjectPKInfo == null)) + { + throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); + } + } + + /** + * @deprecated use getInstance(). + */ + public CertificationRequestInfo( + ASN1Sequence seq) + { + version = (ASN1Integer)seq.getObjectAt(0); + + subject = X500Name.getInstance(seq.getObjectAt(1)); + subjectPKInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(2)); + + // + // some CertificationRequestInfo objects seem to treat this field + // as optional. + // + if (seq.size() > 3) + { + DERTaggedObject tagobj = (DERTaggedObject)seq.getObjectAt(3); + attributes = ASN1Set.getInstance(tagobj, false); + } + + if ((subject == null) || (version == null) || (subjectPKInfo == null)) + { + throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); + } + } + + public ASN1Integer getVersion() + { + return version; + } + + public X500Name getSubject() + { + return subject; + } + + public SubjectPublicKeyInfo getSubjectPublicKeyInfo() + { + return subjectPKInfo; + } + + public ASN1Set getAttributes() + { + return attributes; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(version); + v.add(subject); + v.add(subjectPKInfo); + + if (attributes != null) + { + v.add(new DERTaggedObject(false, 0, attributes)); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java new file mode 100644 index 00000000..1ee920fd --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java @@ -0,0 +1,102 @@ +package org.bouncycastle.asn1.pkcs; + +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERSequence; +import org.bouncycastle.asn1.BERTaggedObject; +import org.bouncycastle.asn1.DLSequence; + +public class ContentInfo + extends ASN1Object + implements PKCSObjectIdentifiers +{ + private ASN1ObjectIdentifier contentType; + private ASN1Encodable content; + private boolean isBer = true; + + public static ContentInfo getInstance( + Object obj) + { + if (obj instanceof ContentInfo) + { + return (ContentInfo)obj; + } + + if (obj != null) + { + return new ContentInfo(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private ContentInfo( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + contentType = (ASN1ObjectIdentifier)e.nextElement(); + + if (e.hasMoreElements()) + { + content = ((ASN1TaggedObject)e.nextElement()).getObject(); + } + + isBer = seq instanceof BERSequence; + } + + public ContentInfo( + ASN1ObjectIdentifier contentType, + ASN1Encodable content) + { + this.contentType = contentType; + this.content = content; + } + + public ASN1ObjectIdentifier getContentType() + { + return contentType; + } + + public ASN1Encodable getContent() + { + return content; + } + + /** + * Produce an object suitable for an ASN1OutputStream. + * <pre> + * ContentInfo ::= SEQUENCE { + * contentType ContentType, + * content + * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } + * </pre> + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(contentType); + + if (content != null) + { + v.add(new BERTaggedObject(true, 0, content)); + } + + if (isBer) + { + return new BERSequence(v); + } + else + { + return new DLSequence(v); + } + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java new file mode 100644 index 00000000..fa22f792 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java @@ -0,0 +1,104 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; + +public class DHParameter + extends ASN1Object +{ + ASN1Integer p, g, l; + + public DHParameter( + BigInteger p, + BigInteger g, + int l) + { + this.p = new ASN1Integer(p); + this.g = new ASN1Integer(g); + + if (l != 0) + { + this.l = new ASN1Integer(l); + } + else + { + this.l = null; + } + } + + public static DHParameter getInstance( + Object obj) + { + if (obj instanceof DHParameter) + { + return (DHParameter)obj; + } + + if (obj != null) + { + return new DHParameter(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private DHParameter( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + p = ASN1Integer.getInstance(e.nextElement()); + g = ASN1Integer.getInstance(e.nextElement()); + + if (e.hasMoreElements()) + { + l = (ASN1Integer)e.nextElement(); + } + else + { + l = null; + } + } + + public BigInteger getP() + { + return p.getPositiveValue(); + } + + public BigInteger getG() + { + return g.getPositiveValue(); + } + + public BigInteger getL() + { + if (l == null) + { + return null; + } + + return l.getPositiveValue(); + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(p); + v.add(g); + + if (this.getL() != null) + { + v.add(l); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java new file mode 100644 index 00000000..e0f5efdf --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java @@ -0,0 +1,115 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERSequence; +import org.bouncycastle.asn1.BERTaggedObject; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * 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 + extends ASN1Object +{ + ASN1Sequence data; + ASN1ObjectIdentifier bagId; + ASN1Primitive bagValue; + + public static EncryptedData getInstance( + Object obj) + { + if (obj instanceof EncryptedData) + { + return (EncryptedData)obj; + } + + if (obj != null) + { + return new EncryptedData(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private EncryptedData( + ASN1Sequence seq) + { + int version = ((ASN1Integer)seq.getObjectAt(0)).getValue().intValue(); + + if (version != 0) + { + throw new IllegalArgumentException("sequence not version 0"); + } + + this.data = ASN1Sequence.getInstance(seq.getObjectAt(1)); + } + + public EncryptedData( + ASN1ObjectIdentifier contentType, + AlgorithmIdentifier encryptionAlgorithm, + ASN1Encodable content) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(contentType); + v.add(encryptionAlgorithm.toASN1Primitive()); + v.add(new BERTaggedObject(false, 0, content)); + + data = new BERSequence(v); + } + + public ASN1ObjectIdentifier getContentType() + { + return ASN1ObjectIdentifier.getInstance(data.getObjectAt(0)); + } + + public AlgorithmIdentifier getEncryptionAlgorithm() + { + return AlgorithmIdentifier.getInstance(data.getObjectAt(1)); + } + + public ASN1OctetString getContent() + { + if (data.size() == 3) + { + ASN1TaggedObject o = ASN1TaggedObject.getInstance(data.getObjectAt(2)); + + return ASN1OctetString.getInstance(o, false); + } + + return null; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new ASN1Integer(0)); + v.add(data); + + return new BERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java new file mode 100644 index 00000000..acbe04a9 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java @@ -0,0 +1,86 @@ +package org.bouncycastle.asn1.pkcs; + +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +public class EncryptedPrivateKeyInfo + extends ASN1Object +{ + private AlgorithmIdentifier algId; + private ASN1OctetString data; + + private EncryptedPrivateKeyInfo( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + algId = AlgorithmIdentifier.getInstance(e.nextElement()); + data = ASN1OctetString.getInstance(e.nextElement()); + } + + public EncryptedPrivateKeyInfo( + AlgorithmIdentifier algId, + byte[] encoding) + { + this.algId = algId; + this.data = new DEROctetString(encoding); + } + + public static EncryptedPrivateKeyInfo getInstance( + Object obj) + { + if (obj instanceof EncryptedPrivateKeyInfo) + { + return (EncryptedPrivateKeyInfo)obj; + } + else if (obj != null) + { + return new EncryptedPrivateKeyInfo(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public AlgorithmIdentifier getEncryptionAlgorithm() + { + 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 ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(algId); + v.add(data); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptionScheme.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptionScheme.java new file mode 100644 index 00000000..c885a6c6 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptionScheme.java @@ -0,0 +1,56 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +public class EncryptionScheme + extends ASN1Object +{ + private AlgorithmIdentifier algId; + + public EncryptionScheme( + ASN1ObjectIdentifier objectId, + ASN1Encodable parameters) + { + this.algId = new AlgorithmIdentifier(objectId, parameters); + } + + private EncryptionScheme( + ASN1Sequence seq) + { + this.algId = AlgorithmIdentifier.getInstance(seq); + } + + public static final EncryptionScheme getInstance(Object obj) + { + if (obj instanceof EncryptionScheme) + { + return (EncryptionScheme)obj; + } + else if (obj != null) + { + return new EncryptionScheme(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public ASN1ObjectIdentifier getAlgorithm() + { + return algId.getAlgorithm(); + } + + public ASN1Encodable getParameters() + { + return algId.getParameters(); + } + + public ASN1Primitive toASN1Primitive() + { + return algId.toASN1Primitive(); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java new file mode 100644 index 00000000..6cbf907a --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java @@ -0,0 +1,85 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.X509Name; + +public class IssuerAndSerialNumber + extends ASN1Object +{ + X500Name name; + ASN1Integer certSerialNumber; + + public static IssuerAndSerialNumber getInstance( + Object obj) + { + if (obj instanceof IssuerAndSerialNumber) + { + return (IssuerAndSerialNumber)obj; + } + else if (obj != null) + { + return new IssuerAndSerialNumber(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private IssuerAndSerialNumber( + ASN1Sequence seq) + { + this.name = X500Name.getInstance(seq.getObjectAt(0)); + this.certSerialNumber = (ASN1Integer)seq.getObjectAt(1); + } + + public IssuerAndSerialNumber( + X509Name name, + BigInteger certSerialNumber) + { + this.name = X500Name.getInstance(name.toASN1Primitive()); + this.certSerialNumber = new ASN1Integer(certSerialNumber); + } + + public IssuerAndSerialNumber( + X509Name name, + ASN1Integer certSerialNumber) + { + this.name = X500Name.getInstance(name.toASN1Primitive()); + this.certSerialNumber = certSerialNumber; + } + + public IssuerAndSerialNumber( + X500Name name, + BigInteger certSerialNumber) + { + this.name = name; + this.certSerialNumber = new ASN1Integer(certSerialNumber); + } + + public X500Name getName() + { + return name; + } + + public ASN1Integer getCertificateSerialNumber() + { + return certSerialNumber; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(name); + v.add(certSerialNumber); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java new file mode 100644 index 00000000..3b408362 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java @@ -0,0 +1,56 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +public class KeyDerivationFunc + extends ASN1Object +{ + private AlgorithmIdentifier algId; + + public KeyDerivationFunc( + ASN1ObjectIdentifier objectId, + ASN1Encodable parameters) + { + this.algId = new AlgorithmIdentifier(objectId, parameters); + } + + private KeyDerivationFunc( + ASN1Sequence seq) + { + this.algId = AlgorithmIdentifier.getInstance(seq); + } + + public static final KeyDerivationFunc getInstance(Object obj) + { + if (obj instanceof KeyDerivationFunc) + { + return (KeyDerivationFunc)obj; + } + else if (obj != null) + { + return new KeyDerivationFunc(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public ASN1ObjectIdentifier getAlgorithm() + { + return algId.getAlgorithm(); + } + + public ASN1Encodable getParameters() + { + return algId.getParameters(); + } + + public ASN1Primitive toASN1Primitive() + { + return algId.toASN1Primitive(); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java new file mode 100644 index 00000000..1d8f582c --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java @@ -0,0 +1,106 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x509.DigestInfo; + +public class MacData + extends ASN1Object +{ + private static final BigInteger ONE = BigInteger.valueOf(1); + + DigestInfo digInfo; + byte[] salt; + BigInteger iterationCount; + + public static MacData getInstance( + Object obj) + { + if (obj instanceof MacData) + { + return (MacData)obj; + } + else if (obj != null) + { + return new MacData(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private MacData( + ASN1Sequence seq) + { + this.digInfo = DigestInfo.getInstance(seq.getObjectAt(0)); + + this.salt = ((ASN1OctetString)seq.getObjectAt(1)).getOctets(); + + if (seq.size() == 3) + { + this.iterationCount = ((ASN1Integer)seq.getObjectAt(2)).getValue(); + } + else + { + this.iterationCount = ONE; + } + } + + public MacData( + DigestInfo digInfo, + byte[] salt, + int iterationCount) + { + this.digInfo = digInfo; + this.salt = salt; + this.iterationCount = BigInteger.valueOf(iterationCount); + } + + public DigestInfo getMac() + { + return digInfo; + } + + public byte[] getSalt() + { + return salt; + } + + public BigInteger getIterationCount() + { + 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 ASN1Primitive construction. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(digInfo); + v.add(new DEROctetString(salt)); + + if (!iterationCount.equals(ONE)) + { + v.add(new ASN1Integer(iterationCount)); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java new file mode 100644 index 00000000..06180dfe --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java @@ -0,0 +1,73 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; + +public class PBEParameter + extends ASN1Object +{ + ASN1Integer iterations; + ASN1OctetString salt; + + public PBEParameter( + byte[] salt, + int iterations) + { + if (salt.length != 8) + { + throw new IllegalArgumentException("salt length must be 8"); + } + this.salt = new DEROctetString(salt); + this.iterations = new ASN1Integer(iterations); + } + + private PBEParameter( + ASN1Sequence seq) + { + salt = (ASN1OctetString)seq.getObjectAt(0); + iterations = (ASN1Integer)seq.getObjectAt(1); + } + + public static PBEParameter getInstance( + Object obj) + { + if (obj instanceof PBEParameter) + { + return (PBEParameter)obj; + } + else if (obj != null) + { + return new PBEParameter(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public BigInteger getIterationCount() + { + return iterations.getValue(); + } + + public byte[] getSalt() + { + return salt.getOctets(); + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(salt); + v.add(iterations); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java new file mode 100644 index 00000000..db44a82a --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java @@ -0,0 +1,77 @@ +package org.bouncycastle.asn1.pkcs; + +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * @deprecated - use AlgorithmIdentifier and PBES2Parameters + */ +public class PBES2Algorithms + extends AlgorithmIdentifier implements PKCSObjectIdentifiers +{ + private ASN1ObjectIdentifier objectId; + private KeyDerivationFunc func; + private EncryptionScheme scheme; + + public PBES2Algorithms( + ASN1Sequence obj) + { + super(obj); + + Enumeration e = obj.getObjects(); + + objectId = (ASN1ObjectIdentifier)e.nextElement(); + + ASN1Sequence seq = (ASN1Sequence)e.nextElement(); + + e = seq.getObjects(); + + ASN1Sequence funcSeq = (ASN1Sequence)e.nextElement(); + + if (funcSeq.getObjectAt(0).equals(id_PBKDF2)) + { + func = new KeyDerivationFunc(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1))); + } + else + { + func = KeyDerivationFunc.getInstance(funcSeq); + } + + scheme = EncryptionScheme.getInstance(e.nextElement()); + } + + public ASN1ObjectIdentifier getObjectId() + { + return objectId; + } + + public KeyDerivationFunc getKeyDerivationFunc() + { + return func; + } + + public EncryptionScheme getEncryptionScheme() + { + return scheme; + } + + public ASN1Primitive getASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector subV = new ASN1EncodableVector(); + + v.add(objectId); + + subV.add(func); + subV.add(scheme); + v.add(new DERSequence(subV)); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java new file mode 100644 index 00000000..b47e9cdd --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java @@ -0,0 +1,77 @@ +package org.bouncycastle.asn1.pkcs; + +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; + +public class PBES2Parameters + extends ASN1Object + implements PKCSObjectIdentifiers +{ + private KeyDerivationFunc func; + private EncryptionScheme scheme; + + public static PBES2Parameters getInstance( + Object obj) + { + if (obj instanceof PBES2Parameters) + { + return (PBES2Parameters)obj; + } + if (obj != null) + { + return new PBES2Parameters(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public PBES2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme) + { + this.func = keyDevFunc; + this.scheme = encScheme; + } + + private PBES2Parameters( + ASN1Sequence obj) + { + Enumeration e = obj.getObjects(); + ASN1Sequence funcSeq = ASN1Sequence.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive()); + + if (funcSeq.getObjectAt(0).equals(id_PBKDF2)) + { + func = new KeyDerivationFunc(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1))); + } + else + { + func = KeyDerivationFunc.getInstance(funcSeq); + } + + scheme = EncryptionScheme.getInstance(e.nextElement()); + } + + public KeyDerivationFunc getKeyDerivationFunc() + { + return func; + } + + public EncryptionScheme getEncryptionScheme() + { + return scheme; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(func); + v.add(scheme); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java new file mode 100644 index 00000000..65c0fa85 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java @@ -0,0 +1,108 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; + +public class PBKDF2Params + extends ASN1Object +{ + private ASN1OctetString octStr; + private ASN1Integer iterationCount; + private ASN1Integer keyLength; + + public static PBKDF2Params getInstance( + Object obj) + { + if (obj instanceof PBKDF2Params) + { + return (PBKDF2Params)obj; + } + + if (obj != null) + { + return new PBKDF2Params(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public PBKDF2Params( + byte[] salt, + int iterationCount) + { + this.octStr = new DEROctetString(salt); + this.iterationCount = new ASN1Integer(iterationCount); + } + + public PBKDF2Params( + byte[] salt, + int iterationCount, + int keyLength) + { + this(salt, iterationCount); + + this.keyLength = new ASN1Integer(keyLength); + } + + private PBKDF2Params( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + octStr = (ASN1OctetString)e.nextElement(); + iterationCount = (ASN1Integer)e.nextElement(); + + if (e.hasMoreElements()) + { + keyLength = (ASN1Integer)e.nextElement(); + } + else + { + keyLength = null; + } + } + + public byte[] getSalt() + { + return octStr.getOctets(); + } + + public BigInteger getIterationCount() + { + return iterationCount.getValue(); + } + + public BigInteger getKeyLength() + { + if (keyLength != null) + { + return keyLength.getValue(); + } + + return null; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(octStr); + v.add(iterationCount); + + if (keyLength != null) + { + v.add(keyLength); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java new file mode 100644 index 00000000..0ddf5c34 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java @@ -0,0 +1,69 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; + +public class PKCS12PBEParams + extends ASN1Object +{ + ASN1Integer iterations; + ASN1OctetString iv; + + public PKCS12PBEParams( + byte[] salt, + int iterations) + { + this.iv = new DEROctetString(salt); + this.iterations = new ASN1Integer(iterations); + } + + private PKCS12PBEParams( + ASN1Sequence seq) + { + iv = (ASN1OctetString)seq.getObjectAt(0); + iterations = ASN1Integer.getInstance(seq.getObjectAt(1)); + } + + public static PKCS12PBEParams getInstance( + Object obj) + { + if (obj instanceof PKCS12PBEParams) + { + return (PKCS12PBEParams)obj; + } + else if (obj != null) + { + return new PKCS12PBEParams(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public BigInteger getIterations() + { + return iterations.getValue(); + } + + public byte[] getIV() + { + return iv.getOctets(); + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(iv); + v.add(iterations); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java new file mode 100644 index 00000000..405d0b4a --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java @@ -0,0 +1,258 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public interface PKCSObjectIdentifiers +{ + // + // pkcs-1 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } + // + static final ASN1ObjectIdentifier pkcs_1 = new ASN1ObjectIdentifier("1.2.840.113549.1.1"); + static final ASN1ObjectIdentifier rsaEncryption = pkcs_1.branch("1"); + static final ASN1ObjectIdentifier md2WithRSAEncryption = pkcs_1.branch("2"); + static final ASN1ObjectIdentifier md4WithRSAEncryption = pkcs_1.branch("3"); + static final ASN1ObjectIdentifier md5WithRSAEncryption = pkcs_1.branch("4"); + static final ASN1ObjectIdentifier sha1WithRSAEncryption = pkcs_1.branch("5"); + static final ASN1ObjectIdentifier srsaOAEPEncryptionSET = pkcs_1.branch("6"); + static final ASN1ObjectIdentifier id_RSAES_OAEP = pkcs_1.branch("7"); + static final ASN1ObjectIdentifier id_mgf1 = pkcs_1.branch("8"); + static final ASN1ObjectIdentifier id_pSpecified = pkcs_1.branch("9"); + static final ASN1ObjectIdentifier id_RSASSA_PSS = pkcs_1.branch("10"); + static final ASN1ObjectIdentifier sha256WithRSAEncryption = pkcs_1.branch("11"); + static final ASN1ObjectIdentifier sha384WithRSAEncryption = pkcs_1.branch("12"); + static final ASN1ObjectIdentifier sha512WithRSAEncryption = pkcs_1.branch("13"); + static final ASN1ObjectIdentifier sha224WithRSAEncryption = pkcs_1.branch("14"); + + // + // pkcs-3 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 } + // + static final ASN1ObjectIdentifier pkcs_3 = new ASN1ObjectIdentifier("1.2.840.113549.1.3"); + static final ASN1ObjectIdentifier dhKeyAgreement = pkcs_3.branch("1"); + + // + // pkcs-5 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } + // + static final ASN1ObjectIdentifier pkcs_5 = new ASN1ObjectIdentifier("1.2.840.113549.1.5"); + + static final ASN1ObjectIdentifier pbeWithMD2AndDES_CBC = pkcs_5.branch("1"); + static final ASN1ObjectIdentifier pbeWithMD2AndRC2_CBC = pkcs_5.branch("4"); + static final ASN1ObjectIdentifier pbeWithMD5AndDES_CBC = pkcs_5.branch("3"); + static final ASN1ObjectIdentifier pbeWithMD5AndRC2_CBC = pkcs_5.branch("6"); + static final ASN1ObjectIdentifier pbeWithSHA1AndDES_CBC = pkcs_5.branch("10"); + static final ASN1ObjectIdentifier pbeWithSHA1AndRC2_CBC = pkcs_5.branch("11"); + + static final ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13"); + + static final ASN1ObjectIdentifier id_PBKDF2 = pkcs_5.branch("12"); + + // + // encryptionAlgorithm OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) 3 } + // + static final ASN1ObjectIdentifier encryptionAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.3"); + + static final ASN1ObjectIdentifier des_EDE3_CBC = encryptionAlgorithm.branch("7"); + static final ASN1ObjectIdentifier RC2_CBC = encryptionAlgorithm.branch("2"); + static final ASN1ObjectIdentifier rc4 = encryptionAlgorithm.branch("4"); + + // + // object identifiers for digests + // + static final ASN1ObjectIdentifier digestAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.2"); + // + // md2 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 2} + // + static final ASN1ObjectIdentifier md2 = digestAlgorithm.branch("2"); + + // + // md4 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 4} + // + static final ASN1ObjectIdentifier md4 = digestAlgorithm.branch("4"); + + // + // md5 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5} + // + static final ASN1ObjectIdentifier md5 = digestAlgorithm.branch("5"); + + static final ASN1ObjectIdentifier id_hmacWithSHA1 = digestAlgorithm.branch("7"); + static final ASN1ObjectIdentifier id_hmacWithSHA224 = digestAlgorithm.branch("8"); + static final ASN1ObjectIdentifier id_hmacWithSHA256 = digestAlgorithm.branch("9"); + static final ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10"); + static final ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11"); + + // + // pkcs-7 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } + // + static final String pkcs_7 = "1.2.840.113549.1.7"; + static final ASN1ObjectIdentifier data = new ASN1ObjectIdentifier(pkcs_7 + ".1"); + static final ASN1ObjectIdentifier signedData = new ASN1ObjectIdentifier(pkcs_7 + ".2"); + static final ASN1ObjectIdentifier envelopedData = new ASN1ObjectIdentifier(pkcs_7 + ".3"); + static final ASN1ObjectIdentifier signedAndEnvelopedData = new ASN1ObjectIdentifier(pkcs_7 + ".4"); + static final ASN1ObjectIdentifier digestedData = new ASN1ObjectIdentifier(pkcs_7 + ".5"); + static final ASN1ObjectIdentifier encryptedData = new ASN1ObjectIdentifier(pkcs_7 + ".6"); + + // + // pkcs-9 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } + // + static final ASN1ObjectIdentifier pkcs_9 = new ASN1ObjectIdentifier("1.2.840.113549.1.9"); + + static final ASN1ObjectIdentifier pkcs_9_at_emailAddress = pkcs_9.branch("1"); + static final ASN1ObjectIdentifier pkcs_9_at_unstructuredName = pkcs_9.branch("2"); + static final ASN1ObjectIdentifier pkcs_9_at_contentType = pkcs_9.branch("3"); + static final ASN1ObjectIdentifier pkcs_9_at_messageDigest = pkcs_9.branch("4"); + static final ASN1ObjectIdentifier pkcs_9_at_signingTime = pkcs_9.branch("5"); + static final ASN1ObjectIdentifier pkcs_9_at_counterSignature = pkcs_9.branch("6"); + static final ASN1ObjectIdentifier pkcs_9_at_challengePassword = pkcs_9.branch("7"); + static final ASN1ObjectIdentifier pkcs_9_at_unstructuredAddress = pkcs_9.branch("8"); + static final ASN1ObjectIdentifier pkcs_9_at_extendedCertificateAttributes = pkcs_9.branch("9"); + + static final ASN1ObjectIdentifier pkcs_9_at_signingDescription = pkcs_9.branch("13"); + static final ASN1ObjectIdentifier pkcs_9_at_extensionRequest = pkcs_9.branch("14"); + static final ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15"); + + static final ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20"); + static final ASN1ObjectIdentifier pkcs_9_at_localKeyId = pkcs_9.branch("21"); + + /** @deprecated use x509Certificate instead */ + static final ASN1ObjectIdentifier x509certType = pkcs_9.branch("22.1"); + + static final ASN1ObjectIdentifier certTypes = pkcs_9.branch("22"); + static final ASN1ObjectIdentifier x509Certificate = certTypes.branch("1"); + static final ASN1ObjectIdentifier sdsiCertificate = certTypes.branch("2"); + + static final ASN1ObjectIdentifier crlTypes = pkcs_9.branch("23"); + static final ASN1ObjectIdentifier x509Crl = crlTypes.branch("1"); + + static final ASN1ObjectIdentifier id_alg_PWRI_KEK = pkcs_9.branch("16.3.9"); + + // + // SMIME capability sub oids. + // + static final ASN1ObjectIdentifier preferSignedData = pkcs_9.branch("15.1"); + static final ASN1ObjectIdentifier canNotDecryptAny = pkcs_9.branch("15.2"); + static final ASN1ObjectIdentifier sMIMECapabilitiesVersions = pkcs_9.branch("15.3"); + + // + // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)} + // + static final ASN1ObjectIdentifier id_ct = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.1"); + + static final ASN1ObjectIdentifier id_ct_authData = id_ct.branch("2"); + static final ASN1ObjectIdentifier id_ct_TSTInfo = id_ct.branch("4"); + static final ASN1ObjectIdentifier id_ct_compressedData = id_ct.branch("9"); + static final ASN1ObjectIdentifier id_ct_authEnvelopedData = id_ct.branch("23"); + static final ASN1ObjectIdentifier id_ct_timestampedData = id_ct.branch("31"); + + // + // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)} + // + static final ASN1ObjectIdentifier id_cti = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.6"); + + static final ASN1ObjectIdentifier id_cti_ets_proofOfOrigin = id_cti.branch("1"); + static final ASN1ObjectIdentifier id_cti_ets_proofOfReceipt = id_cti.branch("2"); + static final ASN1ObjectIdentifier id_cti_ets_proofOfDelivery = id_cti.branch("3"); + static final ASN1ObjectIdentifier id_cti_ets_proofOfSender = id_cti.branch("4"); + static final ASN1ObjectIdentifier id_cti_ets_proofOfApproval = id_cti.branch("5"); + static final ASN1ObjectIdentifier id_cti_ets_proofOfCreation = id_cti.branch("6"); + + // + // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)} + // + static final ASN1ObjectIdentifier id_aa = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.2"); + + + static final ASN1ObjectIdentifier id_aa_receiptRequest = id_aa.branch("1"); + + static final ASN1ObjectIdentifier id_aa_contentHint = id_aa.branch("4"); // See RFC 2634 + static final ASN1ObjectIdentifier id_aa_msgSigDigest = id_aa.branch("5"); + static final ASN1ObjectIdentifier id_aa_contentReference = id_aa.branch("10"); + /* + * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11} + * + */ + static final ASN1ObjectIdentifier id_aa_encrypKeyPref = id_aa.branch("11"); + static final ASN1ObjectIdentifier id_aa_signingCertificate = id_aa.branch("12"); + static final ASN1ObjectIdentifier id_aa_signingCertificateV2 = id_aa.branch("47"); + + static final ASN1ObjectIdentifier id_aa_contentIdentifier = id_aa.branch("7"); // See RFC 2634 + + /* + * RFC 3126 + */ + static final ASN1ObjectIdentifier id_aa_signatureTimeStampToken = id_aa.branch("14"); + + static final ASN1ObjectIdentifier id_aa_ets_sigPolicyId = id_aa.branch("15"); + static final ASN1ObjectIdentifier id_aa_ets_commitmentType = id_aa.branch("16"); + static final ASN1ObjectIdentifier id_aa_ets_signerLocation = id_aa.branch("17"); + static final ASN1ObjectIdentifier id_aa_ets_signerAttr = id_aa.branch("18"); + static final ASN1ObjectIdentifier id_aa_ets_otherSigCert = id_aa.branch("19"); + static final ASN1ObjectIdentifier id_aa_ets_contentTimestamp = id_aa.branch("20"); + static final ASN1ObjectIdentifier id_aa_ets_certificateRefs = id_aa.branch("21"); + static final ASN1ObjectIdentifier id_aa_ets_revocationRefs = id_aa.branch("22"); + static final ASN1ObjectIdentifier id_aa_ets_certValues = id_aa.branch("23"); + static final ASN1ObjectIdentifier id_aa_ets_revocationValues = id_aa.branch("24"); + static final ASN1ObjectIdentifier id_aa_ets_escTimeStamp = id_aa.branch("25"); + static final ASN1ObjectIdentifier id_aa_ets_certCRLTimestamp = id_aa.branch("26"); + static final ASN1ObjectIdentifier id_aa_ets_archiveTimestamp = id_aa.branch("27"); + + /** @deprecated use id_aa_ets_sigPolicyId instead */ + static final ASN1ObjectIdentifier id_aa_sigPolicyId = id_aa_ets_sigPolicyId; + /** @deprecated use id_aa_ets_commitmentType instead */ + static final ASN1ObjectIdentifier id_aa_commitmentType = id_aa_ets_commitmentType; + /** @deprecated use id_aa_ets_signerLocation instead */ + static final ASN1ObjectIdentifier id_aa_signerLocation = id_aa_ets_signerLocation; + /** @deprecated use id_aa_ets_otherSigCert instead */ + static final ASN1ObjectIdentifier id_aa_otherSigCert = id_aa_ets_otherSigCert; + + // + // id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)} + // + final String id_spq = "1.2.840.113549.1.9.16.5"; + + static final ASN1ObjectIdentifier id_spq_ets_uri = new ASN1ObjectIdentifier(id_spq + ".1"); + static final ASN1ObjectIdentifier id_spq_ets_unotice = new ASN1ObjectIdentifier(id_spq + ".2"); + + // + // pkcs-12 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } + // + static final ASN1ObjectIdentifier pkcs_12 = new ASN1ObjectIdentifier("1.2.840.113549.1.12"); + static final ASN1ObjectIdentifier bagtypes = pkcs_12.branch("10.1"); + + static final ASN1ObjectIdentifier keyBag = bagtypes.branch("1"); + static final ASN1ObjectIdentifier pkcs8ShroudedKeyBag = bagtypes.branch("2"); + static final ASN1ObjectIdentifier certBag = bagtypes.branch("3"); + static final ASN1ObjectIdentifier crlBag = bagtypes.branch("4"); + static final ASN1ObjectIdentifier secretBag = bagtypes.branch("5"); + static final ASN1ObjectIdentifier safeContentsBag = bagtypes.branch("6"); + + static final ASN1ObjectIdentifier pkcs_12PbeIds = pkcs_12.branch("1"); + + static final ASN1ObjectIdentifier pbeWithSHAAnd128BitRC4 = pkcs_12PbeIds.branch("1"); + static final ASN1ObjectIdentifier pbeWithSHAAnd40BitRC4 = pkcs_12PbeIds.branch("2"); + static final ASN1ObjectIdentifier pbeWithSHAAnd3_KeyTripleDES_CBC = pkcs_12PbeIds.branch("3"); + static final ASN1ObjectIdentifier pbeWithSHAAnd2_KeyTripleDES_CBC = pkcs_12PbeIds.branch("4"); + static final ASN1ObjectIdentifier pbeWithSHAAnd128BitRC2_CBC = pkcs_12PbeIds.branch("5"); + static final ASN1ObjectIdentifier pbeWithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6"); + + /** + * @deprecated use pbeWithSHAAnd40BitRC2_CBC + */ + static final ASN1ObjectIdentifier pbewithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6"); + + static final ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6"); + static final ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7"); +} + diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java new file mode 100644 index 00000000..7885a795 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java @@ -0,0 +1,87 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.BERSequence; + +/** + * the infamous Pfx from PKCS12 + */ +public class Pfx + extends ASN1Object + implements PKCSObjectIdentifiers +{ + private ContentInfo contentInfo; + private MacData macData = null; + + private Pfx( + ASN1Sequence seq) + { + BigInteger version = ((ASN1Integer)seq.getObjectAt(0)).getValue(); + if (version.intValue() != 3) + { + throw new IllegalArgumentException("wrong version for PFX PDU"); + } + + contentInfo = ContentInfo.getInstance(seq.getObjectAt(1)); + + if (seq.size() == 3) + { + macData = MacData.getInstance(seq.getObjectAt(2)); + } + } + + public static Pfx getInstance( + Object obj) + { + if (obj instanceof Pfx) + { + return (Pfx)obj; + } + + if (obj != null) + { + return new Pfx(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public Pfx( + ContentInfo contentInfo, + MacData macData) + { + this.contentInfo = contentInfo; + this.macData = macData; + } + + public ContentInfo getAuthSafe() + { + return contentInfo; + } + + public MacData getMacData() + { + return macData; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new ASN1Integer(3)); + v.add(contentInfo); + + if (macData != null) + { + v.add(macData); + } + + return new BERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java new file mode 100644 index 00000000..dad86502 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java @@ -0,0 +1,164 @@ +package org.bouncycastle.asn1.pkcs; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +public class PrivateKeyInfo + extends ASN1Object +{ + private ASN1OctetString privKey; + private AlgorithmIdentifier algId; + private ASN1Set attributes; + + public static PrivateKeyInfo getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + return getInstance(ASN1Sequence.getInstance(obj, explicit)); + } + + public static PrivateKeyInfo getInstance( + Object obj) + { + if (obj instanceof PrivateKeyInfo) + { + return (PrivateKeyInfo)obj; + } + else if (obj != null) + { + return new PrivateKeyInfo(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public PrivateKeyInfo( + AlgorithmIdentifier algId, + ASN1Encodable privateKey) + throws IOException + { + this(algId, privateKey, null); + } + + public PrivateKeyInfo( + AlgorithmIdentifier algId, + ASN1Encodable privateKey, + ASN1Set attributes) + throws IOException + { + this.privKey = new DEROctetString(privateKey.toASN1Primitive().getEncoded(ASN1Encoding.DER)); + this.algId = algId; + this.attributes = attributes; + } + + /** + * @deprectaed use PrivateKeyInfo.getInstance() + * @param seq + */ + public PrivateKeyInfo( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + BigInteger version = ((ASN1Integer)e.nextElement()).getValue(); + if (version.intValue() != 0) + { + throw new IllegalArgumentException("wrong version for private key info"); + } + + algId = AlgorithmIdentifier.getInstance(e.nextElement()); + privKey = ASN1OctetString.getInstance(e.nextElement()); + + if (e.hasMoreElements()) + { + attributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); + } + } + + public AlgorithmIdentifier getPrivateKeyAlgorithm() + { + return algId; + } + /** + * @deprecated use getPrivateKeyAlgorithm() + */ + public AlgorithmIdentifier getAlgorithmId() + { + return algId; + } + + public ASN1Encodable parsePrivateKey() + throws IOException + { + return ASN1Primitive.fromByteArray(privKey.getOctets()); + } + + /** + * @deprecated use parsePrivateKey() + */ + public ASN1Primitive getPrivateKey() + { + try + { + return parsePrivateKey().toASN1Primitive(); + } + catch (IOException e) + { + throw new IllegalStateException("unable to parse private key"); + } + } + + public ASN1Set getAttributes() + { + 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 Attribute + * </pre> + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new ASN1Integer(0)); + v.add(algId); + v.add(privKey); + + if (attributes != null) + { + v.add(new DERTaggedObject(false, 0, attributes)); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java new file mode 100644 index 00000000..0a116f71 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java @@ -0,0 +1,93 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; + +public class RC2CBCParameter + extends ASN1Object +{ + ASN1Integer version; + ASN1OctetString iv; + + public static RC2CBCParameter getInstance( + Object o) + { + if (o instanceof RC2CBCParameter) + { + return (RC2CBCParameter)o; + } + if (o != null) + { + return new RC2CBCParameter(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public RC2CBCParameter( + byte[] iv) + { + this.version = null; + this.iv = new DEROctetString(iv); + } + + public RC2CBCParameter( + int parameterVersion, + byte[] iv) + { + this.version = new ASN1Integer(parameterVersion); + this.iv = new DEROctetString(iv); + } + + private RC2CBCParameter( + ASN1Sequence seq) + { + if (seq.size() == 1) + { + version = null; + iv = (ASN1OctetString)seq.getObjectAt(0); + } + else + { + version = (ASN1Integer)seq.getObjectAt(0); + iv = (ASN1OctetString)seq.getObjectAt(1); + } + } + + public BigInteger getRC2ParameterVersion() + { + if (version == null) + { + return null; + } + + return version.getValue(); + } + + public byte[] getIV() + { + return iv.getOctets(); + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + if (version != null) + { + v.add(version); + } + + v.add(iv); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java new file mode 100644 index 00000000..515b515a --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java @@ -0,0 +1,151 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +public class RSAESOAEPparams + extends ASN1Object +{ + private AlgorithmIdentifier hashAlgorithm; + private AlgorithmIdentifier maskGenAlgorithm; + private AlgorithmIdentifier pSourceAlgorithm; + + public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); + public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM); + public final static AlgorithmIdentifier DEFAULT_P_SOURCE_ALGORITHM = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])); + + public static RSAESOAEPparams getInstance( + Object obj) + { + if (obj instanceof RSAESOAEPparams) + { + return (RSAESOAEPparams)obj; + } + else if (obj != null) + { + return new RSAESOAEPparams(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + /** + * The default version + */ + public RSAESOAEPparams() + { + hashAlgorithm = DEFAULT_HASH_ALGORITHM; + maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; + pSourceAlgorithm = DEFAULT_P_SOURCE_ALGORITHM; + } + + public RSAESOAEPparams( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm, + AlgorithmIdentifier pSourceAlgorithm) + { + this.hashAlgorithm = hashAlgorithm; + this.maskGenAlgorithm = maskGenAlgorithm; + this.pSourceAlgorithm = pSourceAlgorithm; + } + + public RSAESOAEPparams( + ASN1Sequence seq) + { + hashAlgorithm = DEFAULT_HASH_ALGORITHM; + maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; + pSourceAlgorithm = DEFAULT_P_SOURCE_ALGORITHM; + + for (int i = 0; i != seq.size(); i++) + { + ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(i); + + switch (o.getTagNo()) + { + 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 IllegalArgumentException("unknown tag"); + } + } + } + + public AlgorithmIdentifier getHashAlgorithm() + { + return hashAlgorithm; + } + + public AlgorithmIdentifier getMaskGenAlgorithm() + { + return maskGenAlgorithm; + } + + public AlgorithmIdentifier getPSourceAlgorithm() + { + 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 ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM)) + { + v.add(new DERTaggedObject(true, 0, hashAlgorithm)); + } + + if (!maskGenAlgorithm.equals(DEFAULT_MASK_GEN_FUNCTION)) + { + v.add(new DERTaggedObject(true, 1, maskGenAlgorithm)); + } + + if (!pSourceAlgorithm.equals(DEFAULT_P_SOURCE_ALGORITHM)) + { + v.add(new DERTaggedObject(true, 2, pSourceAlgorithm)); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java new file mode 100644 index 00000000..36992cf5 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java @@ -0,0 +1,187 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERSequence; + +public class RSAPrivateKey + extends ASN1Object +{ + private BigInteger version; + private BigInteger modulus; + private BigInteger publicExponent; + private BigInteger privateExponent; + private BigInteger prime1; + private BigInteger prime2; + private BigInteger exponent1; + private BigInteger exponent2; + private BigInteger coefficient; + private ASN1Sequence otherPrimeInfos = null; + + public static RSAPrivateKey getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + return getInstance(ASN1Sequence.getInstance(obj, explicit)); + } + + public static RSAPrivateKey getInstance( + Object obj) + { + if (obj instanceof RSAPrivateKey) + { + return (RSAPrivateKey)obj; + } + + if (obj != null) + { + return new RSAPrivateKey(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public RSAPrivateKey( + BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger prime1, + BigInteger prime2, + BigInteger exponent1, + BigInteger exponent2, + BigInteger coefficient) + { + this.version = BigInteger.valueOf(0); + this.modulus = modulus; + this.publicExponent = publicExponent; + this.privateExponent = privateExponent; + this.prime1 = prime1; + this.prime2 = prime2; + this.exponent1 = exponent1; + this.exponent2 = exponent2; + this.coefficient = coefficient; + } + + private RSAPrivateKey( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + BigInteger v = ((ASN1Integer)e.nextElement()).getValue(); + if (v.intValue() != 0 && v.intValue() != 1) + { + throw new IllegalArgumentException("wrong version for RSA private key"); + } + + version = v; + modulus = ((ASN1Integer)e.nextElement()).getValue(); + publicExponent = ((ASN1Integer)e.nextElement()).getValue(); + privateExponent = ((ASN1Integer)e.nextElement()).getValue(); + prime1 = ((ASN1Integer)e.nextElement()).getValue(); + prime2 = ((ASN1Integer)e.nextElement()).getValue(); + exponent1 = ((ASN1Integer)e.nextElement()).getValue(); + exponent2 = ((ASN1Integer)e.nextElement()).getValue(); + coefficient = ((ASN1Integer)e.nextElement()).getValue(); + + if (e.hasMoreElements()) + { + otherPrimeInfos = (ASN1Sequence)e.nextElement(); + } + } + + public BigInteger getVersion() + { + return version; + } + + public BigInteger getModulus() + { + return modulus; + } + + public BigInteger getPublicExponent() + { + return publicExponent; + } + + public BigInteger getPrivateExponent() + { + return privateExponent; + } + + public BigInteger getPrime1() + { + return prime1; + } + + public BigInteger getPrime2() + { + return prime2; + } + + public BigInteger getExponent1() + { + return exponent1; + } + + public BigInteger getExponent2() + { + return exponent2; + } + + public BigInteger getCoefficient() + { + 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 + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + * + * Version ::= INTEGER { two-prime(0), multi(1) } + * (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --}) + * </pre> + * <p> + * This routine is written to output PKCS1 version 2.1, private keys. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new ASN1Integer(version)); // version + v.add(new ASN1Integer(getModulus())); + v.add(new ASN1Integer(getPublicExponent())); + v.add(new ASN1Integer(getPrivateExponent())); + v.add(new ASN1Integer(getPrime1())); + v.add(new ASN1Integer(getPrime2())); + v.add(new ASN1Integer(getExponent1())); + v.add(new ASN1Integer(getExponent2())); + v.add(new ASN1Integer(getCoefficient())); + + if (otherPrimeInfos != null) + { + v.add(otherPrimeInfos); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java new file mode 100644 index 00000000..5912d5ea --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java @@ -0,0 +1,189 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERSequence; + +/** + * @deprecated use RSAPrivateKey + */ +public class RSAPrivateKeyStructure + extends ASN1Object +{ + private int version; + private BigInteger modulus; + private BigInteger publicExponent; + private BigInteger privateExponent; + private BigInteger prime1; + private BigInteger prime2; + private BigInteger exponent1; + private BigInteger exponent2; + private BigInteger coefficient; + private ASN1Sequence otherPrimeInfos = null; + + public static RSAPrivateKeyStructure getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + return getInstance(ASN1Sequence.getInstance(obj, explicit)); + } + + public static RSAPrivateKeyStructure getInstance( + Object obj) + { + if (obj instanceof RSAPrivateKeyStructure) + { + return (RSAPrivateKeyStructure)obj; + } + else if (obj instanceof ASN1Sequence) + { + return new RSAPrivateKeyStructure((ASN1Sequence)obj); + } + + throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); + } + + public RSAPrivateKeyStructure( + BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger prime1, + BigInteger prime2, + BigInteger exponent1, + BigInteger exponent2, + BigInteger coefficient) + { + this.version = 0; + 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) + { + Enumeration e = seq.getObjects(); + + BigInteger v = ((ASN1Integer)e.nextElement()).getValue(); + if (v.intValue() != 0 && v.intValue() != 1) + { + throw new IllegalArgumentException("wrong version for RSA private key"); + } + + version = v.intValue(); + modulus = ((ASN1Integer)e.nextElement()).getValue(); + publicExponent = ((ASN1Integer)e.nextElement()).getValue(); + privateExponent = ((ASN1Integer)e.nextElement()).getValue(); + prime1 = ((ASN1Integer)e.nextElement()).getValue(); + prime2 = ((ASN1Integer)e.nextElement()).getValue(); + exponent1 = ((ASN1Integer)e.nextElement()).getValue(); + exponent2 = ((ASN1Integer)e.nextElement()).getValue(); + coefficient = ((ASN1Integer)e.nextElement()).getValue(); + + if (e.hasMoreElements()) + { + otherPrimeInfos = (ASN1Sequence)e.nextElement(); + } + } + + public int getVersion() + { + return version; + } + + public BigInteger getModulus() + { + return modulus; + } + + public BigInteger getPublicExponent() + { + return publicExponent; + } + + public BigInteger getPrivateExponent() + { + return privateExponent; + } + + public BigInteger getPrime1() + { + return prime1; + } + + public BigInteger getPrime2() + { + return prime2; + } + + public BigInteger getExponent1() + { + return exponent1; + } + + public BigInteger getExponent2() + { + return exponent2; + } + + public BigInteger getCoefficient() + { + 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 + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + * + * Version ::= INTEGER { two-prime(0), multi(1) } + * (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --}) + * </pre> + * <p> + * This routine is written to output PKCS1 version 2.1, private keys. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new ASN1Integer(version)); // version + v.add(new ASN1Integer(getModulus())); + v.add(new ASN1Integer(getPublicExponent())); + v.add(new ASN1Integer(getPrivateExponent())); + v.add(new ASN1Integer(getPrime1())); + v.add(new ASN1Integer(getPrime2())); + v.add(new ASN1Integer(getExponent1())); + v.add(new ASN1Integer(getExponent2())); + v.add(new ASN1Integer(getCoefficient())); + + if (otherPrimeInfos != null) + { + v.add(otherPrimeInfos); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java new file mode 100644 index 00000000..6c432985 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java @@ -0,0 +1,95 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERSequence; + +public class RSAPublicKey + extends ASN1Object +{ + private BigInteger modulus; + private BigInteger publicExponent; + + public static RSAPublicKey getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + return getInstance(ASN1Sequence.getInstance(obj, explicit)); + } + + public static RSAPublicKey getInstance( + Object obj) + { + if (obj instanceof RSAPublicKey) + { + return (RSAPublicKey)obj; + } + + if (obj != null) + { + return new RSAPublicKey(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + public RSAPublicKey( + BigInteger modulus, + BigInteger publicExponent) + { + this.modulus = modulus; + this.publicExponent = publicExponent; + } + + private RSAPublicKey( + ASN1Sequence seq) + { + if (seq.size() != 2) + { + throw new IllegalArgumentException("Bad sequence size: " + + seq.size()); + } + + Enumeration e = seq.getObjects(); + + modulus = ASN1Integer.getInstance(e.nextElement()).getPositiveValue(); + publicExponent = ASN1Integer.getInstance(e.nextElement()).getPositiveValue(); + } + + public BigInteger getModulus() + { + return modulus; + } + + public BigInteger getPublicExponent() + { + return publicExponent; + } + + /** + * This outputs the key in PKCS1v2 format. + * <pre> + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * } + * </pre> + * <p> + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new ASN1Integer(getModulus())); + v.add(new ASN1Integer(getPublicExponent())); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java new file mode 100644 index 00000000..dc91c9c1 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java @@ -0,0 +1,172 @@ +package org.bouncycastle.asn1.pkcs; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +public class RSASSAPSSparams + extends ASN1Object +{ + private AlgorithmIdentifier hashAlgorithm; + private AlgorithmIdentifier maskGenAlgorithm; + private ASN1Integer saltLength; + private ASN1Integer trailerField; + + public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); + public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM); + public final static ASN1Integer DEFAULT_SALT_LENGTH = new ASN1Integer(20); + public final static ASN1Integer DEFAULT_TRAILER_FIELD = new ASN1Integer(1); + + public static RSASSAPSSparams getInstance( + Object obj) + { + if (obj instanceof RSASSAPSSparams) + { + return (RSASSAPSSparams)obj; + } + else if (obj != null) + { + return new RSASSAPSSparams(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + /** + * The default version + */ + public RSASSAPSSparams() + { + hashAlgorithm = DEFAULT_HASH_ALGORITHM; + maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; + saltLength = DEFAULT_SALT_LENGTH; + trailerField = DEFAULT_TRAILER_FIELD; + } + + public RSASSAPSSparams( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm, + ASN1Integer saltLength, + ASN1Integer trailerField) + { + this.hashAlgorithm = hashAlgorithm; + this.maskGenAlgorithm = maskGenAlgorithm; + this.saltLength = saltLength; + this.trailerField = trailerField; + } + + private RSASSAPSSparams( + ASN1Sequence seq) + { + hashAlgorithm = DEFAULT_HASH_ALGORITHM; + maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION; + saltLength = DEFAULT_SALT_LENGTH; + trailerField = DEFAULT_TRAILER_FIELD; + + for (int i = 0; i != seq.size(); i++) + { + ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(i); + + switch (o.getTagNo()) + { + case 0: + hashAlgorithm = AlgorithmIdentifier.getInstance(o, true); + break; + case 1: + maskGenAlgorithm = AlgorithmIdentifier.getInstance(o, true); + break; + case 2: + saltLength = ASN1Integer.getInstance(o, true); + break; + case 3: + trailerField = ASN1Integer.getInstance(o, true); + break; + default: + throw new IllegalArgumentException("unknown tag"); + } + } + } + + public AlgorithmIdentifier getHashAlgorithm() + { + return hashAlgorithm; + } + + public AlgorithmIdentifier getMaskGenAlgorithm() + { + return maskGenAlgorithm; + } + + public BigInteger getSaltLength() + { + return saltLength.getValue(); + } + + public BigInteger getTrailerField() + { + return trailerField.getValue(); + } + + /** + * <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 ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM)) + { + v.add(new DERTaggedObject(true, 0, hashAlgorithm)); + } + + if (!maskGenAlgorithm.equals(DEFAULT_MASK_GEN_FUNCTION)) + { + v.add(new DERTaggedObject(true, 1, maskGenAlgorithm)); + } + + if (!saltLength.equals(DEFAULT_SALT_LENGTH)) + { + v.add(new DERTaggedObject(true, 2, saltLength)); + } + + if (!trailerField.equals(DEFAULT_TRAILER_FIELD)) + { + v.add(new DERTaggedObject(true, 3, trailerField)); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java new file mode 100644 index 00000000..00ca0a20 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java @@ -0,0 +1,96 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DLSequence; +import org.bouncycastle.asn1.DLTaggedObject; + +public class SafeBag + extends ASN1Object +{ + private ASN1ObjectIdentifier bagId; + private ASN1Encodable bagValue; + private ASN1Set bagAttributes; + + public SafeBag( + ASN1ObjectIdentifier oid, + ASN1Encodable obj) + { + this.bagId = oid; + this.bagValue = obj; + this.bagAttributes = null; + } + + public SafeBag( + ASN1ObjectIdentifier oid, + ASN1Encodable obj, + ASN1Set bagAttributes) + { + this.bagId = oid; + this.bagValue = obj; + this.bagAttributes = bagAttributes; + } + + public static SafeBag getInstance( + Object obj) + { + if (obj instanceof SafeBag) + { + return (SafeBag)obj; + } + + if (obj != null) + { + return new SafeBag(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private SafeBag( + ASN1Sequence seq) + { + this.bagId = (ASN1ObjectIdentifier)seq.getObjectAt(0); + this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject(); + if (seq.size() == 3) + { + this.bagAttributes = (ASN1Set)seq.getObjectAt(2); + } + } + + public ASN1ObjectIdentifier getBagId() + { + return bagId; + } + + public ASN1Encodable getBagValue() + { + return bagValue; + } + + public ASN1Set getBagAttributes() + { + return bagAttributes; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(bagId); + v.add(new DLTaggedObject(true, 0, bagValue)); + + if (bagAttributes != null) + { + v.add(bagAttributes); + } + + return new DLSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java new file mode 100644 index 00000000..3d3089bc --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java @@ -0,0 +1,167 @@ +package org.bouncycastle.asn1.pkcs; + +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERSequence; +import org.bouncycastle.asn1.DERTaggedObject; + +/** + * a PKCS#7 signed data object. + */ +public class SignedData + extends ASN1Object + implements PKCSObjectIdentifiers +{ + private ASN1Integer version; + private ASN1Set digestAlgorithms; + private ContentInfo contentInfo; + private ASN1Set certificates; + private ASN1Set crls; + private ASN1Set signerInfos; + + public static SignedData getInstance( + Object o) + { + if (o instanceof SignedData) + { + return (SignedData)o; + } + else if (o != null) + { + return new SignedData(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public SignedData( + ASN1Integer _version, + ASN1Set _digestAlgorithms, + ContentInfo _contentInfo, + ASN1Set _certificates, + ASN1Set _crls, + ASN1Set _signerInfos) + { + version = _version; + digestAlgorithms = _digestAlgorithms; + contentInfo = _contentInfo; + certificates = _certificates; + crls = _crls; + signerInfos = _signerInfos; + } + + public SignedData( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + version = (ASN1Integer)e.nextElement(); + digestAlgorithms = ((ASN1Set)e.nextElement()); + contentInfo = ContentInfo.getInstance(e.nextElement()); + + while (e.hasMoreElements()) + { + ASN1Primitive o = (ASN1Primitive)e.nextElement(); + + // + // 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 instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = (ASN1TaggedObject)o; + + switch (tagged.getTagNo()) + { + case 0: + certificates = ASN1Set.getInstance(tagged, false); + break; + case 1: + crls = ASN1Set.getInstance(tagged, false); + break; + default: + throw new IllegalArgumentException("unknown tag value " + tagged.getTagNo()); + } + } + else + { + signerInfos = (ASN1Set)o; + } + } + } + + public ASN1Integer getVersion() + { + return version; + } + + public ASN1Set getDigestAlgorithms() + { + return digestAlgorithms; + } + + public ContentInfo getContentInfo() + { + return contentInfo; + } + + public ASN1Set getCertificates() + { + return certificates; + } + + public ASN1Set getCRLs() + { + return crls; + } + + public ASN1Set getSignerInfos() + { + 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 ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(version); + v.add(digestAlgorithms); + v.add(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/core/src/main/java/org/bouncycastle/asn1/pkcs/SignerInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/SignerInfo.java new file mode 100644 index 00000000..ab5d78ab --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/SignerInfo.java @@ -0,0 +1,178 @@ +package org.bouncycastle.asn1.pkcs; + +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * a PKCS#7 signer info object. + */ +public class SignerInfo + extends ASN1Object +{ + private ASN1Integer version; + private IssuerAndSerialNumber issuerAndSerialNumber; + private AlgorithmIdentifier digAlgorithm; + private ASN1Set authenticatedAttributes; + private AlgorithmIdentifier digEncryptionAlgorithm; + private ASN1OctetString encryptedDigest; + private ASN1Set unauthenticatedAttributes; + + public static SignerInfo getInstance( + Object o) + { + if (o instanceof SignerInfo) + { + return (SignerInfo)o; + } + else if (o instanceof ASN1Sequence) + { + return new SignerInfo((ASN1Sequence)o); + } + + throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); + } + + public SignerInfo( + ASN1Integer 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) + { + Enumeration e = seq.getObjects(); + + version = (ASN1Integer)e.nextElement(); + issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(e.nextElement()); + digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); + + Object obj = e.nextElement(); + + if (obj instanceof ASN1TaggedObject) + { + authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false); + + digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); + } + else + { + authenticatedAttributes = null; + digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj); + } + + encryptedDigest = DEROctetString.getInstance(e.nextElement()); + + if (e.hasMoreElements()) + { + unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); + } + else + { + unauthenticatedAttributes = null; + } + } + + public ASN1Integer getVersion() + { + return version; + } + + public IssuerAndSerialNumber getIssuerAndSerialNumber() + { + return issuerAndSerialNumber; + } + + public ASN1Set getAuthenticatedAttributes() + { + return authenticatedAttributes; + } + + public AlgorithmIdentifier getDigestAlgorithm() + { + return digAlgorithm; + } + + public ASN1OctetString getEncryptedDigest() + { + return encryptedDigest; + } + + public AlgorithmIdentifier getDigestEncryptionAlgorithm() + { + return digEncryptionAlgorithm; + } + + public ASN1Set getUnauthenticatedAttributes() + { + 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 ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(version); + v.add(issuerAndSerialNumber); + v.add(digAlgorithm); + + if (authenticatedAttributes != null) + { + v.add(new DERTaggedObject(false, 0, authenticatedAttributes)); + } + + v.add(digEncryptionAlgorithm); + v.add(encryptedDigest); + + if (unauthenticatedAttributes != null) + { + v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes)); + } + + return new DERSequence(v); + } +} |