summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/asn1/cms
diff options
context:
space:
mode:
authorSergio Giro <sgiro@google.com>2016-02-01 14:37:23 +0000
committerSergio Giro <sgiro@google.com>2016-02-01 15:16:12 +0000
commit397d32894b89b506dc318e0f83446187c9b76ebe (patch)
tree8229ff72c8cbb06f49dce3a8382930919fa6fc2b /bcprov/src/main/java/org/bouncycastle/asn1/cms
parent9b30eb05e5be69d51881a0d1b31e503e97acd784 (diff)
parent6d876f3f0ae553704a1dcf7e89003fcf14717037 (diff)
downloadandroid_external_bouncycastle-397d32894b89b506dc318e0f83446187c9b76ebe.tar.gz
android_external_bouncycastle-397d32894b89b506dc318e0f83446187c9b76ebe.tar.bz2
android_external_bouncycastle-397d32894b89b506dc318e0f83446187c9b76ebe.zip
Merge remote-tracking branch 'aosp/upstream-master' into merge-152-from-upstream
As to set a common ancestor for future merges from aosp/upstream-master (when updating to new versions of bouncycastle). We'll override all the changes of this commit with patch https://android-review.googlesource.com/#/c/199872 Change-Id: I53a7f797b520a6e119878dbae53246cdcc585ddf
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/asn1/cms')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java248
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java157
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java312
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedDataParser.java206
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java102
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java117
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedDataParser.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfoParser.java48
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java128
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java120
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java53
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java112
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java215
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java120
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/Evidence.java80
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java151
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java133
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java116
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java166
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java127
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/MetaData.java135
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java179
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java159
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java114
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java96
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java112
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java109
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java157
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java109
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java111
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java173
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java171
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java108
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedDataParser.java141
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java96
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampTokenEvidence.java98
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java131
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedDataParser.java141
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/MQVuserKeyingMaterial.java122
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/package.html5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/package.html5
42 files changed, 5233 insertions, 3 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java
new file mode 100644
index 0000000..034753f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java
@@ -0,0 +1,248 @@
+package org.bouncycastle.asn1.cms;
+
+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.BERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5083">RFC 5083</a>:
+ *
+ * CMS AuthEnveloped Data object.
+ * <p>
+ * ASN.1:
+ * <pre>
+ * id-ct-authEnvelopedData OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
+ * smime(16) ct(1) 23 }
+ *
+ * AuthEnvelopedData ::= SEQUENCE {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * authEncryptedContentInfo EncryptedContentInfo,
+ * authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
+ * mac MessageAuthenticationCode,
+ * unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
+ * </pre>
+ */
+public class AuthEnvelopedData
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private OriginatorInfo originatorInfo;
+ private ASN1Set recipientInfos;
+ private EncryptedContentInfo authEncryptedContentInfo;
+ private ASN1Set authAttrs;
+ private ASN1OctetString mac;
+ private ASN1Set unauthAttrs;
+
+ public AuthEnvelopedData(
+ OriginatorInfo originatorInfo,
+ ASN1Set recipientInfos,
+ EncryptedContentInfo authEncryptedContentInfo,
+ ASN1Set authAttrs,
+ ASN1OctetString mac,
+ ASN1Set unauthAttrs)
+ {
+ // "It MUST be set to 0."
+ this.version = new ASN1Integer(0);
+
+ this.originatorInfo = originatorInfo;
+
+ // TODO
+ // "There MUST be at least one element in the collection."
+ this.recipientInfos = recipientInfos;
+
+ this.authEncryptedContentInfo = authEncryptedContentInfo;
+
+ // TODO
+ // "The authAttrs MUST be present if the content type carried in
+ // EncryptedContentInfo is not id-data."
+ this.authAttrs = authAttrs;
+
+ this.mac = mac;
+
+ this.unauthAttrs = unauthAttrs;
+ }
+
+ /**
+ * Constructs AuthEnvelopedData by parsing supplied ASN1Sequence
+ * <p>
+ * @param seq An ASN1Sequence with AuthEnvelopedData
+ * @deprecated use getInstance().
+ */
+ public AuthEnvelopedData(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ // TODO
+ // "It MUST be set to 0."
+ ASN1Primitive tmp = seq.getObjectAt(index++).toASN1Primitive();
+ version = (ASN1Integer)tmp;
+
+ tmp = seq.getObjectAt(index++).toASN1Primitive();
+ if (tmp instanceof ASN1TaggedObject)
+ {
+ originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
+ tmp = seq.getObjectAt(index++).toASN1Primitive();
+ }
+
+ // TODO
+ // "There MUST be at least one element in the collection."
+ recipientInfos = ASN1Set.getInstance(tmp);
+
+ tmp = seq.getObjectAt(index++).toASN1Primitive();
+ authEncryptedContentInfo = EncryptedContentInfo.getInstance(tmp);
+
+ tmp = seq.getObjectAt(index++).toASN1Primitive();
+ if (tmp instanceof ASN1TaggedObject)
+ {
+ authAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false);
+ tmp = seq.getObjectAt(index++).toASN1Primitive();
+ }
+ else
+ {
+ // TODO
+ // "The authAttrs MUST be present if the content type carried in
+ // EncryptedContentInfo is not id-data."
+ }
+
+ mac = ASN1OctetString.getInstance(tmp);
+
+ if (seq.size() > index)
+ {
+ tmp = seq.getObjectAt(index++).toASN1Primitive();
+ unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false);
+ }
+ }
+
+ /**
+ * Return an AuthEnvelopedData object from a tagged object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats
+ * </ul>
+ *
+
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @throws IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static AuthEnvelopedData getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an AuthEnvelopedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link AuthEnvelopedData} object
+ * <li> {@link ASN1Sequence org.bouncycastle.asn1.ASN1Sequence} input formats with AuthEnvelopedData structure inside
+ * </ul>
+ *
+ * @param obj The object we want converted.
+ * @throws IllegalArgumentException if the object cannot be converted, or was null.
+ */
+ public static AuthEnvelopedData getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof AuthEnvelopedData)
+ {
+ return (AuthEnvelopedData)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new AuthEnvelopedData((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid AuthEnvelopedData: " + obj.getClass().getName());
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public OriginatorInfo getOriginatorInfo()
+ {
+ return originatorInfo;
+ }
+
+ public ASN1Set getRecipientInfos()
+ {
+ return recipientInfos;
+ }
+
+ public EncryptedContentInfo getAuthEncryptedContentInfo()
+ {
+ return authEncryptedContentInfo;
+ }
+
+ public ASN1Set getAuthAttrs()
+ {
+ return authAttrs;
+ }
+
+ public ASN1OctetString getMac()
+ {
+ return mac;
+ }
+
+ public ASN1Set getUnauthAttrs()
+ {
+ return unauthAttrs;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+
+ if (originatorInfo != null)
+ {
+ v.add(new DERTaggedObject(false, 0, originatorInfo));
+ }
+
+ v.add(recipientInfos);
+ v.add(authEncryptedContentInfo);
+
+ // "authAttrs optionally contains the authenticated attributes."
+ if (authAttrs != null)
+ {
+ // "AuthAttributes MUST be DER encoded, even if the rest of the
+ // AuthEnvelopedData structure is BER encoded."
+ v.add(new DERTaggedObject(false, 1, authAttrs));
+ }
+
+ v.add(mac);
+
+ // "unauthAttrs optionally contains the unauthenticated attributes."
+ if (unauthAttrs != null)
+ {
+ v.add(new DERTaggedObject(false, 2, unauthAttrs));
+ }
+
+ return new BERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java
new file mode 100644
index 0000000..8460c33
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java
@@ -0,0 +1,157 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.ASN1SetParser;
+import org.bouncycastle.asn1.ASN1TaggedObjectParser;
+import org.bouncycastle.asn1.BERTags;
+
+/**
+ * Parse {@link AuthEnvelopedData} input stream.
+ *
+ * <pre>
+ * AuthEnvelopedData ::= SEQUENCE {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * authEncryptedContentInfo EncryptedContentInfo,
+ * authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
+ * mac MessageAuthenticationCode,
+ * unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
+ * </pre>
+ */
+public class AuthEnvelopedDataParser
+{
+ private ASN1SequenceParser seq;
+ private ASN1Integer version;
+ private ASN1Encodable nextObject;
+ private boolean originatorInfoCalled;
+
+ public AuthEnvelopedDataParser(ASN1SequenceParser seq) throws IOException
+ {
+ this.seq = seq;
+
+ // TODO
+ // "It MUST be set to 0."
+ this.version = ASN1Integer.getInstance(seq.readObject());
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public OriginatorInfo getOriginatorInfo()
+ throws IOException
+ {
+ originatorInfoCalled = true;
+
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)nextObject).getTagNo() == 0)
+ {
+ ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)nextObject).getObjectParser(BERTags.SEQUENCE, false);
+ nextObject = null;
+ return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive());
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getRecipientInfos()
+ throws IOException
+ {
+ if (!originatorInfoCalled)
+ {
+ getOriginatorInfo();
+ }
+
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ ASN1SetParser recipientInfos = (ASN1SetParser)nextObject;
+ nextObject = null;
+ return recipientInfos;
+ }
+
+ public EncryptedContentInfoParser getAuthEncryptedContentInfo()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject != null)
+ {
+ ASN1SequenceParser o = (ASN1SequenceParser) nextObject;
+ nextObject = null;
+ return new EncryptedContentInfoParser(o);
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getAuthAttrs()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject instanceof ASN1TaggedObjectParser)
+ {
+ ASN1Encodable o = nextObject;
+ nextObject = null;
+ return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
+ }
+
+ // TODO
+ // "The authAttrs MUST be present if the content type carried in
+ // EncryptedContentInfo is not id-data."
+
+ return null;
+ }
+
+ public ASN1OctetString getMac()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ ASN1Encodable o = nextObject;
+ nextObject = null;
+
+ return ASN1OctetString.getInstance(o.toASN1Primitive());
+ }
+
+ public ASN1SetParser getUnauthAttrs()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject != null)
+ {
+ ASN1Encodable o = nextObject;
+ nextObject = null;
+ return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
+ }
+
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java
new file mode 100644
index 0000000..c0945f3
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java
@@ -0,0 +1,312 @@
+package org.bouncycastle.asn1.cms;
+
+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.BERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-9.1">RFC 5652</a> section 9.1:
+ * The AuthenticatedData carries AuthAttributes and other data
+ * which define what really is being signed.
+ * <p>
+ * <pre>
+ * AuthenticatedData ::= SEQUENCE {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * macAlgorithm MessageAuthenticationCodeAlgorithm,
+ * digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+ * encapContentInfo EncapsulatedContentInfo,
+ * authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
+ * mac MessageAuthenticationCode,
+ * unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
+ *
+ * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ *
+ * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ *
+ * MessageAuthenticationCode ::= OCTET STRING
+ * </pre>
+ */
+public class AuthenticatedData
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private OriginatorInfo originatorInfo;
+ private ASN1Set recipientInfos;
+ private AlgorithmIdentifier macAlgorithm;
+ private AlgorithmIdentifier digestAlgorithm;
+ private ContentInfo encapsulatedContentInfo;
+ private ASN1Set authAttrs;
+ private ASN1OctetString mac;
+ private ASN1Set unauthAttrs;
+
+ public AuthenticatedData(
+ OriginatorInfo originatorInfo,
+ ASN1Set recipientInfos,
+ AlgorithmIdentifier macAlgorithm,
+ AlgorithmIdentifier digestAlgorithm,
+ ContentInfo encapsulatedContent,
+ ASN1Set authAttrs,
+ ASN1OctetString mac,
+ ASN1Set unauthAttrs)
+ {
+ if (digestAlgorithm != null || authAttrs != null)
+ {
+ if (digestAlgorithm == null || authAttrs == null)
+ {
+ throw new IllegalArgumentException("digestAlgorithm and authAttrs must be set together");
+ }
+ }
+
+ version = new ASN1Integer(calculateVersion(originatorInfo));
+
+ this.originatorInfo = originatorInfo;
+ this.macAlgorithm = macAlgorithm;
+ this.digestAlgorithm = digestAlgorithm;
+ this.recipientInfos = recipientInfos;
+ this.encapsulatedContentInfo = encapsulatedContent;
+ this.authAttrs = authAttrs;
+ this.mac = mac;
+ this.unauthAttrs = unauthAttrs;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public AuthenticatedData(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ version = (ASN1Integer)seq.getObjectAt(index++);
+
+ Object tmp = seq.getObjectAt(index++);
+
+ if (tmp instanceof ASN1TaggedObject)
+ {
+ originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
+ tmp = seq.getObjectAt(index++);
+ }
+
+ recipientInfos = ASN1Set.getInstance(tmp);
+ macAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++));
+
+ tmp = seq.getObjectAt(index++);
+
+ if (tmp instanceof ASN1TaggedObject)
+ {
+ digestAlgorithm = AlgorithmIdentifier.getInstance((ASN1TaggedObject)tmp, false);
+ tmp = seq.getObjectAt(index++);
+ }
+
+ encapsulatedContentInfo = ContentInfo.getInstance(tmp);
+
+ tmp = seq.getObjectAt(index++);
+
+ if (tmp instanceof ASN1TaggedObject)
+ {
+ authAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false);
+ tmp = seq.getObjectAt(index++);
+ }
+
+ mac = ASN1OctetString.getInstance(tmp);
+
+ if (seq.size() > index)
+ {
+ unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
+ }
+ }
+
+ /**
+ * Return an AuthenticatedData object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @throws IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static AuthenticatedData getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an AuthenticatedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link AuthenticatedData} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with AuthenticatedData structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @throws IllegalArgumentException if the object cannot be converted.
+ */
+ public static AuthenticatedData getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof AuthenticatedData)
+ {
+ return (AuthenticatedData)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new AuthenticatedData((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid AuthenticatedData: " + obj.getClass().getName());
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public OriginatorInfo getOriginatorInfo()
+ {
+ return originatorInfo;
+ }
+
+ public ASN1Set getRecipientInfos()
+ {
+ return recipientInfos;
+ }
+
+ public AlgorithmIdentifier getMacAlgorithm()
+ {
+ return macAlgorithm;
+ }
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ return digestAlgorithm;
+ }
+
+ public ContentInfo getEncapsulatedContentInfo()
+ {
+ return encapsulatedContentInfo;
+ }
+
+ public ASN1Set getAuthAttrs()
+ {
+ return authAttrs;
+ }
+
+ public ASN1OctetString getMac()
+ {
+ return mac;
+ }
+
+ public ASN1Set getUnauthAttrs()
+ {
+ return unauthAttrs;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+
+ if (originatorInfo != null)
+ {
+ v.add(new DERTaggedObject(false, 0, originatorInfo));
+ }
+
+ v.add(recipientInfos);
+ v.add(macAlgorithm);
+
+ if (digestAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 1, digestAlgorithm));
+ }
+
+ v.add(encapsulatedContentInfo);
+
+ if (authAttrs != null)
+ {
+ v.add(new DERTaggedObject(false, 2, authAttrs));
+ }
+
+ v.add(mac);
+
+ if (unauthAttrs != null)
+ {
+ v.add(new DERTaggedObject(false, 3, unauthAttrs));
+ }
+
+ return new BERSequence(v);
+ }
+
+ public static int calculateVersion(OriginatorInfo origInfo)
+ {
+ if (origInfo == null)
+ {
+ return 0;
+ }
+ else
+ {
+ int ver = 0;
+
+ for (Enumeration e = origInfo.getCertificates().getObjects(); e.hasMoreElements();)
+ {
+ Object obj = e.nextElement();
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tag = (ASN1TaggedObject)obj;
+
+ if (tag.getTagNo() == 2)
+ {
+ ver = 1;
+ }
+ else if (tag.getTagNo() == 3)
+ {
+ ver = 3;
+ break;
+ }
+ }
+ }
+
+ if (origInfo.getCRLs() != null)
+ {
+ for (Enumeration e = origInfo.getCRLs().getObjects(); e.hasMoreElements();)
+ {
+ Object obj = e.nextElement();
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tag = (ASN1TaggedObject)obj;
+
+ if (tag.getTagNo() == 1)
+ {
+ ver = 3;
+ break;
+ }
+ }
+ }
+ }
+
+ return ver;
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedDataParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedDataParser.java
new file mode 100644
index 0000000..ce9aa4f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedDataParser.java
@@ -0,0 +1,206 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.ASN1SetParser;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.ASN1TaggedObjectParser;
+import org.bouncycastle.asn1.BERTags;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Parse {@link AuthenticatedData} stream.
+ * <pre>
+ * AuthenticatedData ::= SEQUENCE {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * macAlgorithm MessageAuthenticationCodeAlgorithm,
+ * digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+ * encapContentInfo EncapsulatedContentInfo,
+ * authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
+ * mac MessageAuthenticationCode,
+ * unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
+ *
+ * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ *
+ * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ *
+ * MessageAuthenticationCode ::= OCTET STRING
+ * </pre>
+ */
+public class AuthenticatedDataParser
+{
+ private ASN1SequenceParser seq;
+ private ASN1Integer version;
+ private ASN1Encodable nextObject;
+ private boolean originatorInfoCalled;
+
+ public AuthenticatedDataParser(
+ ASN1SequenceParser seq)
+ throws IOException
+ {
+ this.seq = seq;
+ this.version = ASN1Integer.getInstance(seq.readObject());
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public OriginatorInfo getOriginatorInfo()
+ throws IOException
+ {
+ originatorInfoCalled = true;
+
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)nextObject).getTagNo() == 0)
+ {
+ ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)nextObject).getObjectParser(BERTags.SEQUENCE, false);
+ nextObject = null;
+ return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive());
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getRecipientInfos()
+ throws IOException
+ {
+ if (!originatorInfoCalled)
+ {
+ getOriginatorInfo();
+ }
+
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ ASN1SetParser recipientInfos = (ASN1SetParser)nextObject;
+ nextObject = null;
+ return recipientInfos;
+ }
+
+ public AlgorithmIdentifier getMacAlgorithm()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject != null)
+ {
+ ASN1SequenceParser o = (ASN1SequenceParser)nextObject;
+ nextObject = null;
+ return AlgorithmIdentifier.getInstance(o.toASN1Primitive());
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject instanceof ASN1TaggedObjectParser)
+ {
+ AlgorithmIdentifier obj = AlgorithmIdentifier.getInstance((ASN1TaggedObject)nextObject.toASN1Primitive(), false);
+ nextObject = null;
+ return obj;
+ }
+
+ return null;
+ }
+
+ /**
+ * @deprecated use getEncapsulatedContentInfo()
+ */
+ public ContentInfoParser getEnapsulatedContentInfo()
+ throws IOException
+ {
+ return getEncapsulatedContentInfo();
+ }
+
+ public ContentInfoParser getEncapsulatedContentInfo()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject != null)
+ {
+ ASN1SequenceParser o = (ASN1SequenceParser)nextObject;
+ nextObject = null;
+ return new ContentInfoParser(o);
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getAuthAttrs()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject instanceof ASN1TaggedObjectParser)
+ {
+ ASN1Encodable o = nextObject;
+ nextObject = null;
+ return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
+ }
+
+ return null;
+ }
+
+ public ASN1OctetString getMac()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ ASN1Encodable o = nextObject;
+ nextObject = null;
+
+ return ASN1OctetString.getInstance(o.toASN1Primitive());
+ }
+
+ public ASN1SetParser getUnauthAttrs()
+ throws IOException
+ {
+ if (nextObject == null)
+ {
+ nextObject = seq.readObject();
+ }
+
+ if (nextObject != null)
+ {
+ ASN1Encodable o = nextObject;
+ nextObject = null;
+ return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
+ }
+
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java
new file mode 100644
index 0000000..3277bb2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java
@@ -0,0 +1,102 @@
+package org.bouncycastle.asn1.cms;
+
+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.util.Arrays;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5084">RFC 5084</a>: CCMParameters object.
+ * <p>
+ * <pre>
+ CCMParameters ::= SEQUENCE {
+ aes-nonce OCTET STRING, -- recommended size is 12 octets
+ aes-ICVlen AES-CCM-ICVlen DEFAULT 12 }
+ * </pre>
+ */
+public class CCMParameters
+ extends ASN1Object
+{
+ private byte[] nonce;
+ private int icvLen;
+
+ /**
+ * Return an CCMParameters object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link org.bouncycastle.asn1.cms.CCMParameters} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with CCMParameters structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static CCMParameters getInstance(
+ Object obj)
+ {
+ if (obj instanceof CCMParameters)
+ {
+ return (CCMParameters)obj;
+ }
+ else if (obj != null)
+ {
+ return new CCMParameters(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private CCMParameters(
+ ASN1Sequence seq)
+ {
+ this.nonce = ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets();
+
+ if (seq.size() == 2)
+ {
+ this.icvLen = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue().intValue();
+ }
+ else
+ {
+ this.icvLen = 12;
+ }
+ }
+
+ public CCMParameters(
+ byte[] nonce,
+ int icvLen)
+ {
+ this.nonce = Arrays.clone(nonce);
+ this.icvLen = icvLen;
+ }
+
+ public byte[] getNonce()
+ {
+ return Arrays.clone(nonce);
+ }
+
+ public int getIcvLen()
+ {
+ return icvLen;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(new DEROctetString(nonce));
+
+ if (icvLen != 12)
+ {
+ v.add(new ASN1Integer(icvLen));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java
new file mode 100644
index 0000000..e546470
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java
@@ -0,0 +1,117 @@
+package org.bouncycastle.asn1.cms;
+
+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.BERSequence;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc3274">RFC 3274</a>: CMS Compressed Data.
+ *
+ * <pre>
+ * CompressedData ::= SEQUENCE {
+ * version CMSVersion,
+ * compressionAlgorithm CompressionAlgorithmIdentifier,
+ * encapContentInfo EncapsulatedContentInfo
+ * }
+ * </pre>
+ */
+public class CompressedData
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private AlgorithmIdentifier compressionAlgorithm;
+ private ContentInfo encapContentInfo;
+
+ public CompressedData(
+ AlgorithmIdentifier compressionAlgorithm,
+ ContentInfo encapContentInfo)
+ {
+ this.version = new ASN1Integer(0);
+ this.compressionAlgorithm = compressionAlgorithm;
+ this.encapContentInfo = encapContentInfo;
+ }
+
+ private CompressedData(
+ ASN1Sequence seq)
+ {
+ this.version = (ASN1Integer)seq.getObjectAt(0);
+ this.compressionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ this.encapContentInfo = ContentInfo.getInstance(seq.getObjectAt(2));
+ }
+
+ /**
+ * Return a CompressedData object from a tagged object.
+ *
+ * @param ato the tagged object holding the object we want.
+ * @param isExplicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static CompressedData getInstance(
+ ASN1TaggedObject ato,
+ boolean isExplicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(ato, isExplicit));
+ }
+
+ /**
+ * Return a CompressedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link CompressedData} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with CompressedData structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static CompressedData getInstance(
+ Object obj)
+ {
+ if (obj instanceof CompressedData)
+ {
+ return (CompressedData)obj;
+ }
+
+ if (obj != null)
+ {
+ return new CompressedData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public AlgorithmIdentifier getCompressionAlgorithmIdentifier()
+ {
+ return compressionAlgorithm;
+ }
+
+ public ContentInfo getEncapContentInfo()
+ {
+ return encapContentInfo;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+ v.add(compressionAlgorithm);
+ v.add(encapContentInfo);
+
+ return new BERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedDataParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedDataParser.java
new file mode 100644
index 0000000..41895ce
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CompressedDataParser.java
@@ -0,0 +1,49 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Parser of <a href="http://tools.ietf.org/html/rfc3274">RFC 3274</a> {@link CompressedData} object.
+ * <p>
+ * <pre>
+ * CompressedData ::= SEQUENCE {
+ * version CMSVersion,
+ * compressionAlgorithm CompressionAlgorithmIdentifier,
+ * encapContentInfo EncapsulatedContentInfo
+ * }
+ * </pre>
+ */
+public class CompressedDataParser
+{
+ private ASN1Integer _version;
+ private AlgorithmIdentifier _compressionAlgorithm;
+ private ContentInfoParser _encapContentInfo;
+
+ public CompressedDataParser(
+ ASN1SequenceParser seq)
+ throws IOException
+ {
+ this._version = (ASN1Integer)seq.readObject();
+ this._compressionAlgorithm = AlgorithmIdentifier.getInstance(seq.readObject().toASN1Primitive());
+ this._encapContentInfo = new ContentInfoParser((ASN1SequenceParser)seq.readObject());
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return _version;
+ }
+
+ public AlgorithmIdentifier getCompressionAlgorithmIdentifier()
+ {
+ return _compressionAlgorithm;
+ }
+
+ public ContentInfoParser getEncapContentInfo()
+ {
+ return _encapContentInfo;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
index 1592c75..2e8e039 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -28,9 +28,7 @@ import org.bouncycastle.asn1.BERTaggedObject;
*/
public class ContentInfo
extends ASN1Object
- // BEGIN android-removed
- // implements CMSObjectIdentifiers
- // END android-removed
+ implements CMSObjectIdentifiers
{
private ASN1ObjectIdentifier contentType;
private ASN1Encodable content;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfoParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfoParser.java
new file mode 100644
index 0000000..19f0ec8
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfoParser.java
@@ -0,0 +1,48 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.ASN1TaggedObjectParser;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-3">RFC 5652</a> {@link ContentInfo} object parser.
+ *
+ * <pre>
+ * ContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+ * </pre>
+ */
+public class ContentInfoParser
+{
+ private ASN1ObjectIdentifier contentType;
+ private ASN1TaggedObjectParser content;
+
+ public ContentInfoParser(
+ ASN1SequenceParser seq)
+ throws IOException
+ {
+ contentType = (ASN1ObjectIdentifier)seq.readObject();
+ content = (ASN1TaggedObjectParser)seq.readObject();
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return contentType;
+ }
+
+ public ASN1Encodable getContent(
+ int tag)
+ throws IOException
+ {
+ if (content != null)
+ {
+ return content.getObjectParser(tag, true);
+ }
+
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java
new file mode 100644
index 0000000..0f3b906
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java
@@ -0,0 +1,128 @@
+package org.bouncycastle.asn1.cms;
+
+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.ASN1TaggedObject;
+import org.bouncycastle.asn1.BERSequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-7">RFC 5652</a> DigestedData object.
+ * <pre>
+ * DigestedData ::= SEQUENCE {
+ * version CMSVersion,
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * encapContentInfo EncapsulatedContentInfo,
+ * digest Digest }
+ * </pre>
+ */
+public class DigestedData
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private AlgorithmIdentifier digestAlgorithm;
+ private ContentInfo encapContentInfo;
+ private ASN1OctetString digest;
+
+ public DigestedData(
+ AlgorithmIdentifier digestAlgorithm,
+ ContentInfo encapContentInfo,
+ byte[] digest)
+ {
+ this.version = new ASN1Integer(0);
+ this.digestAlgorithm = digestAlgorithm;
+ this.encapContentInfo = encapContentInfo;
+ this.digest = new DEROctetString(digest);
+ }
+
+ private DigestedData(
+ ASN1Sequence seq)
+ {
+ this.version = (ASN1Integer)seq.getObjectAt(0);
+ this.digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ this.encapContentInfo = ContentInfo.getInstance(seq.getObjectAt(2));
+ this.digest = ASN1OctetString.getInstance(seq.getObjectAt(3));
+ }
+
+ /**
+ * Return a DigestedData object from a tagged object.
+ *
+ * @param ato the tagged object holding the object we want.
+ * @param isExplicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static DigestedData getInstance(
+ ASN1TaggedObject ato,
+ boolean isExplicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(ato, isExplicit));
+ }
+
+ /**
+ * Return a DigestedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link DigestedData} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DigestedData getInstance(
+ Object obj)
+ {
+ if (obj instanceof DigestedData)
+ {
+ return (DigestedData)obj;
+ }
+
+ if (obj != null)
+ {
+ return new DigestedData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ return digestAlgorithm;
+ }
+
+ public ContentInfo getEncapContentInfo()
+ {
+ return encapContentInfo;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+ v.add(digestAlgorithm);
+ v.add(encapContentInfo);
+ v.add(digest);
+
+ return new BERSequence(v);
+ }
+
+ public byte[] getDigest()
+ {
+ return digest.getOctets();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java
new file mode 100644
index 0000000..64d887d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java
@@ -0,0 +1,120 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+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;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.1">RFC 5652</a> EncryptedContentInfo object.
+ *
+ * <pre>
+ * EncryptedContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+ * }
+ * </pre>
+ */
+public class EncryptedContentInfo
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier contentType;
+ private AlgorithmIdentifier contentEncryptionAlgorithm;
+ private ASN1OctetString encryptedContent;
+
+ public EncryptedContentInfo(
+ ASN1ObjectIdentifier contentType,
+ AlgorithmIdentifier contentEncryptionAlgorithm,
+ ASN1OctetString encryptedContent)
+ {
+ this.contentType = contentType;
+ this.contentEncryptionAlgorithm = contentEncryptionAlgorithm;
+ this.encryptedContent = encryptedContent;
+ }
+
+ private EncryptedContentInfo(
+ ASN1Sequence seq)
+ {
+ if (seq.size() < 2)
+ {
+ throw new IllegalArgumentException("Truncated Sequence Found");
+ }
+
+ contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(
+ seq.getObjectAt(1));
+ if (seq.size() > 2)
+ {
+ encryptedContent = ASN1OctetString.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(2), false);
+ }
+ }
+
+ /**
+ * Return an EncryptedContentInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link EncryptedContentInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static EncryptedContentInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof EncryptedContentInfo)
+ {
+ return (EncryptedContentInfo)obj;
+ }
+ if (obj != null)
+ {
+ return new EncryptedContentInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return contentType;
+ }
+
+ public AlgorithmIdentifier getContentEncryptionAlgorithm()
+ {
+ return contentEncryptionAlgorithm;
+ }
+
+ public ASN1OctetString getEncryptedContent()
+ {
+ return encryptedContent;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(contentType);
+ v.add(contentEncryptionAlgorithm);
+
+ if (encryptedContent != null)
+ {
+ v.add(new BERTaggedObject(false, 0, encryptedContent));
+ }
+
+ return new BERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java
new file mode 100644
index 0000000..77fb0bb
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java
@@ -0,0 +1,53 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.ASN1TaggedObjectParser;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Parser for <a href="http://tools.ietf.org/html/rfc5652#section-6.1">RFC 5652</a> EncryptedContentInfo object.
+ * <p>
+ * <pre>
+ * EncryptedContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+ * }
+ * </pre>
+ */
+public class EncryptedContentInfoParser
+{
+ private ASN1ObjectIdentifier _contentType;
+ private AlgorithmIdentifier _contentEncryptionAlgorithm;
+ private ASN1TaggedObjectParser _encryptedContent;
+
+ public EncryptedContentInfoParser(
+ ASN1SequenceParser seq)
+ throws IOException
+ {
+ _contentType = (ASN1ObjectIdentifier)seq.readObject();
+ _contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.readObject().toASN1Primitive());
+ _encryptedContent = (ASN1TaggedObjectParser)seq.readObject();
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return _contentType;
+ }
+
+ public AlgorithmIdentifier getContentEncryptionAlgorithm()
+ {
+ return _contentEncryptionAlgorithm;
+ }
+
+ public ASN1Encodable getEncryptedContent(
+ int tag)
+ throws IOException
+ {
+ return _encryptedContent.getObjectParser(tag, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java
new file mode 100644
index 0000000..080abfc
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java
@@ -0,0 +1,112 @@
+package org.bouncycastle.asn1.cms;
+
+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.BERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-8">RFC 5652</a> EncryptedData object.
+ * <p>
+ * <pre>
+ * EncryptedData ::= SEQUENCE {
+ * version CMSVersion,
+ * encryptedContentInfo EncryptedContentInfo,
+ * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
+ * </pre>
+ */
+public class EncryptedData
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private EncryptedContentInfo encryptedContentInfo;
+ private ASN1Set unprotectedAttrs;
+
+ /**
+ * Return an EncryptedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link EncryptedData} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static EncryptedData getInstance(Object o)
+ {
+ if (o instanceof EncryptedData)
+ {
+ return (EncryptedData)o;
+ }
+
+ if (o != null)
+ {
+ return new EncryptedData(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public EncryptedData(EncryptedContentInfo encInfo)
+ {
+ this(encInfo, null);
+ }
+
+ public EncryptedData(EncryptedContentInfo encInfo, ASN1Set unprotectedAttrs)
+ {
+ this.version = new ASN1Integer((unprotectedAttrs == null) ? 0 : 2);
+ this.encryptedContentInfo = encInfo;
+ this.unprotectedAttrs = unprotectedAttrs;
+ }
+
+ private EncryptedData(ASN1Sequence seq)
+ {
+ this.version = ASN1Integer.getInstance(seq.getObjectAt(0));
+ this.encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(1));
+
+ if (seq.size() == 3)
+ {
+ this.unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(2), false);
+ }
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public EncryptedContentInfo getEncryptedContentInfo()
+ {
+ return encryptedContentInfo;
+ }
+
+ public ASN1Set getUnprotectedAttrs()
+ {
+ return unprotectedAttrs;
+ }
+
+ /**
+ * @return a basic ASN.1 object representation.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+ v.add(encryptedContentInfo);
+ if (unprotectedAttrs != null)
+ {
+ v.add(new BERTaggedObject(false, 1, unprotectedAttrs));
+ }
+
+ return new BERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java
new file mode 100644
index 0000000..994575a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java
@@ -0,0 +1,215 @@
+package org.bouncycastle.asn1.cms;
+
+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 href="http://tools.ietf.org/html/rfc5652#section-6.1">RFC 5652</a> EnvelopedData object.
+ * <pre>
+ * EnvelopedData ::= SEQUENCE {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * encryptedContentInfo EncryptedContentInfo,
+ * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
+ * }
+ * </pre>
+ */
+public class EnvelopedData
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private OriginatorInfo originatorInfo;
+ private ASN1Set recipientInfos;
+ private EncryptedContentInfo encryptedContentInfo;
+ private ASN1Set unprotectedAttrs;
+
+ public EnvelopedData(
+ OriginatorInfo originatorInfo,
+ ASN1Set recipientInfos,
+ EncryptedContentInfo encryptedContentInfo,
+ ASN1Set unprotectedAttrs)
+ {
+ version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, unprotectedAttrs));
+
+ this.originatorInfo = originatorInfo;
+ this.recipientInfos = recipientInfos;
+ this.encryptedContentInfo = encryptedContentInfo;
+ this.unprotectedAttrs = unprotectedAttrs;
+ }
+
+ public EnvelopedData(
+ OriginatorInfo originatorInfo,
+ ASN1Set recipientInfos,
+ EncryptedContentInfo encryptedContentInfo,
+ Attributes unprotectedAttrs)
+ {
+ version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, ASN1Set.getInstance(unprotectedAttrs)));
+
+ this.originatorInfo = originatorInfo;
+ this.recipientInfos = recipientInfos;
+ this.encryptedContentInfo = encryptedContentInfo;
+ this.unprotectedAttrs = ASN1Set.getInstance(unprotectedAttrs);
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public EnvelopedData(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ version = (ASN1Integer)seq.getObjectAt(index++);
+
+ Object tmp = seq.getObjectAt(index++);
+
+ if (tmp instanceof ASN1TaggedObject)
+ {
+ originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
+ tmp = seq.getObjectAt(index++);
+ }
+
+ recipientInfos = ASN1Set.getInstance(tmp);
+
+ encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(index++));
+
+ if(seq.size() > index)
+ {
+ unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
+ }
+ }
+
+ /**
+ * Return an EnvelopedData object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static EnvelopedData getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an EnvelopedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link EnvelopedData} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with EnvelopedData structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static EnvelopedData getInstance(
+ Object obj)
+ {
+ if (obj instanceof EnvelopedData)
+ {
+ return (EnvelopedData)obj;
+ }
+
+ if (obj != null)
+ {
+ return new EnvelopedData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public OriginatorInfo getOriginatorInfo()
+ {
+ return originatorInfo;
+ }
+
+ public ASN1Set getRecipientInfos()
+ {
+ return recipientInfos;
+ }
+
+ public EncryptedContentInfo getEncryptedContentInfo()
+ {
+ return encryptedContentInfo;
+ }
+
+ public ASN1Set getUnprotectedAttrs()
+ {
+ return unprotectedAttrs;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+
+ if (originatorInfo != null)
+ {
+ v.add(new DERTaggedObject(false, 0, originatorInfo));
+ }
+
+ v.add(recipientInfos);
+ v.add(encryptedContentInfo);
+
+ if (unprotectedAttrs != null)
+ {
+ v.add(new DERTaggedObject(false, 1, unprotectedAttrs));
+ }
+
+ return new BERSequence(v);
+ }
+
+ public static int calculateVersion(OriginatorInfo originatorInfo, ASN1Set recipientInfos, ASN1Set unprotectedAttrs)
+ {
+ int version;
+
+ if (originatorInfo != null || unprotectedAttrs != null)
+ {
+ version = 2;
+ }
+ else
+ {
+ version = 0;
+
+ Enumeration e = recipientInfos.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ RecipientInfo ri = RecipientInfo.getInstance(e.nextElement());
+
+ if (ri.getVersion().getValue().intValue() != version)
+ {
+ version = 2;
+ break;
+ }
+ }
+ }
+
+ return version;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java
new file mode 100644
index 0000000..774813a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java
@@ -0,0 +1,120 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.ASN1SetParser;
+import org.bouncycastle.asn1.ASN1TaggedObjectParser;
+import org.bouncycastle.asn1.BERTags;
+
+/**
+ * Parser of <a href="http://tools.ietf.org/html/rfc5652#section-6.1">RFC 5652</a> {@link EnvelopedData} object.
+ * <p>
+ * <pre>
+ * EnvelopedData ::= SEQUENCE {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * encryptedContentInfo EncryptedContentInfo,
+ * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
+ * }
+ * </pre>
+ */
+public class EnvelopedDataParser
+{
+ private ASN1SequenceParser _seq;
+ private ASN1Integer _version;
+ private ASN1Encodable _nextObject;
+ private boolean _originatorInfoCalled;
+
+ public EnvelopedDataParser(
+ ASN1SequenceParser seq)
+ throws IOException
+ {
+ this._seq = seq;
+ this._version = ASN1Integer.getInstance(seq.readObject());
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return _version;
+ }
+
+ public OriginatorInfo getOriginatorInfo()
+ throws IOException
+ {
+ _originatorInfoCalled = true;
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.readObject();
+ }
+
+ if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 0)
+ {
+ ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SEQUENCE, false);
+ _nextObject = null;
+ return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive());
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getRecipientInfos()
+ throws IOException
+ {
+ if (!_originatorInfoCalled)
+ {
+ getOriginatorInfo();
+ }
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.readObject();
+ }
+
+ ASN1SetParser recipientInfos = (ASN1SetParser)_nextObject;
+ _nextObject = null;
+ return recipientInfos;
+ }
+
+ public EncryptedContentInfoParser getEncryptedContentInfo()
+ throws IOException
+ {
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.readObject();
+ }
+
+
+ if (_nextObject != null)
+ {
+ ASN1SequenceParser o = (ASN1SequenceParser) _nextObject;
+ _nextObject = null;
+ return new EncryptedContentInfoParser(o);
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getUnprotectedAttrs()
+ throws IOException
+ {
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.readObject();
+ }
+
+
+ if (_nextObject != null)
+ {
+ ASN1Encodable o = _nextObject;
+ _nextObject = null;
+ return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
+ }
+
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/Evidence.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Evidence.java
new file mode 100644
index 0000000..4dcbfde
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Evidence.java
@@ -0,0 +1,80 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5544">RFC 5544</a>:
+ * Binding Documents with Time-Stamps; Evidence object.
+ * <p>
+ * <pre>
+ * Evidence ::= CHOICE {
+ * tstEvidence [0] TimeStampTokenEvidence, -- see RFC 3161
+ * ersEvidence [1] EvidenceRecord, -- see RFC 4998
+ * otherEvidence [2] OtherEvidence
+ * }
+ * </pre>
+ */
+public class Evidence
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private TimeStampTokenEvidence tstEvidence;
+
+ public Evidence(TimeStampTokenEvidence tstEvidence)
+ {
+ this.tstEvidence = tstEvidence;
+ }
+
+ private Evidence(ASN1TaggedObject tagged)
+ {
+ if (tagged.getTagNo() == 0)
+ {
+ this.tstEvidence = TimeStampTokenEvidence.getInstance(tagged, false);
+ }
+ }
+
+ /**
+ * Return an Evidence object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> {@link Evidence} object
+ * <li> {@link org.bouncycastle.asn1.ASN1TaggedObject#getInstance(java.lang.Object) ASN1TaggedObject} input formats with Evidence data inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static Evidence getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof Evidence)
+ {
+ return (Evidence)obj;
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new Evidence(ASN1TaggedObject.getInstance(obj));
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance");
+ }
+
+ public TimeStampTokenEvidence getTstEvidence()
+ {
+ return tstEvidence;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (tstEvidence != null)
+ {
+ return new DERTaggedObject(false, 0, tstEvidence);
+ }
+
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java
new file mode 100644
index 0000000..0361e9f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java
@@ -0,0 +1,151 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1GeneralizedTime;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.3">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <p>
+ * <pre>
+ * KEKIdentifier ::= SEQUENCE {
+ * keyIdentifier OCTET STRING,
+ * date GeneralizedTime OPTIONAL,
+ * other OtherKeyAttribute OPTIONAL
+ * }
+ * </pre>
+ */
+public class KEKIdentifier
+ extends ASN1Object
+{
+ private ASN1OctetString keyIdentifier;
+ private ASN1GeneralizedTime date;
+ private OtherKeyAttribute other;
+
+ public KEKIdentifier(
+ byte[] keyIdentifier,
+ ASN1GeneralizedTime date,
+ OtherKeyAttribute other)
+ {
+ this.keyIdentifier = new DEROctetString(keyIdentifier);
+ this.date = date;
+ this.other = other;
+ }
+
+ private KEKIdentifier(
+ ASN1Sequence seq)
+ {
+ keyIdentifier = (ASN1OctetString)seq.getObjectAt(0);
+
+ switch (seq.size())
+ {
+ case 1:
+ break;
+ case 2:
+ if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime)
+ {
+ date = (ASN1GeneralizedTime)seq.getObjectAt(1);
+ }
+ else
+ {
+ other = OtherKeyAttribute.getInstance(seq.getObjectAt(1));
+ }
+ break;
+ case 3:
+ date = (ASN1GeneralizedTime)seq.getObjectAt(1);
+ other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid KEKIdentifier");
+ }
+ }
+
+ /**
+ * Return a KEKIdentifier object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KEKIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a KEKIdentifier object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link KEKIdentifier} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with KEKIdentifier structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static KEKIdentifier getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof KEKIdentifier)
+ {
+ return (KEKIdentifier)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new KEKIdentifier((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid KEKIdentifier: " + obj.getClass().getName());
+ }
+
+ public ASN1OctetString getKeyIdentifier()
+ {
+ return keyIdentifier;
+ }
+
+ public ASN1GeneralizedTime getDate()
+ {
+ return date;
+ }
+
+ public OtherKeyAttribute getOther()
+ {
+ return other;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(keyIdentifier);
+
+ if (date != null)
+ {
+ v.add(date);
+ }
+
+ if (other != null)
+ {
+ v.add(other);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java
new file mode 100644
index 0000000..2d0cfa6
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java
@@ -0,0 +1,133 @@
+package org.bouncycastle.asn1.cms;
+
+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.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.3">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <p>
+ * <pre>
+ * KEKRecipientInfo ::= SEQUENCE {
+ * version CMSVersion, -- always set to 4
+ * kekid KEKIdentifier,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * encryptedKey EncryptedKey
+ * }
+ * </pre>
+ */
+public class KEKRecipientInfo
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private KEKIdentifier kekid;
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+ private ASN1OctetString encryptedKey;
+
+ public KEKRecipientInfo(
+ KEKIdentifier kekid,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ ASN1OctetString encryptedKey)
+ {
+ this.version = new ASN1Integer(4);
+ this.kekid = kekid;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public KEKRecipientInfo(
+ ASN1Sequence seq)
+ {
+ version = (ASN1Integer)seq.getObjectAt(0);
+ kekid = KEKIdentifier.getInstance(seq.getObjectAt(1));
+ keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2));
+ encryptedKey = (ASN1OctetString)seq.getObjectAt(3);
+ }
+
+ /**
+ * Return a KEKRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KEKRecipientInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a KEKRecipientInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link KEKRecipientInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with KEKRecipientInfo structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static KEKRecipientInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof KEKRecipientInfo)
+ {
+ return (KEKRecipientInfo)obj;
+ }
+
+ if (obj != null)
+ {
+ return new KEKRecipientInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public KEKIdentifier getKekid()
+ {
+ return kekid;
+ }
+
+ public AlgorithmIdentifier getKeyEncryptionAlgorithm()
+ {
+ return keyEncryptionAlgorithm;
+ }
+
+ public ASN1OctetString getEncryptedKey()
+ {
+ return encryptedKey;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+ v.add(kekid);
+ v.add(keyEncryptionAlgorithm);
+ v.add(encryptedKey);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java
new file mode 100644
index 0000000..6580cd4
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java
@@ -0,0 +1,116 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <p>
+ * <pre>
+ * KeyAgreeRecipientIdentifier ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * rKeyId [0] IMPLICIT RecipientKeyIdentifier }
+ * </pre>
+ */
+public class KeyAgreeRecipientIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private IssuerAndSerialNumber issuerSerial;
+ private RecipientKeyIdentifier rKeyID;
+
+ /**
+ * Return an KeyAgreeRecipientIdentifier object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KeyAgreeRecipientIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an KeyAgreeRecipientIdentifier object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> {@link KeyAgreeRecipientIdentifier} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with IssuerAndSerialNumber structure inside
+ * <li> {@link org.bouncycastle.asn1.ASN1TaggedObject#getInstance(java.lang.Object) ASN1TaggedObject} with tag value 0: a KeyAgreeRecipientIdentifier data structure
+ * </ul>
+ * <p>
+ * Note: no byte[] input!
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static KeyAgreeRecipientIdentifier getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof KeyAgreeRecipientIdentifier)
+ {
+ return (KeyAgreeRecipientIdentifier)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.getInstance(obj));
+ }
+
+ if (obj instanceof ASN1TaggedObject && ((ASN1TaggedObject)obj).getTagNo() == 0)
+ {
+ return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.getInstance(
+ (ASN1TaggedObject)obj, false));
+ }
+
+ throw new IllegalArgumentException("Invalid KeyAgreeRecipientIdentifier: " + obj.getClass().getName());
+ }
+
+ public KeyAgreeRecipientIdentifier(
+ IssuerAndSerialNumber issuerSerial)
+ {
+ this.issuerSerial = issuerSerial;
+ this.rKeyID = null;
+ }
+
+ public KeyAgreeRecipientIdentifier(
+ RecipientKeyIdentifier rKeyID)
+ {
+ this.issuerSerial = null;
+ this.rKeyID = rKeyID;
+ }
+
+ public IssuerAndSerialNumber getIssuerAndSerialNumber()
+ {
+ return issuerSerial;
+ }
+
+ public RecipientKeyIdentifier getRKeyID()
+ {
+ return rKeyID;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (issuerSerial != null)
+ {
+ return issuerSerial.toASN1Primitive();
+ }
+
+ return new DERTaggedObject(false, 0, rKeyID);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java
new file mode 100644
index 0000000..224932a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java
@@ -0,0 +1,166 @@
+package org.bouncycastle.asn1.cms;
+
+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.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <p>
+ * <pre>
+ * KeyAgreeRecipientInfo ::= SEQUENCE {
+ * version CMSVersion, -- always set to 3
+ * originator [0] EXPLICIT OriginatorIdentifierOrKey,
+ * ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * recipientEncryptedKeys RecipientEncryptedKeys
+ * }
+ *
+ * UserKeyingMaterial ::= OCTET STRING
+ * </pre>
+ */
+public class KeyAgreeRecipientInfo
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private OriginatorIdentifierOrKey originator;
+ private ASN1OctetString ukm;
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+ private ASN1Sequence recipientEncryptedKeys;
+
+ public KeyAgreeRecipientInfo(
+ OriginatorIdentifierOrKey originator,
+ ASN1OctetString ukm,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ ASN1Sequence recipientEncryptedKeys)
+ {
+ this.version = new ASN1Integer(3);
+ this.originator = originator;
+ this.ukm = ukm;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.recipientEncryptedKeys = recipientEncryptedKeys;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public KeyAgreeRecipientInfo(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ version = (ASN1Integer)seq.getObjectAt(index++);
+ originator = OriginatorIdentifierOrKey.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(index++), true);
+
+ if (seq.getObjectAt(index) instanceof ASN1TaggedObject)
+ {
+ ukm = ASN1OctetString.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(index++), true);
+ }
+
+ keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(
+ seq.getObjectAt(index++));
+
+ recipientEncryptedKeys = (ASN1Sequence)seq.getObjectAt(index++);
+ }
+
+ /**
+ * Return a KeyAgreeRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KeyAgreeRecipientInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a KeyAgreeRecipientInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link KeyAgreeRecipientInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with KeyAgreeRecipientInfo structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static KeyAgreeRecipientInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof KeyAgreeRecipientInfo)
+ {
+ return (KeyAgreeRecipientInfo)obj;
+ }
+
+ if (obj != null)
+ {
+ return new KeyAgreeRecipientInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public OriginatorIdentifierOrKey getOriginator()
+ {
+ return originator;
+ }
+
+ public ASN1OctetString getUserKeyingMaterial()
+ {
+ return ukm;
+ }
+
+ public AlgorithmIdentifier getKeyEncryptionAlgorithm()
+ {
+ return keyEncryptionAlgorithm;
+ }
+
+ public ASN1Sequence getRecipientEncryptedKeys()
+ {
+ return recipientEncryptedKeys;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+ v.add(new DERTaggedObject(true, 0, originator));
+
+ if (ukm != null)
+ {
+ v.add(new DERTaggedObject(true, 1, ukm));
+ }
+
+ v.add(keyEncryptionAlgorithm);
+ v.add(recipientEncryptedKeys);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java
new file mode 100644
index 0000000..7d31111
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java
@@ -0,0 +1,127 @@
+package org.bouncycastle.asn1.cms;
+
+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.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.1">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <pre>
+ * KeyTransRecipientInfo ::= SEQUENCE {
+ * version CMSVersion, -- always set to 0 or 2
+ * rid RecipientIdentifier,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * encryptedKey EncryptedKey
+ * }
+ * </pre>
+ */
+public class KeyTransRecipientInfo
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private RecipientIdentifier rid;
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+ private ASN1OctetString encryptedKey;
+
+ public KeyTransRecipientInfo(
+ RecipientIdentifier rid,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ ASN1OctetString encryptedKey)
+ {
+ if (rid.toASN1Primitive() instanceof ASN1TaggedObject)
+ {
+ this.version = new ASN1Integer(2);
+ }
+ else
+ {
+ this.version = new ASN1Integer(0);
+ }
+
+ this.rid = rid;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public KeyTransRecipientInfo(
+ ASN1Sequence seq)
+ {
+ this.version = (ASN1Integer)seq.getObjectAt(0);
+ this.rid = RecipientIdentifier.getInstance(seq.getObjectAt(1));
+ this.keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2));
+ this.encryptedKey = (ASN1OctetString)seq.getObjectAt(3);
+ }
+
+ /**
+ * Return a KeyTransRecipientInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link KeyTransRecipientInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with KeyTransRecipientInfo structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static KeyTransRecipientInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof KeyTransRecipientInfo)
+ {
+ return (KeyTransRecipientInfo)obj;
+ }
+
+ if(obj != null)
+ {
+ return new KeyTransRecipientInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public RecipientIdentifier getRecipientIdentifier()
+ {
+ return rid;
+ }
+
+ public AlgorithmIdentifier getKeyEncryptionAlgorithm()
+ {
+ return keyEncryptionAlgorithm;
+ }
+
+ public ASN1OctetString getEncryptedKey()
+ {
+ return encryptedKey;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+ v.add(rid);
+ v.add(keyEncryptionAlgorithm);
+ v.add(encryptedKey);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/MetaData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/MetaData.java
new file mode 100644
index 0000000..667187b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/MetaData.java
@@ -0,0 +1,135 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1Boolean;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERUTF8String;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5544">RFC 5544</a>:
+ * Binding Documents with Time-Stamps; MetaData object.
+ * <p>
+ * <pre>
+ * MetaData ::= SEQUENCE {
+ * hashProtected BOOLEAN,
+ * fileName UTF8String OPTIONAL,
+ * mediaType IA5String OPTIONAL,
+ * otherMetaData Attributes OPTIONAL
+ * }
+ * </pre>
+ */
+public class MetaData
+ extends ASN1Object
+{
+ private ASN1Boolean hashProtected;
+ private DERUTF8String fileName;
+ private DERIA5String mediaType;
+ private Attributes otherMetaData;
+
+ public MetaData(
+ ASN1Boolean hashProtected,
+ DERUTF8String fileName,
+ DERIA5String mediaType,
+ Attributes otherMetaData)
+ {
+ this.hashProtected = hashProtected;
+ this.fileName = fileName;
+ this.mediaType = mediaType;
+ this.otherMetaData = otherMetaData;
+ }
+
+ private MetaData(ASN1Sequence seq)
+ {
+ this.hashProtected = ASN1Boolean.getInstance(seq.getObjectAt(0));
+
+ int index = 1;
+
+ if (index < seq.size() && seq.getObjectAt(index) instanceof DERUTF8String)
+ {
+ this.fileName = DERUTF8String.getInstance(seq.getObjectAt(index++));
+ }
+ if (index < seq.size() && seq.getObjectAt(index) instanceof DERIA5String)
+ {
+ this.mediaType = DERIA5String.getInstance(seq.getObjectAt(index++));
+ }
+ if (index < seq.size())
+ {
+ this.otherMetaData = Attributes.getInstance(seq.getObjectAt(index++));
+ }
+ }
+
+ /**
+ * Return a MetaData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link MetaData} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with MetaData structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static MetaData getInstance(Object obj)
+ {
+ if (obj instanceof MetaData)
+ {
+ return (MetaData)obj;
+ }
+ else if (obj != null)
+ {
+ return new MetaData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(hashProtected);
+
+ if (fileName != null)
+ {
+ v.add(fileName);
+ }
+
+ if (mediaType != null)
+ {
+ v.add(mediaType);
+ }
+
+ if (otherMetaData != null)
+ {
+ v.add(otherMetaData);
+ }
+
+ return new DERSequence(v);
+ }
+
+ public boolean isHashProtected()
+ {
+ return hashProtected.isTrue();
+ }
+
+ public DERUTF8String getFileName()
+ {
+ return this.fileName;
+ }
+
+ public DERIA5String getMediaType()
+ {
+ return this.mediaType;
+ }
+
+ public Attributes getOtherMetaData()
+ {
+ return otherMetaData;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java
new file mode 100644
index 0000000..2096be2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java
@@ -0,0 +1,179 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <pre>
+ * OriginatorIdentifierOrKey ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier,
+ * originatorKey [1] OriginatorPublicKey
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ * </pre>
+ */
+public class OriginatorIdentifierOrKey
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1Encodable id;
+
+ public OriginatorIdentifierOrKey(
+ IssuerAndSerialNumber id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * @deprecated use version taking a SubjectKeyIdentifier
+ */
+ public OriginatorIdentifierOrKey(
+ ASN1OctetString id)
+ {
+ this(new SubjectKeyIdentifier(id.getOctets()));
+ }
+
+ public OriginatorIdentifierOrKey(
+ SubjectKeyIdentifier id)
+ {
+ this.id = new DERTaggedObject(false, 0, id);
+ }
+
+ public OriginatorIdentifierOrKey(
+ OriginatorPublicKey id)
+ {
+ this.id = new DERTaggedObject(false, 1, id);
+ }
+
+ /**
+ * @deprecated use more specific version
+ */
+ public OriginatorIdentifierOrKey(
+ ASN1Primitive id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * Return an OriginatorIdentifierOrKey object from a tagged object.
+ *
+ * @param o the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OriginatorIdentifierOrKey getInstance(
+ ASN1TaggedObject o,
+ boolean explicit)
+ {
+ if (!explicit)
+ {
+ throw new IllegalArgumentException(
+ "Can't implicitly tag OriginatorIdentifierOrKey");
+ }
+
+ return getInstance(o.getObject());
+ }
+
+ /**
+ * Return an OriginatorIdentifierOrKey object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link OriginatorIdentifierOrKey} object
+ * <li> {@link IssuerAndSerialNumber} object
+ * <li> {@link SubjectKeyIdentifier} object
+ * <li> {@link OriginatorPublicKey} object
+ * <li> {@link org.bouncycastle.asn1.ASN1TaggedObject#getInstance(java.lang.Object) ASN1TaggedObject} input formats with IssuerAndSerialNumber structure inside
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static OriginatorIdentifierOrKey getInstance(
+ Object o)
+ {
+ if (o == null || o instanceof OriginatorIdentifierOrKey)
+ {
+ return (OriginatorIdentifierOrKey)o;
+ }
+
+ if (o instanceof IssuerAndSerialNumber)
+ {
+ return new OriginatorIdentifierOrKey((IssuerAndSerialNumber)o);
+ }
+
+ if (o instanceof SubjectKeyIdentifier)
+ {
+ return new OriginatorIdentifierOrKey((SubjectKeyIdentifier)o);
+ }
+
+ if (o instanceof OriginatorPublicKey)
+ {
+ return new OriginatorIdentifierOrKey((OriginatorPublicKey)o);
+ }
+
+ if (o instanceof ASN1TaggedObject)
+ {
+ // TODO Add validation
+ return new OriginatorIdentifierOrKey((ASN1TaggedObject)o);
+ }
+
+ throw new IllegalArgumentException("Invalid OriginatorIdentifierOrKey: " + o.getClass().getName());
+ }
+
+ public ASN1Encodable getId()
+ {
+ return id;
+ }
+
+ public IssuerAndSerialNumber getIssuerAndSerialNumber()
+ {
+ if (id instanceof IssuerAndSerialNumber)
+ {
+ return (IssuerAndSerialNumber)id;
+ }
+
+ return null;
+ }
+
+ public SubjectKeyIdentifier getSubjectKeyIdentifier()
+ {
+ if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 0)
+ {
+ return SubjectKeyIdentifier.getInstance((ASN1TaggedObject)id, false);
+ }
+
+ return null;
+ }
+
+ public OriginatorPublicKey getOriginatorKey()
+ {
+ if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 1)
+ {
+ return OriginatorPublicKey.getInstance((ASN1TaggedObject)id, false);
+ }
+
+ return null;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return id.toASN1Primitive();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java
new file mode 100644
index 0000000..96abf7d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java
@@ -0,0 +1,159 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+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.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.1">RFC 5652</a>: OriginatorInfo object.
+ * <pre>
+ * RFC 3369:
+ *
+ * OriginatorInfo ::= SEQUENCE {
+ * certs [0] IMPLICIT CertificateSet OPTIONAL,
+ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL
+ * }
+ * CertificateRevocationLists ::= SET OF CertificateList (from X.509)
+ *
+ * RFC 3582 / 5652:
+ *
+ * OriginatorInfo ::= SEQUENCE {
+ * certs [0] IMPLICIT CertificateSet OPTIONAL,
+ * crls [1] IMPLICIT RevocationInfoChoices OPTIONAL
+ * }
+ * RevocationInfoChoices ::= SET OF RevocationInfoChoice
+ * RevocationInfoChoice ::= CHOICE {
+ * crl CertificateList,
+ * other [1] IMPLICIT OtherRevocationInfoFormat }
+ *
+ * OtherRevocationInfoFormat ::= SEQUENCE {
+ * otherRevInfoFormat OBJECT IDENTIFIER,
+ * otherRevInfo ANY DEFINED BY otherRevInfoFormat }
+ * </pre>
+ * <p>
+ * TODO: RevocationInfoChoices / RevocationInfoChoice.
+ * Constructor using CertificateSet, CertificationInfoChoices
+ */
+public class OriginatorInfo
+ extends ASN1Object
+{
+ private ASN1Set certs;
+ private ASN1Set crls;
+
+ public OriginatorInfo(
+ ASN1Set certs,
+ ASN1Set crls)
+ {
+ this.certs = certs;
+ this.crls = crls;
+ }
+
+ private OriginatorInfo(
+ ASN1Sequence seq)
+ {
+ switch (seq.size())
+ {
+ case 0: // empty
+ break;
+ case 1:
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
+ switch (o.getTagNo())
+ {
+ case 0 :
+ certs = ASN1Set.getInstance(o, false);
+ break;
+ case 1 :
+ crls = ASN1Set.getInstance(o, false);
+ break;
+ default:
+ throw new IllegalArgumentException("Bad tag in OriginatorInfo: " + o.getTagNo());
+ }
+ break;
+ case 2:
+ certs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(0), false);
+ crls = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
+ break;
+ default:
+ throw new IllegalArgumentException("OriginatorInfo too big");
+ }
+ }
+
+ /**
+ * Return an OriginatorInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OriginatorInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an OriginatorInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link OriginatorInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with OriginatorInfo structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static OriginatorInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof OriginatorInfo)
+ {
+ return (OriginatorInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new OriginatorInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Set getCertificates()
+ {
+ return certs;
+ }
+
+ public ASN1Set getCRLs()
+ {
+ return crls;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (certs != null)
+ {
+ v.add(new DERTaggedObject(false, 0, certs));
+ }
+
+ if (crls != null)
+ {
+ v.add(new DERTaggedObject(false, 1, crls));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java
new file mode 100644
index 0000000..b9bc52f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java
@@ -0,0 +1,114 @@
+package org.bouncycastle.asn1.cms;
+
+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.DERBitString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <p>
+ * <pre>
+ * OriginatorPublicKey ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * publicKey BIT STRING
+ * }
+ * </pre>
+ */
+public class OriginatorPublicKey
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algorithm;
+ private DERBitString publicKey;
+
+ public OriginatorPublicKey(
+ AlgorithmIdentifier algorithm,
+ byte[] publicKey)
+ {
+ this.algorithm = algorithm;
+ this.publicKey = new DERBitString(publicKey);
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public OriginatorPublicKey(
+ ASN1Sequence seq)
+ {
+ algorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
+ publicKey = (DERBitString)seq.getObjectAt(1);
+ }
+
+ /**
+ * Return an OriginatorPublicKey object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OriginatorPublicKey getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an OriginatorPublicKey object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link OriginatorPublicKey} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with OriginatorPublicKey structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static OriginatorPublicKey getInstance(
+ Object obj)
+ {
+ if (obj instanceof OriginatorPublicKey)
+ {
+ return (OriginatorPublicKey)obj;
+ }
+
+ if (obj != null)
+ {
+ return new OriginatorPublicKey(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public DERBitString getPublicKey()
+ {
+ return publicKey;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(algorithm);
+ v.add(publicKey);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java
new file mode 100644
index 0000000..7363c81
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java
@@ -0,0 +1,96 @@
+package org.bouncycastle.asn1.cms;
+
+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;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-10.2.7">RFC 5652</a>: OtherKeyAttribute object.
+ * <p>
+ * <pre>
+ * OtherKeyAttribute ::= SEQUENCE {
+ * keyAttrId OBJECT IDENTIFIER,
+ * keyAttr ANY DEFINED BY keyAttrId OPTIONAL
+ * }
+ * </pre>
+ */
+public class OtherKeyAttribute
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier keyAttrId;
+ private ASN1Encodable keyAttr;
+
+ /**
+ * Return an OtherKeyAttribute object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link OtherKeyAttribute} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with OtherKeyAttribute structure inside
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static OtherKeyAttribute getInstance(
+ Object o)
+ {
+ if (o instanceof OtherKeyAttribute)
+ {
+ return (OtherKeyAttribute)o;
+ }
+
+ if (o != null)
+ {
+ return new OtherKeyAttribute(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public OtherKeyAttribute(
+ ASN1Sequence seq)
+ {
+ keyAttrId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ keyAttr = seq.getObjectAt(1);
+ }
+
+ public OtherKeyAttribute(
+ ASN1ObjectIdentifier keyAttrId,
+ ASN1Encodable keyAttr)
+ {
+ this.keyAttrId = keyAttrId;
+ this.keyAttr = keyAttr;
+ }
+
+ public ASN1ObjectIdentifier getKeyAttrId()
+ {
+ return keyAttrId;
+ }
+
+ public ASN1Encodable getKeyAttr()
+ {
+ return keyAttr;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(keyAttrId);
+ v.add(keyAttr);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java
new file mode 100644
index 0000000..b77b150
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java
@@ -0,0 +1,112 @@
+package org.bouncycastle.asn1.cms;
+
+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.DERSequence;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.5">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <pre>
+ * OtherRecipientInfo ::= SEQUENCE {
+ * oriType OBJECT IDENTIFIER,
+ * oriValue ANY DEFINED BY oriType }
+ * </pre>
+ */
+public class OtherRecipientInfo
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier oriType;
+ private ASN1Encodable oriValue;
+
+ public OtherRecipientInfo(
+ ASN1ObjectIdentifier oriType,
+ ASN1Encodable oriValue)
+ {
+ this.oriType = oriType;
+ this.oriValue = oriValue;
+ }
+
+ /**
+ * @deprecated use getInstance().
+ */
+ public OtherRecipientInfo(
+ ASN1Sequence seq)
+ {
+ oriType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ oriValue = seq.getObjectAt(1);
+ }
+
+ /**
+ * Return a OtherRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OtherRecipientInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a OtherRecipientInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link PasswordRecipientInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with OtherRecipientInfo structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static OtherRecipientInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof OtherRecipientInfo)
+ {
+ return (OtherRecipientInfo)obj;
+ }
+
+ if (obj != null)
+ {
+ return new OtherRecipientInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getType()
+ {
+ return oriType;
+ }
+
+ public ASN1Encodable getValue()
+ {
+ return oriValue;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(oriType);
+ v.add(oriValue);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java
new file mode 100644
index 0000000..a8348ff
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java
@@ -0,0 +1,109 @@
+package org.bouncycastle.asn1.cms;
+
+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.DERSequence;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-10.2.1">RFC 5652</a>: OtherRevocationInfoFormat object.
+ * <p>
+ * <pre>
+ * OtherRevocationInfoFormat ::= SEQUENCE {
+ * otherRevInfoFormat OBJECT IDENTIFIER,
+ * otherRevInfo ANY DEFINED BY otherRevInfoFormat }
+ * </pre>
+ */
+public class OtherRevocationInfoFormat
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier otherRevInfoFormat;
+ private ASN1Encodable otherRevInfo;
+
+ public OtherRevocationInfoFormat(
+ ASN1ObjectIdentifier otherRevInfoFormat,
+ ASN1Encodable otherRevInfo)
+ {
+ this.otherRevInfoFormat = otherRevInfoFormat;
+ this.otherRevInfo = otherRevInfo;
+ }
+
+ private OtherRevocationInfoFormat(
+ ASN1Sequence seq)
+ {
+ otherRevInfoFormat = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ otherRevInfo = seq.getObjectAt(1);
+ }
+
+ /**
+ * Return a OtherRevocationInfoFormat object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OtherRevocationInfoFormat getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a OtherRevocationInfoFormat object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link OtherRevocationInfoFormat} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with OtherRevocationInfoFormat structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static OtherRevocationInfoFormat getInstance(
+ Object obj)
+ {
+ if (obj instanceof OtherRevocationInfoFormat)
+ {
+ return (OtherRevocationInfoFormat)obj;
+ }
+
+ if (obj != null)
+ {
+ return new OtherRevocationInfoFormat(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getInfoFormat()
+ {
+ return otherRevInfoFormat;
+ }
+
+ public ASN1Encodable getInfo()
+ {
+ return otherRevInfo;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(otherRevInfoFormat);
+ v.add(otherRevInfo);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java
new file mode 100644
index 0000000..7ed16cf
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java
@@ -0,0 +1,157 @@
+package org.bouncycastle.asn1.cms;
+
+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.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-10.2.7">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <pre>
+ * PasswordRecipientInfo ::= SEQUENCE {
+ * version CMSVersion, -- Always set to 0
+ * keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
+ * OPTIONAL,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * encryptedKey EncryptedKey }
+ * </pre>
+ */
+public class PasswordRecipientInfo
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private AlgorithmIdentifier keyDerivationAlgorithm;
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+ private ASN1OctetString encryptedKey;
+
+ public PasswordRecipientInfo(
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ ASN1OctetString encryptedKey)
+ {
+ this.version = new ASN1Integer(0);
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public PasswordRecipientInfo(
+ AlgorithmIdentifier keyDerivationAlgorithm,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ ASN1OctetString encryptedKey)
+ {
+ this.version = new ASN1Integer(0);
+ this.keyDerivationAlgorithm = keyDerivationAlgorithm;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ /**
+ * @deprecated use getInstance() method.
+ */
+ public PasswordRecipientInfo(
+ ASN1Sequence seq)
+ {
+ version = (ASN1Integer)seq.getObjectAt(0);
+ if (seq.getObjectAt(1) instanceof ASN1TaggedObject)
+ {
+ keyDerivationAlgorithm = AlgorithmIdentifier.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
+ keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2));
+ encryptedKey = (ASN1OctetString)seq.getObjectAt(3);
+ }
+ else
+ {
+ keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ encryptedKey = (ASN1OctetString)seq.getObjectAt(2);
+ }
+ }
+
+ /**
+ * Return a PasswordRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static PasswordRecipientInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a PasswordRecipientInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link PasswordRecipientInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with PasswordRecipientInfo structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static PasswordRecipientInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof PasswordRecipientInfo)
+ {
+ return (PasswordRecipientInfo)obj;
+ }
+
+ if (obj != null)
+ {
+ return new PasswordRecipientInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public AlgorithmIdentifier getKeyDerivationAlgorithm()
+ {
+ return keyDerivationAlgorithm;
+ }
+
+ public AlgorithmIdentifier getKeyEncryptionAlgorithm()
+ {
+ return keyEncryptionAlgorithm;
+ }
+
+ public ASN1OctetString getEncryptedKey()
+ {
+ return encryptedKey;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+
+ if (keyDerivationAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 0, keyDerivationAlgorithm));
+ }
+ v.add(keyEncryptionAlgorithm);
+ v.add(encryptedKey);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java
new file mode 100644
index 0000000..5062c10
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java
@@ -0,0 +1,109 @@
+package org.bouncycastle.asn1.cms;
+
+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.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <pre>
+ * RecipientEncryptedKey ::= SEQUENCE {
+ * rid KeyAgreeRecipientIdentifier,
+ * encryptedKey EncryptedKey
+ * }
+ * </pre>
+ */
+public class RecipientEncryptedKey
+ extends ASN1Object
+{
+ private KeyAgreeRecipientIdentifier identifier;
+ private ASN1OctetString encryptedKey;
+
+ private RecipientEncryptedKey(
+ ASN1Sequence seq)
+ {
+ identifier = KeyAgreeRecipientIdentifier.getInstance(seq.getObjectAt(0));
+ encryptedKey = (ASN1OctetString)seq.getObjectAt(1);
+ }
+
+ /**
+ * Return an RecipientEncryptedKey object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static RecipientEncryptedKey getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a RecipientEncryptedKey object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link RecipientEncryptedKey} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with RecipientEncryptedKey structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static RecipientEncryptedKey getInstance(
+ Object obj)
+ {
+ if (obj instanceof RecipientEncryptedKey)
+ {
+ return (RecipientEncryptedKey)obj;
+ }
+
+ if (obj != null)
+ {
+ return new RecipientEncryptedKey(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public RecipientEncryptedKey(
+ KeyAgreeRecipientIdentifier id,
+ ASN1OctetString encryptedKey)
+ {
+ this.identifier = id;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public KeyAgreeRecipientIdentifier getIdentifier()
+ {
+ return identifier;
+ }
+
+ public ASN1OctetString getEncryptedKey()
+ {
+ return encryptedKey;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(identifier);
+ v.add(encryptedKey);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java
new file mode 100644
index 0000000..66b154a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java
@@ -0,0 +1,111 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.1">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <pre>
+ * RecipientIdentifier ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ * </pre>
+ */
+public class RecipientIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1Encodable id;
+
+ public RecipientIdentifier(
+ IssuerAndSerialNumber id)
+ {
+ this.id = id;
+ }
+
+ public RecipientIdentifier(
+ ASN1OctetString id)
+ {
+ this.id = new DERTaggedObject(false, 0, id);
+ }
+
+ public RecipientIdentifier(
+ ASN1Primitive id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * Return a RecipientIdentifier object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link RecipientIdentifier} object
+ * <li> {@link IssuerAndSerialNumber} object
+ * <li> {@link org.bouncycastle.asn1.ASN1OctetString#getInstance(java.lang.Object) ASN1OctetString} input formats (OctetString, byte[]) with value of KeyIdentifier in DER form
+ * <li> {@link org.bouncycastle.asn1.ASN1Primitive ASN1Primitive} for RecipientIdentifier constructor
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static RecipientIdentifier getInstance(
+ Object o)
+ {
+ if (o == null || o instanceof RecipientIdentifier)
+ {
+ return (RecipientIdentifier)o;
+ }
+
+ if (o instanceof IssuerAndSerialNumber)
+ {
+ return new RecipientIdentifier((IssuerAndSerialNumber)o);
+ }
+
+ if (o instanceof ASN1OctetString)
+ {
+ return new RecipientIdentifier((ASN1OctetString)o);
+ }
+
+ if (o instanceof ASN1Primitive)
+ {
+ return new RecipientIdentifier((ASN1Primitive)o);
+ }
+
+ throw new IllegalArgumentException(
+ "Illegal object in RecipientIdentifier: " + o.getClass().getName());
+ }
+
+ public boolean isTagged()
+ {
+ return (id instanceof ASN1TaggedObject);
+ }
+
+ public ASN1Encodable getId()
+ {
+ if (id instanceof ASN1TaggedObject)
+ {
+ return ASN1OctetString.getInstance((ASN1TaggedObject)id, false);
+ }
+
+ return IssuerAndSerialNumber.getInstance(id);
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return id.toASN1Primitive();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java
new file mode 100644
index 0000000..39a7bb2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java
@@ -0,0 +1,173 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Encodable;
+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.DERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <p>
+ * <pre>
+ * RecipientInfo ::= CHOICE {
+ * ktri KeyTransRecipientInfo,
+ * kari [1] KeyAgreeRecipientInfo,
+ * kekri [2] KEKRecipientInfo,
+ * pwri [3] PasswordRecipientInfo,
+ * ori [4] OtherRecipientInfo }
+ * </pre>
+ */
+public class RecipientInfo
+ extends ASN1Object
+ implements ASN1Choice
+{
+ ASN1Encodable info;
+
+ public RecipientInfo(
+ KeyTransRecipientInfo info)
+ {
+ this.info = info;
+ }
+
+ public RecipientInfo(
+ KeyAgreeRecipientInfo info)
+ {
+ this.info = new DERTaggedObject(false, 1, info);
+ }
+
+ public RecipientInfo(
+ KEKRecipientInfo info)
+ {
+ this.info = new DERTaggedObject(false, 2, info);
+ }
+
+ public RecipientInfo(
+ PasswordRecipientInfo info)
+ {
+ this.info = new DERTaggedObject(false, 3, info);
+ }
+
+ public RecipientInfo(
+ OtherRecipientInfo info)
+ {
+ this.info = new DERTaggedObject(false, 4, info);
+ }
+
+ public RecipientInfo(
+ ASN1Primitive info)
+ {
+ this.info = info;
+ }
+
+ /**
+ * Return a RecipientInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link RecipientInfo} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with RecipientInfo structure inside
+ * <li> {@link org.bouncycastle.asn1.ASN1TaggedObject#getInstance(java.lang.Object) ASN1TaggedObject} input formats with RecipientInfo structure inside
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static RecipientInfo getInstance(
+ Object o)
+ {
+ if (o == null || o instanceof RecipientInfo)
+ {
+ return (RecipientInfo)o;
+ }
+ else if (o instanceof ASN1Sequence)
+ {
+ return new RecipientInfo((ASN1Sequence)o);
+ }
+ else if (o instanceof ASN1TaggedObject)
+ {
+ return new RecipientInfo((ASN1TaggedObject)o);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: "
+ + o.getClass().getName());
+ }
+
+ public ASN1Integer getVersion()
+ {
+ if (info instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)info;
+
+ switch (o.getTagNo())
+ {
+ case 1:
+ return KeyAgreeRecipientInfo.getInstance(o, false).getVersion();
+ case 2:
+ return getKEKInfo(o).getVersion();
+ case 3:
+ return PasswordRecipientInfo.getInstance(o, false).getVersion();
+ case 4:
+ return new ASN1Integer(0); // no syntax version for OtherRecipientInfo
+ default:
+ throw new IllegalStateException("unknown tag");
+ }
+ }
+
+ return KeyTransRecipientInfo.getInstance(info).getVersion();
+ }
+
+ public boolean isTagged()
+ {
+ return (info instanceof ASN1TaggedObject);
+ }
+
+ public ASN1Encodable getInfo()
+ {
+ if (info instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)info;
+
+ switch (o.getTagNo())
+ {
+ case 1:
+ return KeyAgreeRecipientInfo.getInstance(o, false);
+ case 2:
+ return getKEKInfo(o);
+ case 3:
+ return PasswordRecipientInfo.getInstance(o, false);
+ case 4:
+ return OtherRecipientInfo.getInstance(o, false);
+ default:
+ throw new IllegalStateException("unknown tag");
+ }
+ }
+
+ return KeyTransRecipientInfo.getInstance(info);
+ }
+
+ private KEKRecipientInfo getKEKInfo(ASN1TaggedObject o)
+ {
+ if (o.isExplicit())
+ { // compatibilty with erroneous version
+ return KEKRecipientInfo.getInstance(o, true);
+ }
+ else
+ {
+ return KEKRecipientInfo.getInstance(o, false);
+ }
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return info.toASN1Primitive();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java
new file mode 100644
index 0000000..a680e4a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java
@@ -0,0 +1,171 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1GeneralizedTime;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
+ * Content encryption key delivery mechanisms.
+ * <p>
+ * <pre>
+ * RecipientKeyIdentifier ::= SEQUENCE {
+ * subjectKeyIdentifier SubjectKeyIdentifier,
+ * date GeneralizedTime OPTIONAL,
+ * other OtherKeyAttribute OPTIONAL
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ * </pre>
+ */
+public class RecipientKeyIdentifier
+ extends ASN1Object
+{
+ private ASN1OctetString subjectKeyIdentifier;
+ private ASN1GeneralizedTime date;
+ private OtherKeyAttribute other;
+
+ public RecipientKeyIdentifier(
+ ASN1OctetString subjectKeyIdentifier,
+ ASN1GeneralizedTime date,
+ OtherKeyAttribute other)
+ {
+ this.subjectKeyIdentifier = subjectKeyIdentifier;
+ this.date = date;
+ this.other = other;
+ }
+
+ public RecipientKeyIdentifier(
+ byte[] subjectKeyIdentifier,
+ ASN1GeneralizedTime date,
+ OtherKeyAttribute other)
+ {
+ this.subjectKeyIdentifier = new DEROctetString(subjectKeyIdentifier);
+ this.date = date;
+ this.other = other;
+ }
+
+ public RecipientKeyIdentifier(
+ byte[] subjectKeyIdentifier)
+ {
+ this(subjectKeyIdentifier, null, null);
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public RecipientKeyIdentifier(
+ ASN1Sequence seq)
+ {
+ subjectKeyIdentifier = ASN1OctetString.getInstance(
+ seq.getObjectAt(0));
+
+ switch(seq.size())
+ {
+ case 1:
+ break;
+ case 2:
+ if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime)
+ {
+ date = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
+ }
+ else
+ {
+ other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
+ }
+ break;
+ case 3:
+ date = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
+ other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid RecipientKeyIdentifier");
+ }
+ }
+
+ /**
+ * Return a RecipientKeyIdentifier object from a tagged object.
+ *
+ * @param ato the tagged object holding the object we want.
+ * @param isExplicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static RecipientKeyIdentifier getInstance(ASN1TaggedObject ato, boolean isExplicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(ato, isExplicit));
+ }
+
+ /**
+ * Return a RecipientKeyIdentifier object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link RecipientKeyIdentifier} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with RecipientKeyIdentifier structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static RecipientKeyIdentifier getInstance(Object obj)
+ {
+ if (obj instanceof RecipientKeyIdentifier)
+ {
+ return (RecipientKeyIdentifier)obj;
+ }
+
+ if(obj != null)
+ {
+ return new RecipientKeyIdentifier(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1OctetString getSubjectKeyIdentifier()
+ {
+ return subjectKeyIdentifier;
+ }
+
+ public ASN1GeneralizedTime getDate()
+ {
+ return date;
+ }
+
+ public OtherKeyAttribute getOtherKeyAttribute()
+ {
+ return other;
+ }
+
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(subjectKeyIdentifier);
+
+ if (date != null)
+ {
+ v.add(date);
+ }
+
+ if (other != null)
+ {
+ v.add(other);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java
new file mode 100644
index 0000000..52279c3
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java
@@ -0,0 +1,108 @@
+package org.bouncycastle.asn1.cms;
+
+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.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5940">RFC 5940</a>:
+ * Additional Cryptographic Message Syntax (CMS) Revocation Information Choices.
+ * <p>
+ * <pre>
+ * SCVPReqRes ::= SEQUENCE {
+ * request [0] EXPLICIT ContentInfo OPTIONAL,
+ * response ContentInfo }
+ * </pre>
+ */
+public class SCVPReqRes
+ extends ASN1Object
+{
+ private final ContentInfo request;
+ private final ContentInfo response;
+
+ /**
+ * Return a SCVPReqRes object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link SCVPReqRes} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with SCVPReqRes structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static SCVPReqRes getInstance(
+ Object obj)
+ {
+ if (obj instanceof SCVPReqRes)
+ {
+ return (SCVPReqRes)obj;
+ }
+ else if (obj != null)
+ {
+ return new SCVPReqRes(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private SCVPReqRes(
+ ASN1Sequence seq)
+ {
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ this.request = ContentInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(0)), true);
+ this.response = ContentInfo.getInstance(seq.getObjectAt(1));
+ }
+ else
+ {
+ this.request = null;
+ this.response = ContentInfo.getInstance(seq.getObjectAt(0));
+ }
+ }
+
+ public SCVPReqRes(ContentInfo response)
+ {
+ this.request = null; // use of this confuses earlier JDKs
+ this.response = response;
+ }
+
+ public SCVPReqRes(ContentInfo request, ContentInfo response)
+ {
+ this.request = request;
+ this.response = response;
+ }
+
+ public ContentInfo getRequest()
+ {
+ return request;
+ }
+
+ public ContentInfo getResponse()
+ {
+ return response;
+ }
+
+ /**
+ * @return the ASN.1 primitive representation.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (request != null)
+ {
+ v.add(new DERTaggedObject(true, 0, request));
+ }
+
+ v.add(response);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedDataParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedDataParser.java
new file mode 100644
index 0000000..df22b8e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedDataParser.java
@@ -0,0 +1,141 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.ASN1Set;
+import org.bouncycastle.asn1.ASN1SetParser;
+import org.bouncycastle.asn1.ASN1TaggedObjectParser;
+import org.bouncycastle.asn1.BERTags;
+
+/**
+ * Parser for <a href="http://tools.ietf.org/html/rfc5652#section-5.1">RFC 5652</a>: {@link SignedData} object.
+ * <p>
+ * <pre>
+ * SignedData ::= SEQUENCE {
+ * version CMSVersion,
+ * digestAlgorithms DigestAlgorithmIdentifiers,
+ * encapContentInfo EncapsulatedContentInfo,
+ * certificates [0] IMPLICIT CertificateSet OPTIONAL,
+ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ * signerInfos SignerInfos
+ * }
+ * </pre>
+ */
+public class SignedDataParser
+{
+ private ASN1SequenceParser _seq;
+ private ASN1Integer _version;
+ private Object _nextObject;
+ private boolean _certsCalled;
+ private boolean _crlsCalled;
+
+ public static SignedDataParser getInstance(
+ Object o)
+ throws IOException
+ {
+ if (o instanceof ASN1Sequence)
+ {
+ return new SignedDataParser(((ASN1Sequence)o).parser());
+ }
+ if (o instanceof ASN1SequenceParser)
+ {
+ return new SignedDataParser((ASN1SequenceParser)o);
+ }
+
+ throw new IOException("unknown object encountered: " + o.getClass().getName());
+ }
+
+ private SignedDataParser(
+ ASN1SequenceParser seq)
+ throws IOException
+ {
+ this._seq = seq;
+ this._version = (ASN1Integer)seq.readObject();
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return _version;
+ }
+
+ public ASN1SetParser getDigestAlgorithms()
+ throws IOException
+ {
+ Object o = _seq.readObject();
+
+ if (o instanceof ASN1Set)
+ {
+ return ((ASN1Set)o).parser();
+ }
+
+ return (ASN1SetParser)o;
+ }
+
+ public ContentInfoParser getEncapContentInfo()
+ throws IOException
+ {
+ return new ContentInfoParser((ASN1SequenceParser)_seq.readObject());
+ }
+
+ public ASN1SetParser getCertificates()
+ throws IOException
+ {
+ _certsCalled = true;
+ _nextObject = _seq.readObject();
+
+ if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 0)
+ {
+ ASN1SetParser certs = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false);
+ _nextObject = null;
+
+ return certs;
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getCrls()
+ throws IOException
+ {
+ if (!_certsCalled)
+ {
+ throw new IOException("getCerts() has not been called.");
+ }
+
+ _crlsCalled = true;
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.readObject();
+ }
+
+ if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 1)
+ {
+ ASN1SetParser crls = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false);
+ _nextObject = null;
+
+ return crls;
+ }
+
+ return null;
+ }
+
+ public ASN1SetParser getSignerInfos()
+ throws IOException
+ {
+ if (!_certsCalled || !_crlsCalled)
+ {
+ throw new IOException("getCerts() and/or getCrls() has not been called.");
+ }
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.readObject();
+ }
+
+ return (ASN1SetParser)_nextObject;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java
new file mode 100644
index 0000000..f6d8d5a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java
@@ -0,0 +1,96 @@
+package org.bouncycastle.asn1.cms;
+
+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;
+import org.bouncycastle.asn1.x509.CertificateList;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5544">RFC 5544</a>
+ * Binding Documents with Time-Stamps; TimeStampAndCRL object.
+ * <pre>
+ * TimeStampAndCRL ::= SEQUENCE {
+ * timeStamp TimeStampToken, -- according to RFC 3161
+ * crl CertificateList OPTIONAL -- according to RFC 5280
+ * }
+ * </pre>
+ */
+public class TimeStampAndCRL
+ extends ASN1Object
+{
+ private ContentInfo timeStamp;
+ private CertificateList crl;
+
+ public TimeStampAndCRL(ContentInfo timeStamp)
+ {
+ this.timeStamp = timeStamp;
+ }
+
+ private TimeStampAndCRL(ASN1Sequence seq)
+ {
+ this.timeStamp = ContentInfo.getInstance(seq.getObjectAt(0));
+ if (seq.size() == 2)
+ {
+ this.crl = CertificateList.getInstance(seq.getObjectAt(1));
+ }
+ }
+
+ /**
+ * Return a TimeStampAndCRL object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link TimeStampAndCRL} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with TimeStampAndCRL structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static TimeStampAndCRL getInstance(Object obj)
+ {
+ if (obj instanceof TimeStampAndCRL)
+ {
+ return (TimeStampAndCRL)obj;
+ }
+ else if (obj != null)
+ {
+ return new TimeStampAndCRL(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ContentInfo getTimeStampToken()
+ {
+ return this.timeStamp;
+ }
+
+ /** @deprecated use getCRL() */
+ public CertificateList getCertificateList()
+ {
+ return this.crl;
+ }
+
+ public CertificateList getCRL()
+ {
+ return this.crl;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(timeStamp);
+
+ if (crl != null)
+ {
+ v.add(crl);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampTokenEvidence.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampTokenEvidence.java
new file mode 100644
index 0000000..5461147
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampTokenEvidence.java
@@ -0,0 +1,98 @@
+package org.bouncycastle.asn1.cms;
+
+import java.util.Enumeration;
+
+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.DERSequence;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5544">RFC 5544</a>
+ * Binding Documents with Time-Stamps; TimeStampTokenEvidence object.
+ * <pre>
+ * TimeStampTokenEvidence ::=
+ * SEQUENCE SIZE(1..MAX) OF TimeStampAndCRL
+ * </pre>
+ */
+public class TimeStampTokenEvidence
+ extends ASN1Object
+{
+ private TimeStampAndCRL[] timeStampAndCRLs;
+
+ public TimeStampTokenEvidence(TimeStampAndCRL[] timeStampAndCRLs)
+ {
+ this.timeStampAndCRLs = timeStampAndCRLs;
+ }
+
+ public TimeStampTokenEvidence(TimeStampAndCRL timeStampAndCRL)
+ {
+ this.timeStampAndCRLs = new TimeStampAndCRL[1];
+
+ timeStampAndCRLs[0] = timeStampAndCRL;
+ }
+
+ private TimeStampTokenEvidence(ASN1Sequence seq)
+ {
+ this.timeStampAndCRLs = new TimeStampAndCRL[seq.size()];
+
+ int count = 0;
+
+ for (Enumeration en = seq.getObjects(); en.hasMoreElements();)
+ {
+ timeStampAndCRLs[count++] = TimeStampAndCRL.getInstance(en.nextElement());
+ }
+ }
+
+ public static TimeStampTokenEvidence getInstance(ASN1TaggedObject tagged, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(tagged, explicit));
+ }
+
+ /**
+ * Return a TimeStampTokenEvidence object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link TimeStampTokenEvidence} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with TimeStampTokenEvidence structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static TimeStampTokenEvidence getInstance(Object obj)
+ {
+ if (obj instanceof TimeStampTokenEvidence)
+ {
+ return (TimeStampTokenEvidence)obj;
+ }
+ else if (obj != null)
+ {
+ return new TimeStampTokenEvidence(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public TimeStampAndCRL[] toTimeStampAndCRLArray()
+ {
+ return timeStampAndCRLs;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != timeStampAndCRLs.length; i++)
+ {
+ v.add(timeStampAndCRLs[i]);
+ }
+
+ return new DERSequence(v);
+ }
+
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java
new file mode 100644
index 0000000..f19061e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java
@@ -0,0 +1,131 @@
+package org.bouncycastle.asn1.cms;
+
+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.BERSequence;
+import org.bouncycastle.asn1.DERIA5String;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5544">RFC 5544</a>:
+ * Binding Documents with Time-Stamps; TimeStampedData object.
+ * <p>
+ * <pre>
+ * TimeStampedData ::= SEQUENCE {
+ * version INTEGER { v1(1) },
+ * dataUri IA5String OPTIONAL,
+ * metaData MetaData OPTIONAL,
+ * content OCTET STRING OPTIONAL,
+ * temporalEvidence Evidence
+ * }
+ * </pre>
+ */
+public class TimeStampedData
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private DERIA5String dataUri;
+ private MetaData metaData;
+ private ASN1OctetString content;
+ private Evidence temporalEvidence;
+
+ public TimeStampedData(DERIA5String dataUri, MetaData metaData, ASN1OctetString content, Evidence temporalEvidence)
+ {
+ this.version = new ASN1Integer(1);
+ this.dataUri = dataUri;
+ this.metaData = metaData;
+ this.content = content;
+ this.temporalEvidence = temporalEvidence;
+ }
+
+ private TimeStampedData(ASN1Sequence seq)
+ {
+ this.version = ASN1Integer.getInstance(seq.getObjectAt(0));
+
+ int index = 1;
+ if (seq.getObjectAt(index) instanceof DERIA5String)
+ {
+ this.dataUri = DERIA5String.getInstance(seq.getObjectAt(index++));
+ }
+ if (seq.getObjectAt(index) instanceof MetaData || seq.getObjectAt(index) instanceof ASN1Sequence)
+ {
+ this.metaData = MetaData.getInstance(seq.getObjectAt(index++));
+ }
+ if (seq.getObjectAt(index) instanceof ASN1OctetString)
+ {
+ this.content = ASN1OctetString.getInstance(seq.getObjectAt(index++));
+ }
+ this.temporalEvidence = Evidence.getInstance(seq.getObjectAt(index));
+ }
+
+ /**
+ * Return a TimeStampedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link RecipientKeyIdentifier} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with TimeStampedData structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static TimeStampedData getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof TimeStampedData)
+ {
+ return (TimeStampedData)obj;
+ }
+ return new TimeStampedData(ASN1Sequence.getInstance(obj));
+ }
+
+ public DERIA5String getDataUri()
+ {
+ return dataUri;
+ }
+
+ public MetaData getMetaData()
+ {
+ return metaData;
+ }
+
+ public ASN1OctetString getContent()
+ {
+ return content;
+ }
+
+ public Evidence getTemporalEvidence()
+ {
+ return temporalEvidence;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+
+ if (dataUri != null)
+ {
+ v.add(dataUri);
+ }
+
+ if (metaData != null)
+ {
+ v.add(metaData);
+ }
+
+ if (content != null)
+ {
+ v.add(content);
+ }
+
+ v.add(temporalEvidence);
+
+ return new BERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedDataParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedDataParser.java
new file mode 100644
index 0000000..f53e00f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/TimeStampedDataParser.java
@@ -0,0 +1,141 @@
+package org.bouncycastle.asn1.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1OctetStringParser;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1SequenceParser;
+import org.bouncycastle.asn1.BERSequence;
+import org.bouncycastle.asn1.DERIA5String;
+
+/**
+ * Parser for <a href="http://tools.ietf.org/html/rfc5544">RFC 5544</a>:
+ * {@link TimeStampedData} object.
+ * <p>
+ * <pre>
+ * TimeStampedData ::= SEQUENCE {
+ * version INTEGER { v1(1) },
+ * dataUri IA5String OPTIONAL,
+ * metaData MetaData OPTIONAL,
+ * content OCTET STRING OPTIONAL,
+ * temporalEvidence Evidence
+ * }
+ * </pre>
+ */
+public class TimeStampedDataParser
+{
+ private ASN1Integer version;
+ private DERIA5String dataUri;
+ private MetaData metaData;
+ private ASN1OctetStringParser content;
+ private Evidence temporalEvidence;
+ private ASN1SequenceParser parser;
+
+ private TimeStampedDataParser(ASN1SequenceParser parser)
+ throws IOException
+ {
+ this.parser = parser;
+ this.version = ASN1Integer.getInstance(parser.readObject());
+
+ ASN1Encodable obj = parser.readObject();
+
+ if (obj instanceof DERIA5String)
+ {
+ this.dataUri = DERIA5String.getInstance(obj);
+ obj = parser.readObject();
+ }
+ if (obj instanceof MetaData || obj instanceof ASN1SequenceParser)
+ {
+ this.metaData = MetaData.getInstance(obj.toASN1Primitive());
+ obj = parser.readObject();
+ }
+ if (obj instanceof ASN1OctetStringParser)
+ {
+ this.content = (ASN1OctetStringParser)obj;
+ }
+ }
+
+ public static TimeStampedDataParser getInstance(Object obj)
+ throws IOException
+ {
+ if (obj instanceof ASN1Sequence)
+ {
+ return new TimeStampedDataParser(((ASN1Sequence)obj).parser());
+ }
+ if (obj instanceof ASN1SequenceParser)
+ {
+ return new TimeStampedDataParser((ASN1SequenceParser)obj);
+ }
+
+ return null;
+ }
+
+ public DERIA5String getDataUri()
+ {
+ return dataUri;
+ }
+
+ public MetaData getMetaData()
+ {
+ return metaData;
+ }
+
+ public ASN1OctetStringParser getContent()
+ {
+ return content;
+ }
+
+ public Evidence getTemporalEvidence()
+ throws IOException
+ {
+ if (temporalEvidence == null)
+ {
+ temporalEvidence = Evidence.getInstance(parser.readObject().toASN1Primitive());
+ }
+
+ return temporalEvidence;
+ }
+
+ /**
+ * <pre>
+ * TimeStampedData ::= SEQUENCE {
+ * version INTEGER { v1(1) },
+ * dataUri IA5String OPTIONAL,
+ * metaData MetaData OPTIONAL,
+ * content OCTET STRING OPTIONAL,
+ * temporalEvidence Evidence
+ * }
+ * </pre>
+ * @return
+ * @deprecated will be removed
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(version);
+
+ if (dataUri != null)
+ {
+ v.add(dataUri);
+ }
+
+ if (metaData != null)
+ {
+ v.add(metaData);
+ }
+
+ if (content != null)
+ {
+ v.add(content);
+ }
+
+ v.add(temporalEvidence);
+
+ return new BERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/MQVuserKeyingMaterial.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/MQVuserKeyingMaterial.java
new file mode 100644
index 0000000..bd7267b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/MQVuserKeyingMaterial.java
@@ -0,0 +1,122 @@
+package org.bouncycastle.asn1.cms.ecc;
+
+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.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.cms.OriginatorPublicKey;
+
+/**
+ * <a href="http://tools.ietf.org/html/rfc5753">RFC 5753/3278</a>: MQVuserKeyingMaterial object.
+ * <pre>
+ * MQVuserKeyingMaterial ::= SEQUENCE {
+ * ephemeralPublicKey OriginatorPublicKey,
+ * addedukm [0] EXPLICIT UserKeyingMaterial OPTIONAL }
+ * </pre>
+ */
+public class MQVuserKeyingMaterial
+ extends ASN1Object
+{
+ private OriginatorPublicKey ephemeralPublicKey;
+ private ASN1OctetString addedukm;
+
+ public MQVuserKeyingMaterial(
+ OriginatorPublicKey ephemeralPublicKey,
+ ASN1OctetString addedukm)
+ {
+ // TODO Check ephemeralPublicKey not null
+
+ this.ephemeralPublicKey = ephemeralPublicKey;
+ this.addedukm = addedukm;
+ }
+
+ private MQVuserKeyingMaterial(
+ ASN1Sequence seq)
+ {
+ // TODO Check seq has either 1 or 2 elements
+
+ this.ephemeralPublicKey = OriginatorPublicKey.getInstance(
+ seq.getObjectAt(0));
+
+ if (seq.size() > 1)
+ {
+ this.addedukm = ASN1OctetString.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true);
+ }
+ }
+
+ /**
+ * Return an MQVuserKeyingMaterial object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @throws IllegalArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static MQVuserKeyingMaterial getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an MQVuserKeyingMaterial object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link MQVuserKeyingMaterial} object
+ * <li> {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence} with MQVuserKeyingMaterial inside it.
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @throws IllegalArgumentException if the object cannot be converted.
+ */
+ public static MQVuserKeyingMaterial getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof MQVuserKeyingMaterial)
+ {
+ return (MQVuserKeyingMaterial)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new MQVuserKeyingMaterial((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid MQVuserKeyingMaterial: " + obj.getClass().getName());
+ }
+
+ public OriginatorPublicKey getEphemeralPublicKey()
+ {
+ return ephemeralPublicKey;
+ }
+
+ public ASN1OctetString getAddedukm()
+ {
+ return addedukm;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ v.add(ephemeralPublicKey);
+
+ if (addedukm != null)
+ {
+ v.add(new DERTaggedObject(true, 0, addedukm));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/package.html b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/package.html
new file mode 100644
index 0000000..9d33025
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ecc/package.html
@@ -0,0 +1,5 @@
+<html>
+<body bgcolor="#ffffff">
+Support classes for CMS ECC - RFC 5753/3278.
+</body>
+</html>
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/package.html b/bcprov/src/main/java/org/bouncycastle/asn1/cms/package.html
new file mode 100644
index 0000000..c165a7a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/package.html
@@ -0,0 +1,5 @@
+<html>
+<body bgcolor="#ffffff">
+Support classes useful for encoding and supporting Cryptographic Message Syntax as described in PKCS#7 and RFC 3369 (formerly RFC 2630).
+</body>
+</html>