Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/spongycastle/asn1/dvcs')
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/CertEtcToken.java171
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfo.java302
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfoBuilder.java151
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSErrorNotice.java96
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSObjectIdentifiers.java29
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequest.java107
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformation.java271
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformationBuilder.java224
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSResponse.java117
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/DVCSTime.java111
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/Data.java149
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/PathProcInput.java180
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/ServiceType.java92
-rw-r--r--core/src/main/java/org/spongycastle/asn1/dvcs/TargetEtcChain.java191
14 files changed, 2191 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/CertEtcToken.java b/core/src/main/java/org/spongycastle/asn1/dvcs/CertEtcToken.java
new file mode 100644
index 00000000..7774ade8
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/CertEtcToken.java
@@ -0,0 +1,171 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1Choice;
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cmp.PKIStatusInfo;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.ess.ESSCertID;
+import org.spongycastle.asn1.ocsp.CertID;
+import org.spongycastle.asn1.ocsp.CertStatus;
+import org.spongycastle.asn1.ocsp.OCSPResponse;
+import org.spongycastle.asn1.smime.SMIMECapabilities;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.asn1.x509.Extension;
+
+/**
+ * <pre>
+ * CertEtcToken ::= CHOICE {
+ * certificate [0] IMPLICIT Certificate ,
+ * esscertid [1] ESSCertId ,
+ * pkistatus [2] IMPLICIT PKIStatusInfo ,
+ * assertion [3] ContentInfo ,
+ * crl [4] IMPLICIT CertificateList,
+ * ocspcertstatus [5] CertStatus,
+ * oscpcertid [6] IMPLICIT CertId ,
+ * oscpresponse [7] IMPLICIT OCSPResponse,
+ * capabilities [8] SMIMECapabilities,
+ * extension Extension
+ * }
+ * </pre>
+ */
+public class CertEtcToken
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static final int TAG_CERTIFICATE = 0;
+ public static final int TAG_ESSCERTID = 1;
+ public static final int TAG_PKISTATUS = 2;
+ public static final int TAG_ASSERTION = 3;
+ public static final int TAG_CRL = 4;
+ public static final int TAG_OCSPCERTSTATUS = 5;
+ public static final int TAG_OCSPCERTID = 6;
+ public static final int TAG_OCSPRESPONSE = 7;
+ public static final int TAG_CAPABILITIES = 8;
+
+ private static final boolean[] explicit = new boolean[]
+ {
+ false, true, false, true, false, true, false, false, true
+ };
+
+ private int tagNo;
+ private ASN1Encodable value;
+ private Extension extension;
+
+ public CertEtcToken(int tagNo, ASN1Encodable value)
+ {
+ this.tagNo = tagNo;
+ this.value = value;
+ }
+
+ public CertEtcToken(Extension extension)
+ {
+ this.tagNo = -1;
+ this.extension = extension;
+ }
+
+ private CertEtcToken(ASN1TaggedObject choice)
+ {
+ this.tagNo = choice.getTagNo();
+
+ switch (tagNo)
+ {
+ case TAG_CERTIFICATE:
+ value = Certificate.getInstance(choice, false);
+ break;
+ case TAG_ESSCERTID:
+ value = ESSCertID.getInstance(choice.getObject());
+ break;
+ case TAG_PKISTATUS:
+ value = PKIStatusInfo.getInstance(choice, false);
+ break;
+ case TAG_ASSERTION:
+ value = ContentInfo.getInstance(choice.getObject());
+ break;
+ case TAG_CRL:
+ value = CertificateList.getInstance(choice, false);
+ break;
+ case TAG_OCSPCERTSTATUS:
+ value = CertStatus.getInstance(choice.getObject());
+ break;
+ case TAG_OCSPCERTID:
+ value = CertID.getInstance(choice, false);
+ break;
+ case TAG_OCSPRESPONSE:
+ value = OCSPResponse.getInstance(choice, false);
+ break;
+ case TAG_CAPABILITIES:
+ value = SMIMECapabilities.getInstance(choice.getObject());
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag: " + tagNo);
+ }
+ }
+
+ public static CertEtcToken getInstance(Object obj)
+ {
+ if (obj instanceof CertEtcToken)
+ {
+ return (CertEtcToken)obj;
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new CertEtcToken((ASN1TaggedObject)obj);
+ }
+ else if (obj != null)
+ {
+ return new CertEtcToken(Extension.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (extension == null)
+ {
+ return new DERTaggedObject(explicit[tagNo], tagNo, value);
+ }
+ else
+ {
+ return extension.toASN1Primitive();
+ }
+ }
+
+ public int getTagNo()
+ {
+ return tagNo;
+ }
+
+ public ASN1Encodable getValue()
+ {
+ return value;
+ }
+
+ public Extension getExtension()
+ {
+ return extension;
+ }
+
+ public String toString()
+ {
+ return "CertEtcToken {\n" + value + "}\n";
+ }
+
+ public static CertEtcToken[] arrayFromSequence(ASN1Sequence seq)
+ {
+ CertEtcToken[] tmp = new CertEtcToken[seq.size()];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ tmp[i] = CertEtcToken.getInstance(seq.getObjectAt(i));
+ }
+
+ return tmp;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfo.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfo.java
new file mode 100644
index 00000000..3c231b44
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfo.java
@@ -0,0 +1,302 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cmp.PKIStatusInfo;
+import org.spongycastle.asn1.x509.DigestInfo;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.PolicyInformation;
+
+/**
+ * <pre>
+ * DVCSCertInfo::= SEQUENCE {
+ * version Integer DEFAULT 1 ,
+ * dvReqInfo DVCSRequestInformation,
+ * messageImprint DigestInfo,
+ * serialNumber Integer,
+ * responseTime DVCSTime,
+ * dvStatus [0] PKIStatusInfo OPTIONAL,
+ * policy [1] PolicyInformation OPTIONAL,
+ * reqSignature [2] SignerInfos OPTIONAL,
+ * certs [3] SEQUENCE SIZE (1..MAX) OF
+ * TargetEtcChain OPTIONAL,
+ * extensions Extensions OPTIONAL
+ * }
+ * </pre>
+ */
+
+public class DVCSCertInfo
+ extends ASN1Object
+{
+
+ private int version = DEFAULT_VERSION;
+ private DVCSRequestInformation dvReqInfo;
+ private DigestInfo messageImprint;
+ private ASN1Integer serialNumber;
+ private DVCSTime responseTime;
+ private PKIStatusInfo dvStatus;
+ private PolicyInformation policy;
+ private ASN1Set reqSignature;
+ private ASN1Sequence certs;
+ private Extensions extensions;
+
+ private static final int DEFAULT_VERSION = 1;
+ private static final int TAG_DV_STATUS = 0;
+ private static final int TAG_POLICY = 1;
+ private static final int TAG_REQ_SIGNATURE = 2;
+ private static final int TAG_CERTS = 3;
+
+ public DVCSCertInfo(
+ DVCSRequestInformation dvReqInfo,
+ DigestInfo messageImprint,
+ ASN1Integer serialNumber,
+ DVCSTime responseTime)
+ {
+ this.dvReqInfo = dvReqInfo;
+ this.messageImprint = messageImprint;
+ this.serialNumber = serialNumber;
+ this.responseTime = responseTime;
+ }
+
+ private DVCSCertInfo(ASN1Sequence seq)
+ {
+ int i = 0;
+ ASN1Encodable x = seq.getObjectAt(i++);
+ try
+ {
+ ASN1Integer encVersion = ASN1Integer.getInstance(x);
+ this.version = encVersion.getValue().intValue();
+ x = seq.getObjectAt(i++);
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+
+ this.dvReqInfo = DVCSRequestInformation.getInstance(x);
+ x = seq.getObjectAt(i++);
+ this.messageImprint = DigestInfo.getInstance(x);
+ x = seq.getObjectAt(i++);
+ this.serialNumber = ASN1Integer.getInstance(x);
+ x = seq.getObjectAt(i++);
+ this.responseTime = DVCSTime.getInstance(x);
+
+ while (i < seq.size())
+ {
+
+ x = seq.getObjectAt(i++);
+
+ try
+ {
+ ASN1TaggedObject t = ASN1TaggedObject.getInstance(x);
+ int tagNo = t.getTagNo();
+
+ switch (tagNo)
+ {
+ case TAG_DV_STATUS:
+ this.dvStatus = PKIStatusInfo.getInstance(t, false);
+ break;
+ case TAG_POLICY:
+ this.policy = PolicyInformation.getInstance(ASN1Sequence.getInstance(t, false));
+ break;
+ case TAG_REQ_SIGNATURE:
+ this.reqSignature = ASN1Set.getInstance(t, false);
+ break;
+ case TAG_CERTS:
+ this.certs = ASN1Sequence.getInstance(t, false);
+ break;
+ }
+
+ continue;
+
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+
+ try
+ {
+ this.extensions = Extensions.getInstance(x);
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+
+ }
+
+ }
+
+ public static DVCSCertInfo getInstance(Object obj)
+ {
+ if (obj instanceof DVCSCertInfo)
+ {
+ return (DVCSCertInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new DVCSCertInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static DVCSCertInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (version != DEFAULT_VERSION)
+ {
+ v.add(new ASN1Integer(version));
+ }
+ v.add(dvReqInfo);
+ v.add(messageImprint);
+ v.add(serialNumber);
+ v.add(responseTime);
+ if (dvStatus != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_DV_STATUS, dvStatus));
+ }
+ if (policy != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_POLICY, policy));
+ }
+ if (reqSignature != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_REQ_SIGNATURE, reqSignature));
+ }
+ if (certs != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_CERTS, certs));
+ }
+ if (extensions != null)
+ {
+ v.add(extensions);
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+
+ s.append("DVCSCertInfo {\n");
+
+ if (version != DEFAULT_VERSION)
+ {
+ s.append("version: " + version + "\n");
+ }
+ s.append("dvReqInfo: " + dvReqInfo + "\n");
+ s.append("messageImprint: " + messageImprint + "\n");
+ s.append("serialNumber: " + serialNumber + "\n");
+ s.append("responseTime: " + responseTime + "\n");
+ if (dvStatus != null)
+ {
+ s.append("dvStatus: " + dvStatus + "\n");
+ }
+ if (policy != null)
+ {
+ s.append("policy: " + policy + "\n");
+ }
+ if (reqSignature != null)
+ {
+ s.append("reqSignature: " + reqSignature + "\n");
+ }
+ if (certs != null)
+ {
+ s.append("certs: " + certs + "\n");
+ }
+ if (extensions != null)
+ {
+ s.append("extensions: " + extensions + "\n");
+ }
+
+ s.append("}\n");
+ return s.toString();
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ private void setVersion(int version)
+ {
+ this.version = version;
+ }
+
+ public DVCSRequestInformation getDvReqInfo()
+ {
+ return dvReqInfo;
+ }
+
+ private void setDvReqInfo(DVCSRequestInformation dvReqInfo)
+ {
+ this.dvReqInfo = dvReqInfo;
+ }
+
+ public DigestInfo getMessageImprint()
+ {
+ return messageImprint;
+ }
+
+ private void setMessageImprint(DigestInfo messageImprint)
+ {
+ this.messageImprint = messageImprint;
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public DVCSTime getResponseTime()
+ {
+ return responseTime;
+ }
+
+ public PKIStatusInfo getDvStatus()
+ {
+ return dvStatus;
+ }
+
+ public PolicyInformation getPolicy()
+ {
+ return policy;
+ }
+
+ public ASN1Set getReqSignature()
+ {
+ return reqSignature;
+ }
+
+ public TargetEtcChain[] getCerts()
+ {
+ if (certs != null)
+ {
+ return TargetEtcChain.arrayFromSequence(certs);
+ }
+
+ return null;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfoBuilder.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfoBuilder.java
new file mode 100644
index 00000000..47ba84e4
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSCertInfoBuilder.java
@@ -0,0 +1,151 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cmp.PKIStatusInfo;
+import org.spongycastle.asn1.x509.DigestInfo;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.PolicyInformation;
+
+/**
+ * <pre>
+ * DVCSCertInfo::= SEQUENCE {
+ * version Integer DEFAULT 1 ,
+ * dvReqInfo DVCSRequestInformation,
+ * messageImprint DigestInfo,
+ * serialNumber Integer,
+ * responseTime DVCSTime,
+ * dvStatus [0] PKIStatusInfo OPTIONAL,
+ * policy [1] PolicyInformation OPTIONAL,
+ * reqSignature [2] SignerInfos OPTIONAL,
+ * certs [3] SEQUENCE SIZE (1..MAX) OF
+ * TargetEtcChain OPTIONAL,
+ * extensions Extensions OPTIONAL
+ * }
+ * </pre>
+ */
+
+public class DVCSCertInfoBuilder
+{
+
+ private int version = DEFAULT_VERSION;
+ private DVCSRequestInformation dvReqInfo;
+ private DigestInfo messageImprint;
+ private ASN1Integer serialNumber;
+ private DVCSTime responseTime;
+ private PKIStatusInfo dvStatus;
+ private PolicyInformation policy;
+ private ASN1Set reqSignature;
+ private ASN1Sequence certs;
+ private Extensions extensions;
+
+ private static final int DEFAULT_VERSION = 1;
+ private static final int TAG_DV_STATUS = 0;
+ private static final int TAG_POLICY = 1;
+ private static final int TAG_REQ_SIGNATURE = 2;
+ private static final int TAG_CERTS = 3;
+
+ public DVCSCertInfoBuilder(
+ DVCSRequestInformation dvReqInfo,
+ DigestInfo messageImprint,
+ ASN1Integer serialNumber,
+ DVCSTime responseTime)
+ {
+ this.dvReqInfo = dvReqInfo;
+ this.messageImprint = messageImprint;
+ this.serialNumber = serialNumber;
+ this.responseTime = responseTime;
+ }
+
+ public DVCSCertInfo build()
+ {
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (version != DEFAULT_VERSION)
+ {
+ v.add(new ASN1Integer(version));
+ }
+ v.add(dvReqInfo);
+ v.add(messageImprint);
+ v.add(serialNumber);
+ v.add(responseTime);
+ if (dvStatus != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_DV_STATUS, dvStatus));
+ }
+ if (policy != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_POLICY, policy));
+ }
+ if (reqSignature != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_REQ_SIGNATURE, reqSignature));
+ }
+ if (certs != null)
+ {
+ v.add(new DERTaggedObject(false, TAG_CERTS, certs));
+ }
+ if (extensions != null)
+ {
+ v.add(extensions);
+ }
+
+ return DVCSCertInfo.getInstance(new DERSequence(v));
+ }
+
+ public void setVersion(int version)
+ {
+ this.version = version;
+ }
+
+ public void setDvReqInfo(DVCSRequestInformation dvReqInfo)
+ {
+ this.dvReqInfo = dvReqInfo;
+ }
+
+ public void setMessageImprint(DigestInfo messageImprint)
+ {
+ this.messageImprint = messageImprint;
+ }
+
+ public void setSerialNumber(ASN1Integer serialNumber)
+ {
+ this.serialNumber = serialNumber;
+ }
+
+ public void setResponseTime(DVCSTime responseTime)
+ {
+ this.responseTime = responseTime;
+ }
+
+ public void setDvStatus(PKIStatusInfo dvStatus)
+ {
+ this.dvStatus = dvStatus;
+ }
+
+ public void setPolicy(PolicyInformation policy)
+ {
+ this.policy = policy;
+ }
+
+ public void setReqSignature(ASN1Set reqSignature)
+ {
+ this.reqSignature = reqSignature;
+ }
+
+ public void setCerts(TargetEtcChain[] certs)
+ {
+ this.certs = new DERSequence(certs);
+ }
+
+ public void setExtensions(Extensions extensions)
+ {
+ this.extensions = extensions;
+ }
+
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSErrorNotice.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSErrorNotice.java
new file mode 100644
index 00000000..2bd13ea9
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSErrorNotice.java
@@ -0,0 +1,96 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cmp.PKIStatusInfo;
+import org.spongycastle.asn1.x509.GeneralName;
+
+/**
+ * <pre>
+ * DVCSErrorNotice ::= SEQUENCE {
+ * transactionStatus PKIStatusInfo ,
+ * transactionIdentifier GeneralName OPTIONAL
+ * }
+ * </pre>
+ */
+public class DVCSErrorNotice
+ extends ASN1Object
+{
+ private PKIStatusInfo transactionStatus;
+ private GeneralName transactionIdentifier;
+
+ public DVCSErrorNotice(PKIStatusInfo status)
+ {
+ this(status, null);
+ }
+
+ public DVCSErrorNotice(PKIStatusInfo status, GeneralName transactionIdentifier)
+ {
+ this.transactionStatus = status;
+ this.transactionIdentifier = transactionIdentifier;
+ }
+
+ private DVCSErrorNotice(ASN1Sequence seq)
+ {
+ this.transactionStatus = PKIStatusInfo.getInstance(seq.getObjectAt(0));
+ if (seq.size() > 1)
+ {
+ this.transactionIdentifier = GeneralName.getInstance(seq.getObjectAt(1));
+ }
+ }
+
+ public static DVCSErrorNotice getInstance(Object obj)
+ {
+ if (obj instanceof DVCSErrorNotice)
+ {
+ return (DVCSErrorNotice)obj;
+ }
+ else if (obj != null)
+ {
+ return new DVCSErrorNotice(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static DVCSErrorNotice getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ v.add(transactionStatus);
+ if (transactionIdentifier != null)
+ {
+ v.add(transactionIdentifier);
+ }
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ return "DVCSErrorNotice {\n" +
+ "transactionStatus: " + transactionStatus + "\n" +
+ (transactionIdentifier != null ? "transactionIdentifier: " + transactionIdentifier + "\n" : "") +
+ "}\n";
+ }
+
+
+ public PKIStatusInfo getTransactionStatus()
+ {
+ return transactionStatus;
+ }
+
+ public GeneralName getTransactionIdentifier()
+ {
+ return transactionIdentifier;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSObjectIdentifiers.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSObjectIdentifiers.java
new file mode 100644
index 00000000..02915089
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSObjectIdentifiers.java
@@ -0,0 +1,29 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * OIDs for <a href="http://tools.ietf.org/html/rfc3029">RFC 3029</a>
+ * Data Validation and Certification Server Protocols
+ */
+public interface DVCSObjectIdentifiers
+{
+ /** Base OID id-pkix: 1.3.6.1.5.5.7 */
+ static final ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7");
+ /** Base OID id-smime: 1.2.840.113549.1.9.16 */
+ static final ASN1ObjectIdentifier id_smime = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16");
+
+ /** Authority Information Access for DVCS; id-ad-dcvs; OID: 1.3.6.1.5.5.7.48.4 */
+ static final ASN1ObjectIdentifier id_ad_dvcs = id_pkix.branch("48.4");
+
+ /** Key Purpose for DVCS; id-kp-dvcs; OID: 1.3.6.1.5.5.7.3.10 */
+ static final ASN1ObjectIdentifier id_kp_dvcs = id_pkix.branch("3.10");
+
+ /** SMIME eContentType id-ct-DVCSRequestData; OID: 1.2.840.113549.1.9.16.1.7 */
+ static final ASN1ObjectIdentifier id_ct_DVCSRequestData = id_smime.branch("1.7");
+ /** SMIME eContentType id-ct-DVCSResponseData; OID: 1.2.840.113549.1.9.16.1.8 */
+ static final ASN1ObjectIdentifier id_ct_DVCSResponseData = id_smime.branch("1.8");
+
+ /** SMIME DataValidation certificate attribute id-aa-dvcs-dvc; OID: 1.2.840.113549.1.9.16.2,29 */
+ static final ASN1ObjectIdentifier id_aa_dvcs_dvc = id_smime.branch("2.29");
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequest.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequest.java
new file mode 100644
index 00000000..7be8221c
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequest.java
@@ -0,0 +1,107 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x509.GeneralName;
+
+/**
+ * <pre>
+ * DVCSRequest ::= SEQUENCE {
+ * requestInformation DVCSRequestInformation,
+ * data Data,
+ * transactionIdentifier GeneralName OPTIONAL
+ * }
+ * </pre>
+ */
+
+public class DVCSRequest
+ extends ASN1Object
+{
+
+ private DVCSRequestInformation requestInformation;
+ private Data data;
+ private GeneralName transactionIdentifier;
+
+ public DVCSRequest(DVCSRequestInformation requestInformation, Data data)
+ {
+ this(requestInformation, data, null);
+ }
+
+ public DVCSRequest(DVCSRequestInformation requestInformation, Data data, GeneralName transactionIdentifier)
+ {
+ this.requestInformation = requestInformation;
+ this.data = data;
+ this.transactionIdentifier = transactionIdentifier;
+ }
+
+ private DVCSRequest(ASN1Sequence seq)
+ {
+ requestInformation = DVCSRequestInformation.getInstance(seq.getObjectAt(0));
+ data = Data.getInstance(seq.getObjectAt(1));
+ if (seq.size() > 2)
+ {
+ transactionIdentifier = GeneralName.getInstance(seq.getObjectAt(2));
+ }
+ }
+
+ public static DVCSRequest getInstance(Object obj)
+ {
+ if (obj instanceof DVCSRequest)
+ {
+ return (DVCSRequest)obj;
+ }
+ else if (obj != null)
+ {
+ return new DVCSRequest(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static DVCSRequest getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ v.add(requestInformation);
+ v.add(data);
+ if (transactionIdentifier != null)
+ {
+ v.add(transactionIdentifier);
+ }
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ return "DVCSRequest {\n" +
+ "requestInformation: " + requestInformation + "\n" +
+ "data: " + data + "\n" +
+ (transactionIdentifier != null ? "transactionIdentifier: " + transactionIdentifier + "\n" : "") +
+ "}\n";
+ }
+
+ public Data getData()
+ {
+ return data;
+ }
+
+ public DVCSRequestInformation getRequestInformation()
+ {
+ return requestInformation;
+ }
+
+ public GeneralName getTransactionIdentifier()
+ {
+ return transactionIdentifier;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformation.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformation.java
new file mode 100644
index 00000000..374df9db
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformation.java
@@ -0,0 +1,271 @@
+package org.spongycastle.asn1.dvcs;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.PolicyInformation;
+
+/**
+ * <pre>
+ * DVCSRequestInformation ::= SEQUENCE {
+ * version INTEGER DEFAULT 1 ,
+ * service ServiceType,
+ * nonce Nonce OPTIONAL,
+ * requestTime DVCSTime OPTIONAL,
+ * requester [0] GeneralNames OPTIONAL,
+ * requestPolicy [1] PolicyInformation OPTIONAL,
+ * dvcs [2] GeneralNames OPTIONAL,
+ * dataLocations [3] GeneralNames OPTIONAL,
+ * extensions [4] IMPLICIT Extensions OPTIONAL
+ * }
+ * </pre>
+ */
+
+public class DVCSRequestInformation
+ extends ASN1Object
+{
+ private int version = DEFAULT_VERSION;
+ private ServiceType service;
+ private BigInteger nonce;
+ private DVCSTime requestTime;
+ private GeneralNames requester;
+ private PolicyInformation requestPolicy;
+ private GeneralNames dvcs;
+ private GeneralNames dataLocations;
+ private Extensions extensions;
+
+ private static final int DEFAULT_VERSION = 1;
+ private static final int TAG_REQUESTER = 0;
+ private static final int TAG_REQUEST_POLICY = 1;
+ private static final int TAG_DVCS = 2;
+ private static final int TAG_DATA_LOCATIONS = 3;
+ private static final int TAG_EXTENSIONS = 4;
+
+ private DVCSRequestInformation(ASN1Sequence seq)
+ {
+ int i = 0;
+
+ if (seq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ ASN1Integer encVersion = ASN1Integer.getInstance(seq.getObjectAt(i++));
+ this.version = encVersion.getValue().intValue();
+ }
+ else
+ {
+ this.version = 1;
+ }
+
+ this.service = ServiceType.getInstance(seq.getObjectAt(i++));
+
+ while (i < seq.size())
+ {
+ ASN1Encodable x = seq.getObjectAt(i);
+
+ if (x instanceof ASN1Integer)
+ {
+ this.nonce = ASN1Integer.getInstance(x).getValue();
+ }
+ else if (x instanceof ASN1GeneralizedTime)
+ {
+ this.requestTime = DVCSTime.getInstance(x);
+ }
+ else if (x instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject t = ASN1TaggedObject.getInstance(x);
+ int tagNo = t.getTagNo();
+
+ switch (tagNo)
+ {
+ case TAG_REQUESTER:
+ this.requester = GeneralNames.getInstance(t, false);
+ break;
+ case TAG_REQUEST_POLICY:
+ this.requestPolicy = PolicyInformation.getInstance(ASN1Sequence.getInstance(t, false));
+ break;
+ case TAG_DVCS:
+ this.dvcs = GeneralNames.getInstance(t, false);
+ break;
+ case TAG_DATA_LOCATIONS:
+ this.dataLocations = GeneralNames.getInstance(t, false);
+ break;
+ case TAG_EXTENSIONS:
+ this.extensions = Extensions.getInstance(t, false);
+ break;
+ }
+ }
+ else
+ {
+ this.requestTime = DVCSTime.getInstance(x);
+ }
+
+ i++;
+ }
+ }
+
+ public static DVCSRequestInformation getInstance(Object obj)
+ {
+ if (obj instanceof DVCSRequestInformation)
+ {
+ return (DVCSRequestInformation)obj;
+ }
+ else if (obj != null)
+ {
+ return new DVCSRequestInformation(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static DVCSRequestInformation getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (version != DEFAULT_VERSION)
+ {
+ v.add(new ASN1Integer(version));
+ }
+ v.add(service);
+ if (nonce != null)
+ {
+ v.add(new ASN1Integer(nonce));
+ }
+ if (requestTime != null)
+ {
+ v.add(requestTime);
+ }
+
+ int[] tags = new int[]{
+ TAG_REQUESTER,
+ TAG_REQUEST_POLICY,
+ TAG_DVCS,
+ TAG_DATA_LOCATIONS,
+ TAG_EXTENSIONS
+ };
+ ASN1Encodable[] taggedObjects = new ASN1Encodable[]{
+ requester,
+ requestPolicy,
+ dvcs,
+ dataLocations,
+ extensions
+ };
+ for (int i = 0; i < tags.length; i++)
+ {
+ int tag = tags[i];
+ ASN1Encodable taggedObject = taggedObjects[i];
+ if (taggedObject != null)
+ {
+ v.add(new DERTaggedObject(false, tag, taggedObject));
+ }
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+
+ StringBuffer s = new StringBuffer();
+
+ s.append("DVCSRequestInformation {\n");
+
+ if (version != DEFAULT_VERSION)
+ {
+ s.append("version: " + version + "\n");
+ }
+ s.append("service: " + service + "\n");
+ if (nonce != null)
+ {
+ s.append("nonce: " + nonce + "\n");
+ }
+ if (requestTime != null)
+ {
+ s.append("requestTime: " + requestTime + "\n");
+ }
+ if (requester != null)
+ {
+ s.append("requester: " + requester + "\n");
+ }
+ if (requestPolicy != null)
+ {
+ s.append("requestPolicy: " + requestPolicy + "\n");
+ }
+ if (dvcs != null)
+ {
+ s.append("dvcs: " + dvcs + "\n");
+ }
+ if (dataLocations != null)
+ {
+ s.append("dataLocations: " + dataLocations + "\n");
+ }
+ if (extensions != null)
+ {
+ s.append("extensions: " + extensions + "\n");
+ }
+
+ s.append("}\n");
+ return s.toString();
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ public ServiceType getService()
+ {
+ return service;
+ }
+
+ public BigInteger getNonce()
+ {
+ return nonce;
+ }
+
+ public DVCSTime getRequestTime()
+ {
+ return requestTime;
+ }
+
+ public GeneralNames getRequester()
+ {
+ return requester;
+ }
+
+ public PolicyInformation getRequestPolicy()
+ {
+ return requestPolicy;
+ }
+
+ public GeneralNames getDVCS()
+ {
+ return dvcs;
+ }
+
+ public GeneralNames getDataLocations()
+ {
+ return dataLocations;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformationBuilder.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformationBuilder.java
new file mode 100644
index 00000000..8815fe37
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSRequestInformationBuilder.java
@@ -0,0 +1,224 @@
+package org.spongycastle.asn1.dvcs;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.PolicyInformation;
+import org.spongycastle.util.BigIntegers;
+
+/**
+ * <pre>
+ * DVCSRequestInformation ::= SEQUENCE {
+ * version INTEGER DEFAULT 1 ,
+ * service ServiceType,
+ * nonce Nonce OPTIONAL,
+ * requestTime DVCSTime OPTIONAL,
+ * requester [0] GeneralNames OPTIONAL,
+ * requestPolicy [1] PolicyInformation OPTIONAL,
+ * dvcs [2] GeneralNames OPTIONAL,
+ * dataLocations [3] GeneralNames OPTIONAL,
+ * extensions [4] IMPLICIT Extensions OPTIONAL
+ * }
+ * </pre>
+ */
+public class DVCSRequestInformationBuilder
+{
+ private int version = DEFAULT_VERSION;
+
+ private final ServiceType service;
+ private DVCSRequestInformation initialInfo;
+
+ private BigInteger nonce;
+ private DVCSTime requestTime;
+ private GeneralNames requester;
+ private PolicyInformation requestPolicy;
+ private GeneralNames dvcs;
+ private GeneralNames dataLocations;
+ private Extensions extensions;
+
+ private static final int DEFAULT_VERSION = 1;
+ private static final int TAG_REQUESTER = 0;
+ private static final int TAG_REQUEST_POLICY = 1;
+ private static final int TAG_DVCS = 2;
+ private static final int TAG_DATA_LOCATIONS = 3;
+ private static final int TAG_EXTENSIONS = 4;
+
+ public DVCSRequestInformationBuilder(ServiceType service)
+ {
+ this.service = service;
+ }
+
+ public DVCSRequestInformationBuilder(DVCSRequestInformation initialInfo)
+ {
+ this.initialInfo = initialInfo;
+ this.service = initialInfo.getService();
+ this.version = initialInfo.getVersion();
+ this.nonce = initialInfo.getNonce();
+ this.requestTime = initialInfo.getRequestTime();
+ this.requestPolicy = initialInfo.getRequestPolicy();
+ this.dvcs = initialInfo.getDVCS();
+ this.dataLocations = initialInfo.getDataLocations();
+ }
+
+ public DVCSRequestInformation build()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (version != DEFAULT_VERSION)
+ {
+ v.add(new ASN1Integer(version));
+ }
+ v.add(service);
+ if (nonce != null)
+ {
+ v.add(new ASN1Integer(nonce));
+ }
+ if (requestTime != null)
+ {
+ v.add(requestTime);
+ }
+
+ int[] tags = new int[]{
+ TAG_REQUESTER,
+ TAG_REQUEST_POLICY,
+ TAG_DVCS,
+ TAG_DATA_LOCATIONS,
+ TAG_EXTENSIONS
+ };
+ ASN1Encodable[] taggedObjects = new ASN1Encodable[]{
+ requester,
+ requestPolicy,
+ dvcs,
+ dataLocations,
+ extensions
+ };
+ for (int i = 0; i < tags.length; i++)
+ {
+ int tag = tags[i];
+ ASN1Encodable taggedObject = taggedObjects[i];
+ if (taggedObject != null)
+ {
+ v.add(new DERTaggedObject(false, tag, taggedObject));
+ }
+ }
+
+ return DVCSRequestInformation.getInstance(new DERSequence(v));
+ }
+
+ public void setVersion(int version)
+ {
+ if (initialInfo != null)
+ {
+ throw new IllegalStateException("cannot change version in existing DVCSRequestInformation");
+ }
+
+ this.version = version;
+ }
+
+ public void setNonce(BigInteger nonce)
+ {
+ // RFC 3029, 9.1: The DVCS MAY modify the fields
+ // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure
+
+ // RFC 3029, 9.1: The only modification
+ // allowed to a 'nonce' is the inclusion of a new field if it was not
+ // present, or to concatenate other data to the end (right) of an
+ // existing value.
+ if (initialInfo != null)
+ {
+ if (initialInfo.getNonce() == null)
+ {
+ this.nonce = nonce;
+ }
+ else
+ {
+ byte[] initialBytes = initialInfo.getNonce().toByteArray();
+ byte[] newBytes = BigIntegers.asUnsignedByteArray(nonce);
+ byte[] nonceBytes = new byte[initialBytes.length + newBytes.length];
+
+ System.arraycopy(initialBytes, 0, nonceBytes, 0, initialBytes.length);
+ System.arraycopy(newBytes, 0, nonceBytes, initialBytes.length, newBytes.length);
+
+ this.nonce = new BigInteger(nonceBytes);
+ }
+ }
+
+ this.nonce = nonce;
+ }
+
+ public void setRequestTime(DVCSTime requestTime)
+ {
+ if (initialInfo != null)
+ {
+ throw new IllegalStateException("cannot change request time in existing DVCSRequestInformation");
+ }
+
+ this.requestTime = requestTime;
+ }
+
+ public void setRequester(GeneralName requester)
+ {
+ this.setRequester(new GeneralNames(requester));
+ }
+
+ public void setRequester(GeneralNames requester)
+ {
+ // RFC 3029, 9.1: The DVCS MAY modify the fields
+ // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure
+
+ this.requester = requester;
+ }
+
+ public void setRequestPolicy(PolicyInformation requestPolicy)
+ {
+ if (initialInfo != null)
+ {
+ throw new IllegalStateException("cannot change request policy in existing DVCSRequestInformation");
+ }
+
+ this.requestPolicy = requestPolicy;
+ }
+
+ public void setDVCS(GeneralName dvcs)
+ {
+ this.setDVCS(new GeneralNames(dvcs));
+ }
+
+ public void setDVCS(GeneralNames dvcs)
+ {
+ // RFC 3029, 9.1: The DVCS MAY modify the fields
+ // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure
+
+ this.dvcs = dvcs;
+ }
+
+ public void setDataLocations(GeneralName dataLocation)
+ {
+ this.setDataLocations(new GeneralNames(dataLocation));
+ }
+
+ public void setDataLocations(GeneralNames dataLocations)
+ {
+ // RFC 3029, 9.1: The DVCS MAY modify the fields
+ // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure
+
+ this.dataLocations = dataLocations;
+ }
+
+ public void setExtensions(Extensions extensions)
+ {
+ if (initialInfo != null)
+ {
+ throw new IllegalStateException("cannot change extensions in existing DVCSRequestInformation");
+ }
+
+ this.extensions = extensions;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSResponse.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSResponse.java
new file mode 100644
index 00000000..6100bd30
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSResponse.java
@@ -0,0 +1,117 @@
+package org.spongycastle.asn1.dvcs;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Choice;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERTaggedObject;
+
+/**
+ * <pre>
+ * DVCSResponse ::= CHOICE
+ * {
+ * dvCertInfo DVCSCertInfo ,
+ * dvErrorNote [0] DVCSErrorNotice
+ * }
+ * </pre>
+ */
+
+public class DVCSResponse
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private DVCSCertInfo dvCertInfo;
+ private DVCSErrorNotice dvErrorNote;
+
+ public DVCSResponse(DVCSCertInfo dvCertInfo)
+ {
+ this.dvCertInfo = dvCertInfo;
+ }
+
+ public DVCSResponse(DVCSErrorNotice dvErrorNote)
+ {
+ this.dvErrorNote = dvErrorNote;
+ }
+
+ public static DVCSResponse getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof DVCSResponse)
+ {
+ return (DVCSResponse)obj;
+ }
+ else
+ {
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
+ }
+ }
+ if (obj instanceof ASN1Sequence)
+ {
+ DVCSCertInfo dvCertInfo = DVCSCertInfo.getInstance(obj);
+
+ return new DVCSResponse(dvCertInfo);
+ }
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject t = ASN1TaggedObject.getInstance(obj);
+ DVCSErrorNotice dvErrorNote = DVCSErrorNotice.getInstance(t, false);
+
+ return new DVCSResponse(dvErrorNote);
+ }
+ }
+
+ throw new IllegalArgumentException("Couldn't convert from object to DVCSResponse: " + obj.getClass().getName());
+ }
+
+ public static DVCSResponse getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public DVCSCertInfo getCertInfo()
+ {
+ return dvCertInfo;
+ }
+
+ public DVCSErrorNotice getErrorNotice()
+ {
+ return dvErrorNote;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (dvCertInfo != null)
+ {
+ return dvCertInfo.toASN1Primitive();
+ }
+ else
+ {
+ return new DERTaggedObject(0, dvErrorNote);
+ }
+ }
+
+ public String toString()
+ {
+ if (dvCertInfo != null)
+ {
+ return "DVCSResponse {\ndvCertInfo: " + dvCertInfo.toString() + "}\n";
+ }
+ if (dvErrorNote != null)
+ {
+ return "DVCSResponse {\ndvErrorNote: " + dvErrorNote.toString() + "}\n";
+ }
+ return null;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSTime.java b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSTime.java
new file mode 100644
index 00000000..f8bf2f90
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/DVCSTime.java
@@ -0,0 +1,111 @@
+package org.spongycastle.asn1.dvcs;
+
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1Choice;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.cms.ContentInfo;
+
+/**
+ * <pre>
+ * DVCSTime ::= CHOICE {
+ * genTime GeneralizedTime,
+ * timeStampToken ContentInfo
+ * }
+ * </pre>
+ */
+public class DVCSTime
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1GeneralizedTime genTime;
+ private ContentInfo timeStampToken;
+ private Date time;
+
+ // constructors:
+
+ public DVCSTime(Date time)
+ {
+ this(new ASN1GeneralizedTime(time));
+ }
+
+ public DVCSTime(ASN1GeneralizedTime genTime)
+ {
+ this.genTime = genTime;
+ }
+
+ public DVCSTime(ContentInfo timeStampToken)
+ {
+ this.timeStampToken = timeStampToken;
+ }
+
+ public static DVCSTime getInstance(Object obj)
+ {
+ if (obj instanceof DVCSTime)
+ {
+ return (DVCSTime)obj;
+ }
+ else if (obj instanceof ASN1GeneralizedTime)
+ {
+ return new DVCSTime(ASN1GeneralizedTime.getInstance(obj));
+ }
+ else if (obj != null)
+ {
+ return new DVCSTime(ContentInfo.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static DVCSTime getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject()); // must be explicitly tagged
+ }
+
+
+ // selectors:
+
+ public ASN1GeneralizedTime getGenTime()
+ {
+ return genTime;
+ }
+
+ public ContentInfo getTimeStampToken()
+ {
+ return timeStampToken;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+
+ if (genTime != null)
+ {
+ return genTime;
+ }
+
+ if (timeStampToken != null)
+ {
+ return timeStampToken.toASN1Primitive();
+ }
+
+ return null;
+ }
+
+ public String toString()
+ {
+ if (genTime != null)
+ {
+ return genTime.toString();
+ }
+ if (timeStampToken != null)
+ {
+ return timeStampToken.toString();
+ }
+ return null;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/Data.java b/core/src/main/java/org/spongycastle/asn1/dvcs/Data.java
new file mode 100644
index 00000000..8d00f33f
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/Data.java
@@ -0,0 +1,149 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1Choice;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.x509.DigestInfo;
+
+/**
+ * <pre>
+ * Data ::= CHOICE {
+ * message OCTET STRING ,
+ * messageImprint DigestInfo,
+ * certs [0] SEQUENCE SIZE (1..MAX) OF
+ * TargetEtcChain
+ * }
+ * </pre>
+ */
+
+public class Data
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1OctetString message;
+ private DigestInfo messageImprint;
+ private ASN1Sequence certs;
+
+ public Data(byte[] messageBytes)
+ {
+ this.message = new DEROctetString(messageBytes);
+ }
+
+ public Data(ASN1OctetString message)
+ {
+ this.message = message;
+ }
+
+ public Data(DigestInfo messageImprint)
+ {
+ this.messageImprint = messageImprint;
+ }
+
+ public Data(TargetEtcChain cert)
+ {
+ this.certs = new DERSequence(cert);
+ }
+
+ public Data(TargetEtcChain[] certs)
+ {
+ this.certs = new DERSequence(certs);
+ }
+
+ private Data(ASN1Sequence certs)
+ {
+ this.certs = certs;
+ }
+
+ public static Data getInstance(Object obj)
+ {
+ if (obj instanceof Data)
+ {
+ return (Data)obj;
+ }
+ else if (obj instanceof ASN1OctetString)
+ {
+ return new Data((ASN1OctetString)obj);
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new Data(DigestInfo.getInstance(obj));
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new Data(ASN1Sequence.getInstance((ASN1TaggedObject)obj, false));
+ }
+ throw new IllegalArgumentException("Unknown object submitted to getInstance: " + obj.getClass().getName());
+ }
+
+ public static Data getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (message != null)
+ {
+ return message.toASN1Primitive();
+ }
+ if (messageImprint != null)
+ {
+ return messageImprint.toASN1Primitive();
+ }
+ else
+ {
+ return new DERTaggedObject(false, 0, certs);
+ }
+ }
+
+ public String toString()
+ {
+ if (message != null)
+ {
+ return "Data {\n" + message + "}\n";
+ }
+ if (messageImprint != null)
+ {
+ return "Data {\n" + messageImprint + "}\n";
+ }
+ else
+ {
+ return "Data {\n" + certs + "}\n";
+ }
+ }
+
+ public ASN1OctetString getMessage()
+ {
+ return message;
+ }
+
+ public DigestInfo getMessageImprint()
+ {
+ return messageImprint;
+ }
+
+ public TargetEtcChain[] getCerts()
+ {
+ if (certs == null)
+ {
+ return null;
+ }
+
+ TargetEtcChain[] tmp = new TargetEtcChain[certs.size()];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ tmp[i] = TargetEtcChain.getInstance(certs.getObjectAt(i));
+ }
+
+ return tmp;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/PathProcInput.java b/core/src/main/java/org/spongycastle/asn1/dvcs/PathProcInput.java
new file mode 100644
index 00000000..2c5b8875
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/PathProcInput.java
@@ -0,0 +1,180 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1Boolean;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.x509.PolicyInformation;
+
+/**
+ * <pre>
+ * PathProcInput ::= SEQUENCE {
+ * acceptablePolicySet SEQUENCE SIZE (1..MAX) OF
+ * PolicyInformation,
+ * inhibitPolicyMapping BOOLEAN DEFAULT FALSE,
+ * explicitPolicyReqd [0] BOOLEAN DEFAULT FALSE ,
+ * inhibitAnyPolicy [1] BOOLEAN DEFAULT FALSE
+ * }
+ * </pre>
+ */
+public class PathProcInput
+ extends ASN1Object
+{
+
+ private PolicyInformation[] acceptablePolicySet;
+ private boolean inhibitPolicyMapping = false;
+ private boolean explicitPolicyReqd = false;
+ private boolean inhibitAnyPolicy = false;
+
+ public PathProcInput(PolicyInformation[] acceptablePolicySet)
+ {
+ this.acceptablePolicySet = acceptablePolicySet;
+ }
+
+ public PathProcInput(PolicyInformation[] acceptablePolicySet, boolean inhibitPolicyMapping, boolean explicitPolicyReqd, boolean inhibitAnyPolicy)
+ {
+ this.acceptablePolicySet = acceptablePolicySet;
+ this.inhibitPolicyMapping = inhibitPolicyMapping;
+ this.explicitPolicyReqd = explicitPolicyReqd;
+ this.inhibitAnyPolicy = inhibitAnyPolicy;
+ }
+
+ private static PolicyInformation[] fromSequence(ASN1Sequence seq)
+ {
+ PolicyInformation[] tmp = new PolicyInformation[seq.size()];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ tmp[i] = PolicyInformation.getInstance(seq.getObjectAt(i));
+ }
+
+ return tmp;
+ }
+
+ public static PathProcInput getInstance(Object obj)
+ {
+ if (obj instanceof PathProcInput)
+ {
+ return (PathProcInput)obj;
+ }
+ else if (obj != null)
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(obj);
+ ASN1Sequence policies = ASN1Sequence.getInstance(seq.getObjectAt(0));
+ PathProcInput result = new PathProcInput(fromSequence(policies));
+
+ for (int i = 1; i < seq.size(); i++)
+ {
+ Object o = seq.getObjectAt(i);
+
+ if (o instanceof ASN1Boolean)
+ {
+ ASN1Boolean x = ASN1Boolean.getInstance(o);
+ result.setInhibitPolicyMapping(x.isTrue());
+ }
+ else if (o instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject t = ASN1TaggedObject.getInstance(o);
+ ASN1Boolean x;
+ switch (t.getTagNo())
+ {
+ case 0:
+ x = ASN1Boolean.getInstance(t, false);
+ result.setExplicitPolicyReqd(x.isTrue());
+ break;
+ case 1:
+ x = ASN1Boolean.getInstance(t, false);
+ result.setInhibitAnyPolicy(x.isTrue());
+ }
+ }
+ }
+ return result;
+ }
+
+ return null;
+ }
+
+ public static PathProcInput getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector pV = new ASN1EncodableVector();
+
+ for (int i = 0; i != acceptablePolicySet.length; i++)
+ {
+ pV.add(acceptablePolicySet[i]);
+ }
+
+ v.add(new DERSequence(pV));
+
+ if (inhibitPolicyMapping)
+ {
+ v.add(new ASN1Boolean(inhibitPolicyMapping));
+ }
+ if (explicitPolicyReqd)
+ {
+ v.add(new DERTaggedObject(false, 0, new ASN1Boolean(explicitPolicyReqd)));
+ }
+ if (inhibitAnyPolicy)
+ {
+ v.add(new DERTaggedObject(false, 1, new ASN1Boolean(inhibitAnyPolicy)));
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ return "PathProcInput: {\n" +
+ "acceptablePolicySet: " + acceptablePolicySet + "\n" +
+ "inhibitPolicyMapping: " + inhibitPolicyMapping + "\n" +
+ "explicitPolicyReqd: " + explicitPolicyReqd + "\n" +
+ "inhibitAnyPolicy: " + inhibitAnyPolicy + "\n" +
+ "}\n";
+ }
+
+ public PolicyInformation[] getAcceptablePolicySet()
+ {
+ return acceptablePolicySet;
+ }
+
+ public boolean isInhibitPolicyMapping()
+ {
+ return inhibitPolicyMapping;
+ }
+
+ private void setInhibitPolicyMapping(boolean inhibitPolicyMapping)
+ {
+ this.inhibitPolicyMapping = inhibitPolicyMapping;
+ }
+
+ public boolean isExplicitPolicyReqd()
+ {
+ return explicitPolicyReqd;
+ }
+
+ private void setExplicitPolicyReqd(boolean explicitPolicyReqd)
+ {
+ this.explicitPolicyReqd = explicitPolicyReqd;
+ }
+
+ public boolean isInhibitAnyPolicy()
+ {
+ return inhibitAnyPolicy;
+ }
+
+ private void setInhibitAnyPolicy(boolean inhibitAnyPolicy)
+ {
+ this.inhibitAnyPolicy = inhibitAnyPolicy;
+ }
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/ServiceType.java b/core/src/main/java/org/spongycastle/asn1/dvcs/ServiceType.java
new file mode 100644
index 00000000..0cc4acc1
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/ServiceType.java
@@ -0,0 +1,92 @@
+package org.spongycastle.asn1.dvcs;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Enumerated;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1TaggedObject;
+
+
+/**
+ * ServiceType ::= ENUMERATED { cpd(1), vsd(2), cpkc(3), ccpd(4) }
+ */
+
+public class ServiceType
+ extends ASN1Object
+{
+ /**
+ * Identifier of CPD service (Certify Possession of Data).
+ */
+ public static final ServiceType CPD = new ServiceType(1);
+
+ /**
+ * Identifier of VSD service (Verify Signed Document).
+ */
+ public static final ServiceType VSD = new ServiceType(2);
+
+ /**
+ * Identifier of VPKC service (Verify Public Key Certificates (also referred to as CPKC)).
+ */
+ public static final ServiceType VPKC = new ServiceType(3);
+
+ /**
+ * Identifier of CCPD service (Certify Claim of Possession of Data).
+ */
+ public static final ServiceType CCPD = new ServiceType(4);
+
+ private ASN1Enumerated value;
+
+ public ServiceType(int value)
+ {
+ this.value = new ASN1Enumerated(value);
+ }
+
+ private ServiceType(ASN1Enumerated value)
+ {
+ this.value = value;
+ }
+
+ public static ServiceType getInstance(Object obj)
+ {
+ if (obj instanceof ServiceType)
+ {
+ return (ServiceType)obj;
+ }
+ else if (obj != null)
+ {
+ return new ServiceType(ASN1Enumerated.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static ServiceType getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Enumerated.getInstance(obj, explicit));
+ }
+
+ public BigInteger getValue()
+ {
+ return value.getValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return value;
+ }
+
+ public String toString()
+ {
+ int num = value.getValue().intValue();
+ return "" + num + (
+ num == CPD.getValue().intValue() ? "(CPD)" :
+ num == VSD.getValue().intValue() ? "(VSD)" :
+ num == VPKC.getValue().intValue() ? "(VPKC)" :
+ num == CCPD.getValue().intValue() ? "(CCPD)" :
+ "?");
+ }
+
+}
diff --git a/core/src/main/java/org/spongycastle/asn1/dvcs/TargetEtcChain.java b/core/src/main/java/org/spongycastle/asn1/dvcs/TargetEtcChain.java
new file mode 100644
index 00000000..264a6c26
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/asn1/dvcs/TargetEtcChain.java
@@ -0,0 +1,191 @@
+package org.spongycastle.asn1.dvcs;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERTaggedObject;
+
+/**
+ * <pre>
+ * TargetEtcChain ::= SEQUENCE {
+ * target CertEtcToken,
+ * chain SEQUENCE SIZE (1..MAX) OF
+ * CertEtcToken OPTIONAL,
+ * pathProcInput [0] PathProcInput OPTIONAL
+ * }
+ * </pre>
+ */
+
+public class TargetEtcChain
+ extends ASN1Object
+{
+ private CertEtcToken target;
+ private ASN1Sequence chain;
+ private PathProcInput pathProcInput;
+
+ public TargetEtcChain(CertEtcToken target)
+ {
+ this(target, null, null);
+ }
+
+ public TargetEtcChain(CertEtcToken target, CertEtcToken[] chain)
+ {
+ this(target, chain, null);
+ }
+
+ public TargetEtcChain(CertEtcToken target, PathProcInput pathProcInput)
+ {
+ this(target, null, pathProcInput);
+ }
+
+ public TargetEtcChain(CertEtcToken target, CertEtcToken[] chain, PathProcInput pathProcInput)
+ {
+ this.target = target;
+
+ if (chain != null)
+ {
+ this.chain = new DERSequence(chain);
+ }
+
+ this.pathProcInput = pathProcInput;
+ }
+
+ private TargetEtcChain(ASN1Sequence seq)
+ {
+ int i = 0;
+ ASN1Encodable obj = seq.getObjectAt(i++);
+ this.target = CertEtcToken.getInstance(obj);
+
+ try
+ {
+ obj = seq.getObjectAt(i++);
+ this.chain = ASN1Sequence.getInstance(obj);
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ return;
+ }
+
+ try
+ {
+ obj = seq.getObjectAt(i++);
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(obj);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ this.pathProcInput = PathProcInput.getInstance(tagged, false);
+ break;
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ }
+ }
+
+ public static TargetEtcChain getInstance(Object obj)
+ {
+ if (obj instanceof TargetEtcChain)
+ {
+ return (TargetEtcChain)obj;
+ }
+ else if (obj != null)
+ {
+ return new TargetEtcChain(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static TargetEtcChain getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ v.add(target);
+ if (chain != null)
+ {
+ v.add(chain);
+ }
+ if (pathProcInput != null)
+ {
+ v.add(new DERTaggedObject(false, 0, pathProcInput));
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append("TargetEtcChain {\n");
+ s.append("target: " + target + "\n");
+ if (chain != null)
+ {
+ s.append("chain: " + chain + "\n");
+ }
+ if (pathProcInput != null)
+ {
+ s.append("pathProcInput: " + pathProcInput + "\n");
+ }
+ s.append("}\n");
+ return s.toString();
+ }
+
+
+ public CertEtcToken getTarget()
+ {
+ return target;
+ }
+
+ public CertEtcToken[] getChain()
+ {
+ if (chain != null)
+ {
+ return CertEtcToken.arrayFromSequence(chain);
+ }
+
+ return null;
+ }
+
+ private void setChain(ASN1Sequence chain)
+ {
+ this.chain = chain;
+ }
+
+ public PathProcInput getPathProcInput()
+ {
+ return pathProcInput;
+ }
+
+ private void setPathProcInput(PathProcInput pathProcInput)
+ {
+ this.pathProcInput = pathProcInput;
+ }
+
+ public static TargetEtcChain[] arrayFromSequence(ASN1Sequence seq)
+ {
+ TargetEtcChain[] tmp = new TargetEtcChain[seq.size()];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ tmp[i] = TargetEtcChain.getInstance(seq.getObjectAt(i));
+ }
+
+ return tmp;
+ }
+}