diff options
author | Roberto Tyley <roberto.tyley@gmail.com> | 2014-07-15 01:38:01 +0400 |
---|---|---|
committer | Roberto Tyley <roberto.tyley@gmail.com> | 2014-07-26 11:23:17 +0400 |
commit | 7cb752aaf746dc0b473afeb9e892b7fbc12666c5 (patch) | |
tree | cc4f91ddc18332b5adbe82e3fcb040d976c90105 /core/src/main/java/org/spongycastle/asn1/cmp | |
parent | 551830f8ea5177042af2c7dd1fc90888bc67387d (diff) |
Execute become-spongy.sh
https://github.com/rtyley/spongycastle/blob/3040af/become-spongy.sh
Diffstat (limited to 'core/src/main/java/org/spongycastle/asn1/cmp')
38 files changed, 4208 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CAKeyUpdAnnContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/CAKeyUpdAnnContent.java new file mode 100644 index 00000000..ddc4c252 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CAKeyUpdAnnContent.java @@ -0,0 +1,80 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class CAKeyUpdAnnContent + extends ASN1Object +{ + private CMPCertificate oldWithNew; + private CMPCertificate newWithOld; + private CMPCertificate newWithNew; + + private CAKeyUpdAnnContent(ASN1Sequence seq) + { + oldWithNew = CMPCertificate.getInstance(seq.getObjectAt(0)); + newWithOld = CMPCertificate.getInstance(seq.getObjectAt(1)); + newWithNew = CMPCertificate.getInstance(seq.getObjectAt(2)); + } + + public static CAKeyUpdAnnContent getInstance(Object o) + { + if (o instanceof CAKeyUpdAnnContent) + { + return (CAKeyUpdAnnContent)o; + } + + if (o != null) + { + return new CAKeyUpdAnnContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CAKeyUpdAnnContent(CMPCertificate oldWithNew, CMPCertificate newWithOld, CMPCertificate newWithNew) + { + this.oldWithNew = oldWithNew; + this.newWithOld = newWithOld; + this.newWithNew = newWithNew; + } + + public CMPCertificate getOldWithNew() + { + return oldWithNew; + } + + public CMPCertificate getNewWithOld() + { + return newWithOld; + } + + public CMPCertificate getNewWithNew() + { + return newWithNew; + } + + /** + * <pre> + * CAKeyUpdAnnContent ::= SEQUENCE { + * oldWithNew CMPCertificate, -- old pub signed with new priv + * newWithOld CMPCertificate, -- new pub signed with old priv + * newWithNew CMPCertificate -- new pub signed with new priv + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(oldWithNew); + v.add(newWithOld); + v.add(newWithNew); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CMPCertificate.java b/core/src/main/java/org/spongycastle/asn1/cmp/CMPCertificate.java new file mode 100644 index 00000000..22dcb3b8 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CMPCertificate.java @@ -0,0 +1,92 @@ +package org.spongycastle.asn1.cmp; + +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; +import org.spongycastle.asn1.x509.AttributeCertificate; +import org.spongycastle.asn1.x509.Certificate; + +public class CMPCertificate + extends ASN1Object + implements ASN1Choice +{ + private Certificate x509v3PKCert; + private AttributeCertificate x509v2AttrCert; + + /** + * Note: the addition of attribute certificates is a BC extension. + */ + public CMPCertificate(AttributeCertificate x509v2AttrCert) + { + this.x509v2AttrCert = x509v2AttrCert; + } + + public CMPCertificate(Certificate x509v3PKCert) + { + if (x509v3PKCert.getVersionNumber() != 3) + { + throw new IllegalArgumentException("only version 3 certificates allowed"); + } + + this.x509v3PKCert = x509v3PKCert; + } + + public static CMPCertificate getInstance(Object o) + { + if (o == null || o instanceof CMPCertificate) + { + return (CMPCertificate)o; + } + + if (o instanceof ASN1Sequence || o instanceof byte[]) + { + return new CMPCertificate(Certificate.getInstance(o)); + } + + if (o instanceof ASN1TaggedObject) + { + return new CMPCertificate(AttributeCertificate.getInstance(((ASN1TaggedObject)o).getObject())); + } + + throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); + } + + public boolean isX509v3PKCert() + { + return x509v3PKCert != null; + } + + public Certificate getX509v3PKCert() + { + return x509v3PKCert; + } + + public AttributeCertificate getX509v2AttrCert() + { + return x509v2AttrCert; + } + + /** + * <pre> + * CMPCertificate ::= CHOICE { + * x509v3PKCert Certificate + * x509v2AttrCert [1] AttributeCertificate + * } + * </pre> + * Note: the addition of attribute certificates is a BC extension. + * + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + if (x509v2AttrCert != null) + { // explicit following CMP conventions + return new DERTaggedObject(true, 1, x509v2AttrCert); + } + + return x509v3PKCert.toASN1Primitive(); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CMPObjectIdentifiers.java b/core/src/main/java/org/spongycastle/asn1/cmp/CMPObjectIdentifiers.java new file mode 100644 index 00000000..c7cbc5a5 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CMPObjectIdentifiers.java @@ -0,0 +1,141 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1ObjectIdentifier; + +public interface CMPObjectIdentifiers +{ + // RFC 4210 + + /** id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13} */ + static final ASN1ObjectIdentifier passwordBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); + + /** id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30} */ + static final ASN1ObjectIdentifier dhBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.30"); + + // Example InfoTypeAndValue contents include, but are not limited + // to, the following (un-comment in this ASN.1 module and use as + // appropriate for a given environment): + // + // id-it-caProtEncCert OBJECT IDENTIFIER ::= {id-it 1} + // CAProtEncCertValue ::= CMPCertificate + // id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2} + // SignKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + // id-it-encKeyPairTypes OBJECT IDENTIFIER ::= {id-it 3} + // EncKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + // id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4} + // PreferredSymmAlgValue ::= AlgorithmIdentifier + // id-it-caKeyUpdateInfo OBJECT IDENTIFIER ::= {id-it 5} + // CAKeyUpdateInfoValue ::= CAKeyUpdAnnContent + // id-it-currentCRL OBJECT IDENTIFIER ::= {id-it 6} + // CurrentCRLValue ::= CertificateList + // id-it-unsupportedOIDs OBJECT IDENTIFIER ::= {id-it 7} + // UnsupportedOIDsValue ::= SEQUENCE OF OBJECT IDENTIFIER + // id-it-keyPairParamReq OBJECT IDENTIFIER ::= {id-it 10} + // KeyPairParamReqValue ::= OBJECT IDENTIFIER + // id-it-keyPairParamRep OBJECT IDENTIFIER ::= {id-it 11} + // KeyPairParamRepValue ::= AlgorithmIdentifer + // id-it-revPassphrase OBJECT IDENTIFIER ::= {id-it 12} + // RevPassphraseValue ::= EncryptedValue + // id-it-implicitConfirm OBJECT IDENTIFIER ::= {id-it 13} + // ImplicitConfirmValue ::= NULL + // id-it-confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14} + // ConfirmWaitTimeValue ::= GeneralizedTime + // id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15} + // OrigPKIMessageValue ::= PKIMessages + // id-it-suppLangTags OBJECT IDENTIFIER ::= {id-it 16} + // SuppLangTagsValue ::= SEQUENCE OF UTF8String + // + // where + // + // id-pkix OBJECT IDENTIFIER ::= { + // iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) pkix(7)} + // and + // id-it OBJECT IDENTIFIER ::= {id-pkix 4} + + /** RFC 4120: it-id: PKIX.4 = 1.3.6.1.5.5.7.4 */ + + /** RFC 4120: 1.3.6.1.5.5.7.4.1 */ + static final ASN1ObjectIdentifier it_caProtEncCert = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.1"); + /** RFC 4120: 1.3.6.1.5.5.7.4.2 */ + static final ASN1ObjectIdentifier it_signKeyPairTypes = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.2"); + /** RFC 4120: 1.3.6.1.5.5.7.4.3 */ + static final ASN1ObjectIdentifier it_encKeyPairTypes = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.3"); + /** RFC 4120: 1.3.6.1.5.5.7.4.4 */ + static final ASN1ObjectIdentifier it_preferredSymAlg = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.4"); + /** RFC 4120: 1.3.6.1.5.5.7.4.5 */ + static final ASN1ObjectIdentifier it_caKeyUpdateInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.5"); + /** RFC 4120: 1.3.6.1.5.5.7.4.6 */ + static final ASN1ObjectIdentifier it_currentCRL = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.6"); + /** RFC 4120: 1.3.6.1.5.5.7.4.7 */ + static final ASN1ObjectIdentifier it_unsupportedOIDs = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.7"); + /** RFC 4120: 1.3.6.1.5.5.7.4.10 */ + static final ASN1ObjectIdentifier it_keyPairParamReq = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.10"); + /** RFC 4120: 1.3.6.1.5.5.7.4.11 */ + static final ASN1ObjectIdentifier it_keyPairParamRep = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.11"); + /** RFC 4120: 1.3.6.1.5.5.7.4.12 */ + static final ASN1ObjectIdentifier it_revPassphrase = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.12"); + /** RFC 4120: 1.3.6.1.5.5.7.4.13 */ + static final ASN1ObjectIdentifier it_implicitConfirm = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.13"); + /** RFC 4120: 1.3.6.1.5.5.7.4.14 */ + static final ASN1ObjectIdentifier it_confirmWaitTime = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.14"); + /** RFC 4120: 1.3.6.1.5.5.7.4.15 */ + static final ASN1ObjectIdentifier it_origPKIMessage = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.15"); + /** RFC 4120: 1.3.6.1.5.5.7.4.16 */ + static final ASN1ObjectIdentifier it_suppLangTags = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.16"); + + // RFC 4211 + + // id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) pkix(7) } + // + // arc for Internet X.509 PKI protocols and their components + // id-pkip OBJECT IDENTIFIER :: { id-pkix pkip(5) } + // + // arc for Registration Controls in CRMF + // id-regCtrl OBJECT IDENTIFIER ::= { id-pkip regCtrl(1) } + // + // arc for Registration Info in CRMF + // id-regInfo OBJECT IDENTIFIER ::= { id-pkip id-regInfo(2) } + + /** RFC 4211: it-pkip: PKIX.5 = 1.3.6.1.5.5.7.5 */ + static final ASN1ObjectIdentifier id_pkip = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5"); + + /** RFC 4211: it-regCtrl: 1.3.6.1.5.5.7.5.1 */ + static final ASN1ObjectIdentifier id_regCtrl = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1"); + /** RFC 4211: it-regInfo: 1.3.6.1.5.5.7.5.2 */ + static final ASN1ObjectIdentifier id_regInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.2"); + + + /** 1.3.6.1.5.5.7.5.1.1 */ + static final ASN1ObjectIdentifier regCtrl_regToken = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.1"); + /** 1.3.6.1.5.5.7.5.1.2 */ + static final ASN1ObjectIdentifier regCtrl_authenticator = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.2"); + /** 1.3.6.1.5.5.7.5.1.3 */ + static final ASN1ObjectIdentifier regCtrl_pkiPublicationInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.3"); + /** 1.3.6.1.5.5.7.5.1.4 */ + static final ASN1ObjectIdentifier regCtrl_pkiArchiveOptions = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.4"); + /** 1.3.6.1.5.5.7.5.1.5 */ + static final ASN1ObjectIdentifier regCtrl_oldCertID = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.5"); + /** 1.3.6.1.5.5.7.5.1.6 */ + static final ASN1ObjectIdentifier regCtrl_protocolEncrKey = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.6"); + + /** From RFC4210: + * id-regCtrl-altCertTemplate OBJECT IDENTIFIER ::= {id-regCtrl 7}; 1.3.6.1.5.5.7.1.7 */ + static final ASN1ObjectIdentifier regCtrl_altCertTemplate = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.7"); + + /** RFC 4211: it-regInfo-utf8Pairs: 1.3.6.1.5.5.7.5.2.1 */ + static final ASN1ObjectIdentifier regInfo_utf8Pairs = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.2.1"); + /** RFC 4211: it-regInfo-certReq: 1.3.6.1.5.5.7.5.2.1 */ + static final ASN1ObjectIdentifier regInfo_certReq = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.2.2"); + + /** + * 1.2.840.113549.1.9.16.1.21 + * <p> + * id-ct OBJECT IDENTIFIER ::= { id-smime 1 } -- content types + * <p> + * id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} + */ + static final ASN1ObjectIdentifier ct_encKeyWithID = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.1.21"); + +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CRLAnnContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/CRLAnnContent.java new file mode 100644 index 00000000..513baeb9 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CRLAnnContent.java @@ -0,0 +1,61 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.x509.CertificateList; + +public class CRLAnnContent + extends ASN1Object +{ + private ASN1Sequence content; + + private CRLAnnContent(ASN1Sequence seq) + { + content = seq; + } + + public static CRLAnnContent getInstance(Object o) + { + if (o instanceof CRLAnnContent) + { + return (CRLAnnContent)o; + } + + if (o != null) + { + return new CRLAnnContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CRLAnnContent(CertificateList crl) + { + this.content = new DERSequence(crl); + } + + public CertificateList[] getCertificateLists() + { + CertificateList[] result = new CertificateList[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = CertificateList.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * CRLAnnContent ::= SEQUENCE OF CertificateList + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CertConfirmContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/CertConfirmContent.java new file mode 100644 index 00000000..974eb757 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CertConfirmContent.java @@ -0,0 +1,54 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; + +public class CertConfirmContent + extends ASN1Object +{ + private ASN1Sequence content; + + private CertConfirmContent(ASN1Sequence seq) + { + content = seq; + } + + public static CertConfirmContent getInstance(Object o) + { + if (o instanceof CertConfirmContent) + { + return (CertConfirmContent)o; + } + + if (o != null) + { + return new CertConfirmContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CertStatus[] toCertStatusArray() + { + CertStatus[] result = new CertStatus[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = CertStatus.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * CertConfirmContent ::= SEQUENCE OF CertStatus + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CertOrEncCert.java b/core/src/main/java/org/spongycastle/asn1/cmp/CertOrEncCert.java new file mode 100644 index 00000000..ed16a650 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CertOrEncCert.java @@ -0,0 +1,96 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Choice; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1TaggedObject; +import org.spongycastle.asn1.DERTaggedObject; +import org.spongycastle.asn1.crmf.EncryptedValue; + +public class CertOrEncCert + extends ASN1Object + implements ASN1Choice +{ + private CMPCertificate certificate; + private EncryptedValue encryptedCert; + + private CertOrEncCert(ASN1TaggedObject tagged) + { + if (tagged.getTagNo() == 0) + { + certificate = CMPCertificate.getInstance(tagged.getObject()); + } + else if (tagged.getTagNo() == 1) + { + encryptedCert = EncryptedValue.getInstance(tagged.getObject()); + } + else + { + throw new IllegalArgumentException("unknown tag: " + tagged.getTagNo()); + } + } + + public static CertOrEncCert getInstance(Object o) + { + if (o instanceof CertOrEncCert) + { + return (CertOrEncCert)o; + } + + if (o instanceof ASN1TaggedObject) + { + return new CertOrEncCert((ASN1TaggedObject)o); + } + + return null; + } + + public CertOrEncCert(CMPCertificate certificate) + { + if (certificate == null) + { + throw new IllegalArgumentException("'certificate' cannot be null"); + } + + this.certificate = certificate; + } + + public CertOrEncCert(EncryptedValue encryptedCert) + { + if (encryptedCert == null) + { + throw new IllegalArgumentException("'encryptedCert' cannot be null"); + } + + this.encryptedCert = encryptedCert; + } + + public CMPCertificate getCertificate() + { + return certificate; + } + + public EncryptedValue getEncryptedCert() + { + return encryptedCert; + } + + /** + * <pre> + * CertOrEncCert ::= CHOICE { + * certificate [0] CMPCertificate, + * encryptedCert [1] EncryptedValue + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + if (certificate != null) + { + return new DERTaggedObject(true, 0, certificate); + } + + return new DERTaggedObject(true, 1, encryptedCert); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CertRepMessage.java b/core/src/main/java/org/spongycastle/asn1/cmp/CertRepMessage.java new file mode 100644 index 00000000..3f63a4ac --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CertRepMessage.java @@ -0,0 +1,123 @@ +package org.spongycastle.asn1.cmp; + +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; + +public class CertRepMessage + extends ASN1Object +{ + private ASN1Sequence caPubs; + private ASN1Sequence response; + + private CertRepMessage(ASN1Sequence seq) + { + int index = 0; + + if (seq.size() > 1) + { + caPubs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true); + } + + response = ASN1Sequence.getInstance(seq.getObjectAt(index)); + } + + public static CertRepMessage getInstance(Object o) + { + if (o instanceof CertRepMessage) + { + return (CertRepMessage)o; + } + + if (o != null) + { + return new CertRepMessage(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CertRepMessage(CMPCertificate[] caPubs, CertResponse[] response) + { + if (response == null) + { + throw new IllegalArgumentException("'response' cannot be null"); + } + + if (caPubs != null) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < caPubs.length; i++) + { + v.add(caPubs[i]); + } + this.caPubs = new DERSequence(v); + } + + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < response.length; i++) + { + v.add(response[i]); + } + this.response = new DERSequence(v); + } + } + + public CMPCertificate[] getCaPubs() + { + if (caPubs == null) + { + return null; + } + + CMPCertificate[] results = new CMPCertificate[caPubs.size()]; + + for (int i = 0; i != results.length; i++) + { + results[i] = CMPCertificate.getInstance(caPubs.getObjectAt(i)); + } + + return results; + } + + public CertResponse[] getResponse() + { + CertResponse[] results = new CertResponse[response.size()]; + + for (int i = 0; i != results.length; i++) + { + results[i] = CertResponse.getInstance(response.getObjectAt(i)); + } + + return results; + } + + /** + * <pre> + * CertRepMessage ::= SEQUENCE { + * caPubs [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate + * OPTIONAL, + * response SEQUENCE OF CertResponse + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + if (caPubs != null) + { + v.add(new DERTaggedObject(true, 1, caPubs)); + } + + v.add(response); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CertResponse.java b/core/src/main/java/org/spongycastle/asn1/cmp/CertResponse.java new file mode 100644 index 00000000..9efcff68 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CertResponse.java @@ -0,0 +1,139 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class CertResponse + extends ASN1Object +{ + private ASN1Integer certReqId; + private PKIStatusInfo status; + private CertifiedKeyPair certifiedKeyPair; + private ASN1OctetString rspInfo; + + private CertResponse(ASN1Sequence seq) + { + certReqId = ASN1Integer.getInstance(seq.getObjectAt(0)); + status = PKIStatusInfo.getInstance(seq.getObjectAt(1)); + + if (seq.size() >= 3) + { + if (seq.size() == 3) + { + ASN1Encodable o = seq.getObjectAt(2); + if (o instanceof ASN1OctetString) + { + rspInfo = ASN1OctetString.getInstance(o); + } + else + { + certifiedKeyPair = CertifiedKeyPair.getInstance(o); + } + } + else + { + certifiedKeyPair = CertifiedKeyPair.getInstance(seq.getObjectAt(2)); + rspInfo = ASN1OctetString.getInstance(seq.getObjectAt(3)); + } + } + } + + public static CertResponse getInstance(Object o) + { + if (o instanceof CertResponse) + { + return (CertResponse)o; + } + + if (o != null) + { + return new CertResponse(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CertResponse( + ASN1Integer certReqId, + PKIStatusInfo status) + { + this(certReqId, status, null, null); + } + + public CertResponse( + ASN1Integer certReqId, + PKIStatusInfo status, + CertifiedKeyPair certifiedKeyPair, + ASN1OctetString rspInfo) + { + if (certReqId == null) + { + throw new IllegalArgumentException("'certReqId' cannot be null"); + } + if (status == null) + { + throw new IllegalArgumentException("'status' cannot be null"); + } + this.certReqId = certReqId; + this.status = status; + this.certifiedKeyPair = certifiedKeyPair; + this.rspInfo = rspInfo; + } + + public ASN1Integer getCertReqId() + { + return certReqId; + } + + public PKIStatusInfo getStatus() + { + return status; + } + + public CertifiedKeyPair getCertifiedKeyPair() + { + return certifiedKeyPair; + } + + /** + * <pre> + * CertResponse ::= SEQUENCE { + * certReqId INTEGER, + * -- to match this response with corresponding request (a value + * -- of -1 is to be used if certReqId is not specified in the + * -- corresponding request) + * status PKIStatusInfo, + * certifiedKeyPair CertifiedKeyPair OPTIONAL, + * rspInfo OCTET STRING OPTIONAL + * -- analogous to the id-regInfo-utf8Pairs string defined + * -- for regInfo in CertReqMsg [CRMF] + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(certReqId); + v.add(status); + + if (certifiedKeyPair != null) + { + v.add(certifiedKeyPair); + } + + if (rspInfo != null) + { + v.add(rspInfo); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CertStatus.java b/core/src/main/java/org/spongycastle/asn1/cmp/CertStatus.java new file mode 100644 index 00000000..86664eed --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CertStatus.java @@ -0,0 +1,102 @@ +package org.spongycastle.asn1.cmp; + +import java.math.BigInteger; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.DERSequence; + +public class CertStatus + extends ASN1Object +{ + private ASN1OctetString certHash; + private ASN1Integer certReqId; + private PKIStatusInfo statusInfo; + + private CertStatus(ASN1Sequence seq) + { + certHash = ASN1OctetString.getInstance(seq.getObjectAt(0)); + certReqId = ASN1Integer.getInstance(seq.getObjectAt(1)); + + if (seq.size() > 2) + { + statusInfo = PKIStatusInfo.getInstance(seq.getObjectAt(2)); + } + } + + public CertStatus(byte[] certHash, BigInteger certReqId) + { + this.certHash = new DEROctetString(certHash); + this.certReqId = new ASN1Integer(certReqId); + } + + public CertStatus(byte[] certHash, BigInteger certReqId, PKIStatusInfo statusInfo) + { + this.certHash = new DEROctetString(certHash); + this.certReqId = new ASN1Integer(certReqId); + this.statusInfo = statusInfo; + } + + public static CertStatus getInstance(Object o) + { + if (o instanceof CertStatus) + { + return (CertStatus)o; + } + + if (o != null) + { + return new CertStatus(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public ASN1OctetString getCertHash() + { + return certHash; + } + + public ASN1Integer getCertReqId() + { + return certReqId; + } + + public PKIStatusInfo getStatusInfo() + { + return statusInfo; + } + + /** + * <pre> + * CertStatus ::= SEQUENCE { + * certHash OCTET STRING, + * -- the hash of the certificate, using the same hash algorithm + * -- as is used to create and verify the certificate signature + * certReqId INTEGER, + * -- to match this confirmation with the corresponding req/rep + * statusInfo PKIStatusInfo OPTIONAL + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(certHash); + v.add(certReqId); + + if (statusInfo != null) + { + v.add(statusInfo); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/CertifiedKeyPair.java b/core/src/main/java/org/spongycastle/asn1/cmp/CertifiedKeyPair.java new file mode 100644 index 00000000..500c9d03 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/CertifiedKeyPair.java @@ -0,0 +1,127 @@ +package org.spongycastle.asn1.cmp; + +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.crmf.EncryptedValue; +import org.spongycastle.asn1.crmf.PKIPublicationInfo; + +public class CertifiedKeyPair + extends ASN1Object +{ + private CertOrEncCert certOrEncCert; + private EncryptedValue privateKey; + private PKIPublicationInfo publicationInfo; + + private CertifiedKeyPair(ASN1Sequence seq) + { + certOrEncCert = CertOrEncCert.getInstance(seq.getObjectAt(0)); + + if (seq.size() >= 2) + { + if (seq.size() == 2) + { + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1)); + if (tagged.getTagNo() == 0) + { + privateKey = EncryptedValue.getInstance(tagged.getObject()); + } + else + { + publicationInfo = PKIPublicationInfo.getInstance(tagged.getObject()); + } + } + else + { + privateKey = EncryptedValue.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(1))); + publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(2))); + } + } + } + + public static CertifiedKeyPair getInstance(Object o) + { + if (o instanceof CertifiedKeyPair) + { + return (CertifiedKeyPair)o; + } + + if (o != null) + { + return new CertifiedKeyPair(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CertifiedKeyPair( + CertOrEncCert certOrEncCert) + { + this(certOrEncCert, null, null); + } + + public CertifiedKeyPair( + CertOrEncCert certOrEncCert, + EncryptedValue privateKey, + PKIPublicationInfo publicationInfo + ) + { + if (certOrEncCert == null) + { + throw new IllegalArgumentException("'certOrEncCert' cannot be null"); + } + + this.certOrEncCert = certOrEncCert; + this.privateKey = privateKey; + this.publicationInfo = publicationInfo; + } + + public CertOrEncCert getCertOrEncCert() + { + return certOrEncCert; + } + + public EncryptedValue getPrivateKey() + { + return privateKey; + } + + public PKIPublicationInfo getPublicationInfo() + { + return publicationInfo; + } + + /** + * <pre> + * CertifiedKeyPair ::= SEQUENCE { + * certOrEncCert CertOrEncCert, + * privateKey [0] EncryptedValue OPTIONAL, + * -- see [CRMF] for comment on encoding + * publicationInfo [1] PKIPublicationInfo OPTIONAL + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(certOrEncCert); + + if (privateKey != null) + { + v.add(new DERTaggedObject(true, 0, privateKey)); + } + + if (publicationInfo != null) + { + v.add(new DERTaggedObject(true, 1, publicationInfo)); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/Challenge.java b/core/src/main/java/org/spongycastle/asn1/cmp/Challenge.java new file mode 100644 index 00000000..ef02b28b --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/Challenge.java @@ -0,0 +1,120 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; + +public class Challenge + extends ASN1Object +{ + private AlgorithmIdentifier owf; + private ASN1OctetString witness; + private ASN1OctetString challenge; + + private Challenge(ASN1Sequence seq) + { + int index = 0; + + if (seq.size() == 3) + { + owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++)); + } + + witness = ASN1OctetString.getInstance(seq.getObjectAt(index++)); + challenge = ASN1OctetString.getInstance(seq.getObjectAt(index)); + } + + public static Challenge getInstance(Object o) + { + if (o instanceof Challenge) + { + return (Challenge)o; + } + + if (o != null) + { + return new Challenge(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public Challenge(byte[] witness, byte[] challenge) + { + this(null, witness, challenge); + } + + public Challenge(AlgorithmIdentifier owf, byte[] witness, byte[] challenge) + { + this.owf = owf; + this.witness = new DEROctetString(witness); + this.challenge = new DEROctetString(challenge); + } + + public AlgorithmIdentifier getOwf() + { + return owf; + } + + public byte[] getWitness() + { + return witness.getOctets(); + } + + public byte[] getChallenge() + { + return challenge.getOctets(); + } + + /** + * <pre> + * Challenge ::= SEQUENCE { + * owf AlgorithmIdentifier OPTIONAL, + * + * -- MUST be present in the first Challenge; MAY be omitted in + * -- any subsequent Challenge in POPODecKeyChallContent (if + * -- omitted, then the owf used in the immediately preceding + * -- Challenge is to be used). + * + * witness OCTET STRING, + * -- the result of applying the one-way function (owf) to a + * -- randomly-generated INTEGER, A. [Note that a different + * -- INTEGER MUST be used for each Challenge.] + * challenge OCTET STRING + * -- the encryption (under the public key for which the cert. + * -- request is being made) of Rand, where Rand is specified as + * -- Rand ::= SEQUENCE { + * -- int INTEGER, + * -- - the randomly-generated INTEGER A (above) + * -- sender GeneralName + * -- - the sender's name (as included in PKIHeader) + * -- } + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + addOptional(v, owf); + v.add(witness); + v.add(challenge); + + return new DERSequence(v); + } + + private void addOptional(ASN1EncodableVector v, ASN1Encodable obj) + { + if (obj != null) + { + v.add(obj); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/ErrorMsgContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/ErrorMsgContent.java new file mode 100644 index 00000000..e7ef5716 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/ErrorMsgContent.java @@ -0,0 +1,121 @@ +package org.spongycastle.asn1.cmp; + +import java.util.Enumeration; + +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.DERSequence; + +public class ErrorMsgContent + extends ASN1Object +{ + private PKIStatusInfo pkiStatusInfo; + private ASN1Integer errorCode; + private PKIFreeText errorDetails; + + private ErrorMsgContent(ASN1Sequence seq) + { + Enumeration en = seq.getObjects(); + + pkiStatusInfo = PKIStatusInfo.getInstance(en.nextElement()); + + while (en.hasMoreElements()) + { + Object o = en.nextElement(); + + if (o instanceof ASN1Integer) + { + errorCode = ASN1Integer.getInstance(o); + } + else + { + errorDetails = PKIFreeText.getInstance(o); + } + } + } + + public static ErrorMsgContent getInstance(Object o) + { + if (o instanceof ErrorMsgContent) + { + return (ErrorMsgContent)o; + } + + if (o != null) + { + return new ErrorMsgContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public ErrorMsgContent(PKIStatusInfo pkiStatusInfo) + { + this(pkiStatusInfo, null, null); + } + + public ErrorMsgContent( + PKIStatusInfo pkiStatusInfo, + ASN1Integer errorCode, + PKIFreeText errorDetails) + { + if (pkiStatusInfo == null) + { + throw new IllegalArgumentException("'pkiStatusInfo' cannot be null"); + } + + this.pkiStatusInfo = pkiStatusInfo; + this.errorCode = errorCode; + this.errorDetails = errorDetails; + } + + public PKIStatusInfo getPKIStatusInfo() + { + return pkiStatusInfo; + } + + public ASN1Integer getErrorCode() + { + return errorCode; + } + + public PKIFreeText getErrorDetails() + { + return errorDetails; + } + + /** + * <pre> + * ErrorMsgContent ::= SEQUENCE { + * pKIStatusInfo PKIStatusInfo, + * errorCode INTEGER OPTIONAL, + * -- implementation-specific error codes + * errorDetails PKIFreeText OPTIONAL + * -- implementation-specific error details + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(pkiStatusInfo); + addOptional(v, errorCode); + addOptional(v, errorDetails); + + return new DERSequence(v); + } + + private void addOptional(ASN1EncodableVector v, ASN1Encodable obj) + { + if (obj != null) + { + v.add(obj); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/GenMsgContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/GenMsgContent.java new file mode 100644 index 00000000..5d65e0d1 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/GenMsgContent.java @@ -0,0 +1,71 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class GenMsgContent + extends ASN1Object +{ + private ASN1Sequence content; + + private GenMsgContent(ASN1Sequence seq) + { + content = seq; + } + + public static GenMsgContent getInstance(Object o) + { + if (o instanceof GenMsgContent) + { + return (GenMsgContent)o; + } + + if (o != null) + { + return new GenMsgContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public GenMsgContent(InfoTypeAndValue itv) + { + content = new DERSequence(itv); + } + + public GenMsgContent(InfoTypeAndValue[] itv) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < itv.length; i++) + { + v.add(itv[i]); + } + content = new DERSequence(v); + } + + public InfoTypeAndValue[] toInfoTypeAndValueArray() + { + InfoTypeAndValue[] result = new InfoTypeAndValue[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = InfoTypeAndValue.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * GenMsgContent ::= SEQUENCE OF InfoTypeAndValue + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/GenRepContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/GenRepContent.java new file mode 100644 index 00000000..a6a2f4db --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/GenRepContent.java @@ -0,0 +1,71 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class GenRepContent + extends ASN1Object +{ + private ASN1Sequence content; + + private GenRepContent(ASN1Sequence seq) + { + content = seq; + } + + public static GenRepContent getInstance(Object o) + { + if (o instanceof GenRepContent) + { + return (GenRepContent)o; + } + + if (o != null) + { + return new GenRepContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public GenRepContent(InfoTypeAndValue itv) + { + content = new DERSequence(itv); + } + + public GenRepContent(InfoTypeAndValue[] itv) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < itv.length; i++) + { + v.add(itv[i]); + } + content = new DERSequence(v); + } + + public InfoTypeAndValue[] toInfoTypeAndValueArray() + { + InfoTypeAndValue[] result = new InfoTypeAndValue[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = InfoTypeAndValue.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * GenRepContent ::= SEQUENCE OF InfoTypeAndValue + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/InfoTypeAndValue.java b/core/src/main/java/org/spongycastle/asn1/cmp/InfoTypeAndValue.java new file mode 100644 index 00000000..3f99d1e1 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/InfoTypeAndValue.java @@ -0,0 +1,132 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +/** + * Example InfoTypeAndValue contents include, but are not limited + * to, the following (un-comment in this ASN.1 module and use as + * appropriate for a given environment): + * <pre> + * id-it-caProtEncCert OBJECT IDENTIFIER ::= {id-it 1} + * CAProtEncCertValue ::= CMPCertificate + * id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2} + * SignKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + * id-it-encKeyPairTypes OBJECT IDENTIFIER ::= {id-it 3} + * EncKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + * id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4} + * PreferredSymmAlgValue ::= AlgorithmIdentifier + * id-it-caKeyUpdateInfo OBJECT IDENTIFIER ::= {id-it 5} + * CAKeyUpdateInfoValue ::= CAKeyUpdAnnContent + * id-it-currentCRL OBJECT IDENTIFIER ::= {id-it 6} + * CurrentCRLValue ::= CertificateList + * id-it-unsupportedOIDs OBJECT IDENTIFIER ::= {id-it 7} + * UnsupportedOIDsValue ::= SEQUENCE OF OBJECT IDENTIFIER + * id-it-keyPairParamReq OBJECT IDENTIFIER ::= {id-it 10} + * KeyPairParamReqValue ::= OBJECT IDENTIFIER + * id-it-keyPairParamRep OBJECT IDENTIFIER ::= {id-it 11} + * KeyPairParamRepValue ::= AlgorithmIdentifer + * id-it-revPassphrase OBJECT IDENTIFIER ::= {id-it 12} + * RevPassphraseValue ::= EncryptedValue + * id-it-implicitConfirm OBJECT IDENTIFIER ::= {id-it 13} + * ImplicitConfirmValue ::= NULL + * id-it-confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14} + * ConfirmWaitTimeValue ::= GeneralizedTime + * id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15} + * OrigPKIMessageValue ::= PKIMessages + * id-it-suppLangTags OBJECT IDENTIFIER ::= {id-it 16} + * SuppLangTagsValue ::= SEQUENCE OF UTF8String + * + * where + * + * id-pkix OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) + * dod(6) internet(1) security(5) mechanisms(5) pkix(7)} + * and + * id-it OBJECT IDENTIFIER ::= {id-pkix 4} + * </pre> + */ +public class InfoTypeAndValue + extends ASN1Object +{ + private ASN1ObjectIdentifier infoType; + private ASN1Encodable infoValue; + + private InfoTypeAndValue(ASN1Sequence seq) + { + infoType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); + + if (seq.size() > 1) + { + infoValue = (ASN1Encodable)seq.getObjectAt(1); + } + } + + public static InfoTypeAndValue getInstance(Object o) + { + if (o instanceof InfoTypeAndValue) + { + return (InfoTypeAndValue)o; + } + + if (o != null) + { + return new InfoTypeAndValue(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public InfoTypeAndValue( + ASN1ObjectIdentifier infoType) + { + this.infoType = infoType; + this.infoValue = null; + } + + public InfoTypeAndValue( + ASN1ObjectIdentifier infoType, + ASN1Encodable optionalValue) + { + this.infoType = infoType; + this.infoValue = optionalValue; + } + + public ASN1ObjectIdentifier getInfoType() + { + return infoType; + } + + public ASN1Encodable getInfoValue() + { + return infoValue; + } + + /** + * <pre> + * InfoTypeAndValue ::= SEQUENCE { + * infoType OBJECT IDENTIFIER, + * infoValue ANY DEFINED BY infoType OPTIONAL + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(infoType); + + if (infoValue != null) + { + v.add(infoValue); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/KeyRecRepContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/KeyRecRepContent.java new file mode 100644 index 00000000..903352e5 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/KeyRecRepContent.java @@ -0,0 +1,142 @@ +package org.spongycastle.asn1.cmp; + +import java.util.Enumeration; + +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; + +public class KeyRecRepContent + extends ASN1Object +{ + private PKIStatusInfo status; + private CMPCertificate newSigCert; + private ASN1Sequence caCerts; + private ASN1Sequence keyPairHist; + + private KeyRecRepContent(ASN1Sequence seq) + { + Enumeration en = seq.getObjects(); + + status = PKIStatusInfo.getInstance(en.nextElement()); + + while (en.hasMoreElements()) + { + ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement()); + + switch (tObj.getTagNo()) + { + case 0: + newSigCert = CMPCertificate.getInstance(tObj.getObject()); + break; + case 1: + caCerts = ASN1Sequence.getInstance(tObj.getObject()); + break; + case 2: + keyPairHist = ASN1Sequence.getInstance(tObj.getObject()); + break; + default: + throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo()); + } + } + } + + public static KeyRecRepContent getInstance(Object o) + { + if (o instanceof KeyRecRepContent) + { + return (KeyRecRepContent)o; + } + + if (o != null) + { + return new KeyRecRepContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + + public PKIStatusInfo getStatus() + { + return status; + } + + public CMPCertificate getNewSigCert() + { + return newSigCert; + } + + public CMPCertificate[] getCaCerts() + { + if (caCerts == null) + { + return null; + } + + CMPCertificate[] results = new CMPCertificate[caCerts.size()]; + + for (int i = 0; i != results.length; i++) + { + results[i] = CMPCertificate.getInstance(caCerts.getObjectAt(i)); + } + + return results; + } + + public CertifiedKeyPair[] getKeyPairHist() + { + if (keyPairHist == null) + { + return null; + } + + CertifiedKeyPair[] results = new CertifiedKeyPair[keyPairHist.size()]; + + for (int i = 0; i != results.length; i++) + { + results[i] = CertifiedKeyPair.getInstance(keyPairHist.getObjectAt(i)); + } + + return results; + } + + /** + * <pre> + * KeyRecRepContent ::= SEQUENCE { + * status PKIStatusInfo, + * newSigCert [0] CMPCertificate OPTIONAL, + * caCerts [1] SEQUENCE SIZE (1..MAX) OF + * CMPCertificate OPTIONAL, + * keyPairHist [2] SEQUENCE SIZE (1..MAX) OF + * CertifiedKeyPair OPTIONAL + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(status); + + addOptional(v, 0, newSigCert); + addOptional(v, 1, caCerts); + addOptional(v, 2, keyPairHist); + + return new DERSequence(v); + } + + private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(true, tagNo, obj)); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/OOBCertHash.java b/core/src/main/java/org/spongycastle/asn1/cmp/OOBCertHash.java new file mode 100644 index 00000000..dc81e7ec --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/OOBCertHash.java @@ -0,0 +1,117 @@ +package org.spongycastle.asn1.cmp; + +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.DERBitString; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.DERTaggedObject; +import org.spongycastle.asn1.crmf.CertId; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; + +public class OOBCertHash + extends ASN1Object +{ + private AlgorithmIdentifier hashAlg; + private CertId certId; + private DERBitString hashVal; + + private OOBCertHash(ASN1Sequence seq) + { + int index = seq.size() - 1; + + hashVal = DERBitString.getInstance(seq.getObjectAt(index--)); + + for (int i = index; i >= 0; i--) + { + ASN1TaggedObject tObj = (ASN1TaggedObject)seq.getObjectAt(i); + + if (tObj.getTagNo() == 0) + { + hashAlg = AlgorithmIdentifier.getInstance(tObj, true); + } + else + { + certId = CertId.getInstance(tObj, true); + } + } + + } + + public static OOBCertHash getInstance(Object o) + { + if (o instanceof OOBCertHash) + { + return (OOBCertHash)o; + } + + if (o != null) + { + return new OOBCertHash(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public OOBCertHash(AlgorithmIdentifier hashAlg, CertId certId, byte[] hashVal) + { + this(hashAlg, certId, new DERBitString(hashVal)); + } + + public OOBCertHash(AlgorithmIdentifier hashAlg, CertId certId, DERBitString hashVal) + { + this.hashAlg = hashAlg; + this.certId = certId; + this.hashVal = hashVal; + } + + public AlgorithmIdentifier getHashAlg() + { + return hashAlg; + } + + public CertId getCertId() + { + return certId; + } + + public DERBitString getHashVal() + { + return hashVal; + } + + /** + * <pre> + * OOBCertHash ::= SEQUENCE { + * hashAlg [0] AlgorithmIdentifier OPTIONAL, + * certId [1] CertId OPTIONAL, + * hashVal BIT STRING + * -- hashVal is calculated over the DER encoding of the + * -- self-signed certificate with the identifier certID. + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + addOptional(v, 0, hashAlg); + addOptional(v, 1, certId); + + v.add(hashVal); + + return new DERSequence(v); + } + + private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(true, tagNo, obj)); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PBMParameter.java b/core/src/main/java/org/spongycastle/asn1/cmp/PBMParameter.java new file mode 100644 index 00000000..83c443cf --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PBMParameter.java @@ -0,0 +1,117 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; + +public class PBMParameter + extends ASN1Object +{ + private ASN1OctetString salt; + private AlgorithmIdentifier owf; + private ASN1Integer iterationCount; + private AlgorithmIdentifier mac; + + private PBMParameter(ASN1Sequence seq) + { + salt = ASN1OctetString.getInstance(seq.getObjectAt(0)); + owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); + iterationCount = ASN1Integer.getInstance(seq.getObjectAt(2)); + mac = AlgorithmIdentifier.getInstance(seq.getObjectAt(3)); + } + + public static PBMParameter getInstance(Object o) + { + if (o instanceof PBMParameter) + { + return (PBMParameter)o; + } + + if (o != null) + { + return new PBMParameter(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public PBMParameter( + byte[] salt, + AlgorithmIdentifier owf, + int iterationCount, + AlgorithmIdentifier mac) + { + this(new DEROctetString(salt), owf, + new ASN1Integer(iterationCount), mac); + } + + public PBMParameter( + ASN1OctetString salt, + AlgorithmIdentifier owf, + ASN1Integer iterationCount, + AlgorithmIdentifier mac) + { + this.salt = salt; + this.owf = owf; + this.iterationCount = iterationCount; + this.mac = mac; + } + + public ASN1OctetString getSalt() + { + return salt; + } + + public AlgorithmIdentifier getOwf() + { + return owf; + } + + public ASN1Integer getIterationCount() + { + return iterationCount; + } + + public AlgorithmIdentifier getMac() + { + return mac; + } + + /** + * <pre> + * PBMParameter ::= SEQUENCE { + * salt OCTET STRING, + * -- note: implementations MAY wish to limit acceptable sizes + * -- of this string to values appropriate for their environment + * -- in order to reduce the risk of denial-of-service attacks + * owf AlgorithmIdentifier, + * -- AlgId for a One-Way Function (SHA-1 recommended) + * iterationCount INTEGER, + * -- number of times the OWF is applied + * -- note: implementations MAY wish to limit acceptable sizes + * -- of this integer to values appropriate for their environment + * -- in order to reduce the risk of denial-of-service attacks + * mac AlgorithmIdentifier + * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], + * } -- or HMAC [RFC2104, RFC2202]) + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(salt); + v.add(owf); + v.add(iterationCount); + v.add(mac); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIBody.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIBody.java new file mode 100644 index 00000000..95b6a11c --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIBody.java @@ -0,0 +1,194 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Choice; +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1TaggedObject; +import org.spongycastle.asn1.DERTaggedObject; +import org.spongycastle.asn1.crmf.CertReqMessages; +import org.spongycastle.asn1.pkcs.CertificationRequest; + +public class PKIBody + extends ASN1Object + implements ASN1Choice +{ + public static final int TYPE_INIT_REQ = 0; + public static final int TYPE_INIT_REP = 1; + public static final int TYPE_CERT_REQ = 2; + public static final int TYPE_CERT_REP = 3; + public static final int TYPE_P10_CERT_REQ = 4; + public static final int TYPE_POPO_CHALL = 5; + public static final int TYPE_POPO_REP = 6; + public static final int TYPE_KEY_UPDATE_REQ = 7; + public static final int TYPE_KEY_UPDATE_REP = 8; + public static final int TYPE_KEY_RECOVERY_REQ = 9; + public static final int TYPE_KEY_RECOVERY_REP = 10; + public static final int TYPE_REVOCATION_REQ = 11; + public static final int TYPE_REVOCATION_REP = 12; + public static final int TYPE_CROSS_CERT_REQ = 13; + public static final int TYPE_CROSS_CERT_REP = 14; + public static final int TYPE_CA_KEY_UPDATE_ANN = 15; + public static final int TYPE_CERT_ANN = 16; + public static final int TYPE_REVOCATION_ANN = 17; + public static final int TYPE_CRL_ANN = 18; + public static final int TYPE_CONFIRM = 19; + public static final int TYPE_NESTED = 20; + public static final int TYPE_GEN_MSG = 21; + public static final int TYPE_GEN_REP = 22; + public static final int TYPE_ERROR = 23; + public static final int TYPE_CERT_CONFIRM = 24; + public static final int TYPE_POLL_REQ = 25; + public static final int TYPE_POLL_REP = 26; + + private int tagNo; + private ASN1Encodable body; + + public static PKIBody getInstance(Object o) + { + if (o == null || o instanceof PKIBody) + { + return (PKIBody)o; + } + + if (o instanceof ASN1TaggedObject) + { + return new PKIBody((ASN1TaggedObject)o); + } + + throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); + } + + private PKIBody(ASN1TaggedObject tagged) + { + tagNo = tagged.getTagNo(); + body = getBodyForType(tagNo, tagged.getObject()); + } + + /** + * Creates a new PKIBody. + * @param type one of the TYPE_* constants + * @param content message content + */ + public PKIBody( + int type, + ASN1Encodable content) + { + tagNo = type; + body = getBodyForType(type, content); + } + + private static ASN1Encodable getBodyForType( + int type, + ASN1Encodable o) + { + switch (type) + { + case TYPE_INIT_REQ: + return CertReqMessages.getInstance(o); + case TYPE_INIT_REP: + return CertRepMessage.getInstance(o); + case TYPE_CERT_REQ: + return CertReqMessages.getInstance(o); + case TYPE_CERT_REP: + return CertRepMessage.getInstance(o); + case TYPE_P10_CERT_REQ: + return CertificationRequest.getInstance(o); + case TYPE_POPO_CHALL: + return POPODecKeyChallContent.getInstance(o); + case TYPE_POPO_REP: + return POPODecKeyRespContent.getInstance(o); + case TYPE_KEY_UPDATE_REQ: + return CertReqMessages.getInstance(o); + case TYPE_KEY_UPDATE_REP: + return CertRepMessage.getInstance(o); + case TYPE_KEY_RECOVERY_REQ: + return CertReqMessages.getInstance(o); + case TYPE_KEY_RECOVERY_REP: + return KeyRecRepContent.getInstance(o); + case TYPE_REVOCATION_REQ: + return RevReqContent.getInstance(o); + case TYPE_REVOCATION_REP: + return RevRepContent.getInstance(o); + case TYPE_CROSS_CERT_REQ: + return CertReqMessages.getInstance(o); + case TYPE_CROSS_CERT_REP: + return CertRepMessage.getInstance(o); + case TYPE_CA_KEY_UPDATE_ANN: + return CAKeyUpdAnnContent.getInstance(o); + case TYPE_CERT_ANN: + return CMPCertificate.getInstance(o); + case TYPE_REVOCATION_ANN: + return RevAnnContent.getInstance(o); + case TYPE_CRL_ANN: + return CRLAnnContent.getInstance(o); + case TYPE_CONFIRM: + return PKIConfirmContent.getInstance(o); + case TYPE_NESTED: + return PKIMessages.getInstance(o); + case TYPE_GEN_MSG: + return GenMsgContent.getInstance(o); + case TYPE_GEN_REP: + return GenRepContent.getInstance(o); + case TYPE_ERROR: + return ErrorMsgContent.getInstance(o); + case TYPE_CERT_CONFIRM: + return CertConfirmContent.getInstance(o); + case TYPE_POLL_REQ: + return PollReqContent.getInstance(o); + case TYPE_POLL_REP: + return PollRepContent.getInstance(o); + default: + throw new IllegalArgumentException("unknown tag number: " + type); + } + } + + public int getType() + { + return tagNo; + } + + public ASN1Encodable getContent() + { + return body; + } + + /** + * <pre> + * PKIBody ::= CHOICE { -- message-specific body elements + * ir [0] CertReqMessages, --Initialization Request + * ip [1] CertRepMessage, --Initialization Response + * cr [2] CertReqMessages, --Certification Request + * cp [3] CertRepMessage, --Certification Response + * p10cr [4] CertificationRequest, --imported from [PKCS10] + * popdecc [5] POPODecKeyChallContent, --pop Challenge + * popdecr [6] POPODecKeyRespContent, --pop Response + * kur [7] CertReqMessages, --Key Update Request + * kup [8] CertRepMessage, --Key Update Response + * krr [9] CertReqMessages, --Key Recovery Request + * krp [10] KeyRecRepContent, --Key Recovery Response + * rr [11] RevReqContent, --Revocation Request + * rp [12] RevRepContent, --Revocation Response + * ccr [13] CertReqMessages, --Cross-Cert. Request + * ccp [14] CertRepMessage, --Cross-Cert. Response + * ckuann [15] CAKeyUpdAnnContent, --CA Key Update Ann. + * cann [16] CertAnnContent, --Certificate Ann. + * rann [17] RevAnnContent, --Revocation Ann. + * crlann [18] CRLAnnContent, --CRL Announcement + * pkiconf [19] PKIConfirmContent, --Confirmation + * nested [20] NestedMessageContent, --Nested Message + * genm [21] GenMsgContent, --General Message + * genp [22] GenRepContent, --General Response + * error [23] ErrorMsgContent, --Error Message + * certConf [24] CertConfirmContent, --Certificate confirm + * pollReq [25] PollReqContent, --Polling request + * pollRep [26] PollRepContent --Polling response + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return new DERTaggedObject(true, tagNo, body); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIConfirmContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIConfirmContent.java new file mode 100644 index 00000000..4019779f --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIConfirmContent.java @@ -0,0 +1,48 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Null; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.DERNull; + +public class PKIConfirmContent + extends ASN1Object +{ + private ASN1Null val; + + private PKIConfirmContent(ASN1Null val) + { + this.val = val; + } + + public static PKIConfirmContent getInstance(Object o) + { + if (o == null || o instanceof PKIConfirmContent) + { + return (PKIConfirmContent)o; + } + + if (o instanceof ASN1Null) + { + return new PKIConfirmContent((ASN1Null)o); + } + + throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); + } + + public PKIConfirmContent() + { + val = DERNull.INSTANCE; + } + + /** + * <pre> + * PKIConfirmContent ::= NULL + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return val; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIFailureInfo.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIFailureInfo.java new file mode 100644 index 00000000..03dd5574 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIFailureInfo.java @@ -0,0 +1,126 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.DERBitString; + +/** + * <pre> + * PKIFailureInfo ::= BIT STRING { + * badAlg (0), + * -- unrecognized or unsupported Algorithm Identifier + * badMessageCheck (1), -- integrity check failed (e.g., signature did not verify) + * badRequest (2), + * -- transaction not permitted or supported + * badTime (3), -- messageTime was not sufficiently close to the system time, as defined by local policy + * badCertId (4), -- no certificate could be found matching the provided criteria + * badDataFormat (5), + * -- the data submitted has the wrong format + * wrongAuthority (6), -- the authority indicated in the request is different from the one creating the response token + * incorrectData (7), -- the requester's data is incorrect (for notary services) + * missingTimeStamp (8), -- when the timestamp is missing but should be there (by policy) + * badPOP (9) -- the proof-of-possession failed + * certRevoked (10), + * certConfirmed (11), + * wrongIntegrity (12), + * badRecipientNonce (13), + * timeNotAvailable (14), + * -- the TSA's time source is not available + * unacceptedPolicy (15), + * -- the requested TSA policy is not supported by the TSA + * unacceptedExtension (16), + * -- the requested extension is not supported by the TSA + * addInfoNotAvailable (17) + * -- the additional information requested could not be understood + * -- or is not available + * badSenderNonce (18), + * badCertTemplate (19), + * signerNotTrusted (20), + * transactionIdInUse (21), + * unsupportedVersion (22), + * notAuthorized (23), + * systemUnavail (24), + * systemFailure (25), + * -- the request cannot be handled due to system failure + * duplicateCertReq (26) + * </pre> + */ +public class PKIFailureInfo + extends DERBitString +{ + public static final int badAlg = (1 << 7); // unrecognized or unsupported Algorithm Identifier + public static final int badMessageCheck = (1 << 6); // integrity check failed (e.g., signature did not verify) + public static final int badRequest = (1 << 5); + public static final int badTime = (1 << 4); // -- messageTime was not sufficiently close to the system time, as defined by local policy + public static final int badCertId = (1 << 3); // no certificate could be found matching the provided criteria + public static final int badDataFormat = (1 << 2); + public static final int wrongAuthority = (1 << 1); // the authority indicated in the request is different from the one creating the response token + public static final int incorrectData = 1; // the requester's data is incorrect (for notary services) + public static final int missingTimeStamp = (1 << 15); // when the timestamp is missing but should be there (by policy) + public static final int badPOP = (1 << 14); // the proof-of-possession failed + public static final int certRevoked = (1 << 13); + public static final int certConfirmed = (1 << 12); + public static final int wrongIntegrity = (1 << 11); + public static final int badRecipientNonce = (1 << 10); + public static final int timeNotAvailable = (1 << 9); // the TSA's time source is not available + public static final int unacceptedPolicy = (1 << 8); // the requested TSA policy is not supported by the TSA + public static final int unacceptedExtension = (1 << 23); //the requested extension is not supported by the TSA + public static final int addInfoNotAvailable = (1 << 22); //the additional information requested could not be understood or is not available + public static final int badSenderNonce = (1 << 21); + public static final int badCertTemplate = (1 << 20); + public static final int signerNotTrusted = (1 << 19); + public static final int transactionIdInUse = (1 << 18); + public static final int unsupportedVersion = (1 << 17); + public static final int notAuthorized = (1 << 16); + public static final int systemUnavail = (1 << 31); + public static final int systemFailure = (1 << 30); //the request cannot be handled due to system failure + public static final int duplicateCertReq = (1 << 29); + + /** @deprecated use lower case version */ + public static final int BAD_ALG = badAlg; // unrecognized or unsupported Algorithm Identifier + /** @deprecated use lower case version */ + public static final int BAD_MESSAGE_CHECK = badMessageCheck; + /** @deprecated use lower case version */ + public static final int BAD_REQUEST = badRequest; // transaction not permitted or supported + /** @deprecated use lower case version */ + public static final int BAD_TIME = badTime; + /** @deprecated use lower case version */ + public static final int BAD_CERT_ID = badCertId; + /** @deprecated use lower case version */ + public static final int BAD_DATA_FORMAT = badDataFormat; // the data submitted has the wrong format + /** @deprecated use lower case version */ + public static final int WRONG_AUTHORITY = wrongAuthority; + /** @deprecated use lower case version */ + public static final int INCORRECT_DATA = incorrectData; + /** @deprecated use lower case version */ + public static final int MISSING_TIME_STAMP = missingTimeStamp; + /** @deprecated use lower case version */ + public static final int BAD_POP = badPOP; + /** @deprecated use lower case version */ + public static final int TIME_NOT_AVAILABLE = timeNotAvailable; + /** @deprecated use lower case version */ + public static final int UNACCEPTED_POLICY = unacceptedPolicy; + /** @deprecated use lower case version */ + public static final int UNACCEPTED_EXTENSION = unacceptedExtension; + /** @deprecated use lower case version */ + public static final int ADD_INFO_NOT_AVAILABLE = addInfoNotAvailable; + /** @deprecated use lower case version */ + public static final int SYSTEM_FAILURE = systemFailure; + /** + * Basic constructor. + */ + public PKIFailureInfo( + int info) + { + super(getBytes(info), getPadBits(info)); + } + + public PKIFailureInfo( + DERBitString info) + { + super(info.getBytes(), info.getPadBits()); + } + + public String toString() + { + return "PKIFailureInfo: 0x" + Integer.toHexString(this.intValue()); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIFreeText.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIFreeText.java new file mode 100644 index 00000000..8a10714f --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIFreeText.java @@ -0,0 +1,115 @@ +package org.spongycastle.asn1.cmp; + +import java.util.Enumeration; + +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.DERUTF8String; + +public class PKIFreeText + extends ASN1Object +{ + ASN1Sequence strings; + + public static PKIFreeText getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + return getInstance(ASN1Sequence.getInstance(obj, explicit)); + } + + public static PKIFreeText getInstance( + Object obj) + { + if (obj instanceof PKIFreeText) + { + return (PKIFreeText)obj; + } + else if (obj != null) + { + return new PKIFreeText(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private PKIFreeText( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + while (e.hasMoreElements()) + { + if (!(e.nextElement() instanceof DERUTF8String)) + { + throw new IllegalArgumentException("attempt to insert non UTF8 STRING into PKIFreeText"); + } + } + + strings = seq; + } + + public PKIFreeText( + DERUTF8String p) + { + strings = new DERSequence(p); + } + + public PKIFreeText( + String p) + { + this(new DERUTF8String(p)); + } + + public PKIFreeText( + DERUTF8String[] strs) + { + strings = new DERSequence(strs); + } + + public PKIFreeText( + String[] strs) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < strs.length; i++) + { + v.add(new DERUTF8String(strs[i])); + } + strings = new DERSequence(v); + } + + /** + * Return the number of string elements present. + * + * @return number of elements present. + */ + public int size() + { + return strings.size(); + } + + /** + * Return the UTF8STRING at index i. + * + * @param i index of the string of interest + * @return the string at index i. + */ + public DERUTF8String getStringAt( + int i) + { + return (DERUTF8String)strings.getObjectAt(i); + } + + /** + * <pre> + * PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String + * </pre> + */ + public ASN1Primitive toASN1Primitive() + { + return strings; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIHeader.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIHeader.java new file mode 100644 index 00000000..afcd7767 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIHeader.java @@ -0,0 +1,260 @@ +package org.spongycastle.asn1.cmp; + +import java.util.Enumeration; + +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.ASN1OctetString; +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.x500.X500Name; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; +import org.spongycastle.asn1.x509.GeneralName; + +public class PKIHeader + extends ASN1Object +{ + /** + * Value for a "null" recipient or sender. + */ + public static final GeneralName NULL_NAME = new GeneralName(X500Name.getInstance(new DERSequence())); + + public static final int CMP_1999 = 1; + public static final int CMP_2000 = 2; + + private ASN1Integer pvno; + private GeneralName sender; + private GeneralName recipient; + private ASN1GeneralizedTime messageTime; + private AlgorithmIdentifier protectionAlg; + private ASN1OctetString senderKID; // KeyIdentifier + private ASN1OctetString recipKID; // KeyIdentifier + private ASN1OctetString transactionID; + private ASN1OctetString senderNonce; + private ASN1OctetString recipNonce; + private PKIFreeText freeText; + private ASN1Sequence generalInfo; + + private PKIHeader(ASN1Sequence seq) + { + Enumeration en = seq.getObjects(); + + pvno = ASN1Integer.getInstance(en.nextElement()); + sender = GeneralName.getInstance(en.nextElement()); + recipient = GeneralName.getInstance(en.nextElement()); + + while (en.hasMoreElements()) + { + ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); + + switch (tObj.getTagNo()) + { + case 0: + messageTime = ASN1GeneralizedTime.getInstance(tObj, true); + break; + case 1: + protectionAlg = AlgorithmIdentifier.getInstance(tObj, true); + break; + case 2: + senderKID = ASN1OctetString.getInstance(tObj, true); + break; + case 3: + recipKID = ASN1OctetString.getInstance(tObj, true); + break; + case 4: + transactionID = ASN1OctetString.getInstance(tObj, true); + break; + case 5: + senderNonce = ASN1OctetString.getInstance(tObj, true); + break; + case 6: + recipNonce = ASN1OctetString.getInstance(tObj, true); + break; + case 7: + freeText = PKIFreeText.getInstance(tObj, true); + break; + case 8: + generalInfo = ASN1Sequence.getInstance(tObj, true); + break; + default: + throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo()); + } + } + } + + public static PKIHeader getInstance(Object o) + { + if (o instanceof PKIHeader) + { + return (PKIHeader)o; + } + + if (o != null) + { + return new PKIHeader(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public PKIHeader( + int pvno, + GeneralName sender, + GeneralName recipient) + { + this(new ASN1Integer(pvno), sender, recipient); + } + + private PKIHeader( + ASN1Integer pvno, + GeneralName sender, + GeneralName recipient) + { + this.pvno = pvno; + this.sender = sender; + this.recipient = recipient; + } + + public ASN1Integer getPvno() + { + return pvno; + } + + public GeneralName getSender() + { + return sender; + } + + public GeneralName getRecipient() + { + return recipient; + } + + public ASN1GeneralizedTime getMessageTime() + { + return messageTime; + } + + public AlgorithmIdentifier getProtectionAlg() + { + return protectionAlg; + } + + public ASN1OctetString getSenderKID() + { + return senderKID; + } + + public ASN1OctetString getRecipKID() + { + return recipKID; + } + + public ASN1OctetString getTransactionID() + { + return transactionID; + } + + public ASN1OctetString getSenderNonce() + { + return senderNonce; + } + + public ASN1OctetString getRecipNonce() + { + return recipNonce; + } + + public PKIFreeText getFreeText() + { + return freeText; + } + + public InfoTypeAndValue[] getGeneralInfo() + { + if (generalInfo == null) + { + return null; + } + InfoTypeAndValue[] results = new InfoTypeAndValue[generalInfo.size()]; + for (int i = 0; i < results.length; i++) + { + results[i] + = InfoTypeAndValue.getInstance(generalInfo.getObjectAt(i)); + } + return results; + } + + /** + * <pre> + * PKIHeader ::= SEQUENCE { + * pvno INTEGER { cmp1999(1), cmp2000(2) }, + * sender GeneralName, + * -- identifies the sender + * recipient GeneralName, + * -- identifies the intended recipient + * messageTime [0] GeneralizedTime OPTIONAL, + * -- time of production of this message (used when sender + * -- believes that the transport will be "suitable"; i.e., + * -- that the time will still be meaningful upon receipt) + * protectionAlg [1] AlgorithmIdentifier OPTIONAL, + * -- algorithm used for calculation of protection bits + * senderKID [2] KeyIdentifier OPTIONAL, + * recipKID [3] KeyIdentifier OPTIONAL, + * -- to identify specific keys used for protection + * transactionID [4] OCTET STRING OPTIONAL, + * -- identifies the transaction; i.e., this will be the same in + * -- corresponding request, response, certConf, and PKIConf + * -- messages + * senderNonce [5] OCTET STRING OPTIONAL, + * recipNonce [6] OCTET STRING OPTIONAL, + * -- nonces used to provide replay protection, senderNonce + * -- is inserted by the creator of this message; recipNonce + * -- is a nonce previously inserted in a related message by + * -- the intended recipient of this message + * freeText [7] PKIFreeText OPTIONAL, + * -- this may be used to indicate context-specific instructions + * -- (this field is intended for human consumption) + * generalInfo [8] SEQUENCE SIZE (1..MAX) OF + * InfoTypeAndValue OPTIONAL + * -- this may be used to convey context-specific information + * -- (this field not primarily intended for human consumption) + * } + * </pre> + * + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(pvno); + v.add(sender); + v.add(recipient); + addOptional(v, 0, messageTime); + addOptional(v, 1, protectionAlg); + addOptional(v, 2, senderKID); + addOptional(v, 3, recipKID); + addOptional(v, 4, transactionID); + addOptional(v, 5, senderNonce); + addOptional(v, 6, recipNonce); + addOptional(v, 7, freeText); + addOptional(v, 8, generalInfo); + + return new DERSequence(v); + } + + private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(true, tagNo, obj)); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIHeaderBuilder.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIHeaderBuilder.java new file mode 100644 index 00000000..5249c5e0 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIHeaderBuilder.java @@ -0,0 +1,243 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1GeneralizedTime; +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.DERTaggedObject; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; +import org.spongycastle.asn1.x509.GeneralName; + +public class PKIHeaderBuilder +{ + private ASN1Integer pvno; + private GeneralName sender; + private GeneralName recipient; + private ASN1GeneralizedTime messageTime; + private AlgorithmIdentifier protectionAlg; + private ASN1OctetString senderKID; // KeyIdentifier + private ASN1OctetString recipKID; // KeyIdentifier + private ASN1OctetString transactionID; + private ASN1OctetString senderNonce; + private ASN1OctetString recipNonce; + private PKIFreeText freeText; + private ASN1Sequence generalInfo; + + public PKIHeaderBuilder( + int pvno, + GeneralName sender, + GeneralName recipient) + { + this(new ASN1Integer(pvno), sender, recipient); + } + + private PKIHeaderBuilder( + ASN1Integer pvno, + GeneralName sender, + GeneralName recipient) + { + this.pvno = pvno; + this.sender = sender; + this.recipient = recipient; + } + + public PKIHeaderBuilder setMessageTime(ASN1GeneralizedTime time) + { + messageTime = time; + + return this; + } + + public PKIHeaderBuilder setProtectionAlg(AlgorithmIdentifier aid) + { + protectionAlg = aid; + + return this; + } + + public PKIHeaderBuilder setSenderKID(byte[] kid) + { + return setSenderKID(kid == null ? null : new DEROctetString(kid)); + } + + public PKIHeaderBuilder setSenderKID(ASN1OctetString kid) + { + senderKID = kid; + + return this; + } + + public PKIHeaderBuilder setRecipKID(byte[] kid) + { + return setRecipKID(kid == null ? null : new DEROctetString(kid)); + } + + public PKIHeaderBuilder setRecipKID(DEROctetString kid) + { + recipKID = kid; + + return this; + } + + public PKIHeaderBuilder setTransactionID(byte[] tid) + { + return setTransactionID(tid == null ? null : new DEROctetString(tid)); + } + + public PKIHeaderBuilder setTransactionID(ASN1OctetString tid) + { + transactionID = tid; + + return this; + } + + public PKIHeaderBuilder setSenderNonce(byte[] nonce) + { + return setSenderNonce(nonce == null ? null : new DEROctetString(nonce)); + } + + public PKIHeaderBuilder setSenderNonce(ASN1OctetString nonce) + { + senderNonce = nonce; + + return this; + } + + public PKIHeaderBuilder setRecipNonce(byte[] nonce) + { + return setRecipNonce(nonce == null ? null : new DEROctetString(nonce)); + } + + public PKIHeaderBuilder setRecipNonce(ASN1OctetString nonce) + { + recipNonce = nonce; + + return this; + } + + public PKIHeaderBuilder setFreeText(PKIFreeText text) + { + freeText = text; + + return this; + } + + public PKIHeaderBuilder setGeneralInfo(InfoTypeAndValue genInfo) + { + return setGeneralInfo(makeGeneralInfoSeq(genInfo)); + } + + public PKIHeaderBuilder setGeneralInfo(InfoTypeAndValue[] genInfos) + { + return setGeneralInfo(makeGeneralInfoSeq(genInfos)); + } + + public PKIHeaderBuilder setGeneralInfo(ASN1Sequence seqOfInfoTypeAndValue) + { + generalInfo = seqOfInfoTypeAndValue; + + return this; + } + + private static ASN1Sequence makeGeneralInfoSeq( + InfoTypeAndValue generalInfo) + { + return new DERSequence(generalInfo); + } + + private static ASN1Sequence makeGeneralInfoSeq( + InfoTypeAndValue[] generalInfos) + { + ASN1Sequence genInfoSeq = null; + if (generalInfos != null) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < generalInfos.length; i++) + { + v.add(generalInfos[i]); + } + genInfoSeq = new DERSequence(v); + } + return genInfoSeq; + } + + /** + * <pre> + * PKIHeader ::= SEQUENCE { + * pvno INTEGER { cmp1999(1), cmp2000(2) }, + * sender GeneralName, + * -- identifies the sender + * recipient GeneralName, + * -- identifies the intended recipient + * messageTime [0] GeneralizedTime OPTIONAL, + * -- time of production of this message (used when sender + * -- believes that the transport will be "suitable"; i.e., + * -- that the time will still be meaningful upon receipt) + * protectionAlg [1] AlgorithmIdentifier OPTIONAL, + * -- algorithm used for calculation of protection bits + * senderKID [2] KeyIdentifier OPTIONAL, + * recipKID [3] KeyIdentifier OPTIONAL, + * -- to identify specific keys used for protection + * transactionID [4] OCTET STRING OPTIONAL, + * -- identifies the transaction; i.e., this will be the same in + * -- corresponding request, response, certConf, and PKIConf + * -- messages + * senderNonce [5] OCTET STRING OPTIONAL, + * recipNonce [6] OCTET STRING OPTIONAL, + * -- nonces used to provide replay protection, senderNonce + * -- is inserted by the creator of this message; recipNonce + * -- is a nonce previously inserted in a related message by + * -- the intended recipient of this message + * freeText [7] PKIFreeText OPTIONAL, + * -- this may be used to indicate context-specific instructions + * -- (this field is intended for human consumption) + * generalInfo [8] SEQUENCE SIZE (1..MAX) OF + * InfoTypeAndValue OPTIONAL + * -- this may be used to convey context-specific information + * -- (this field not primarily intended for human consumption) + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public PKIHeader build() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(pvno); + v.add(sender); + v.add(recipient); + addOptional(v, 0, messageTime); + addOptional(v, 1, protectionAlg); + addOptional(v, 2, senderKID); + addOptional(v, 3, recipKID); + addOptional(v, 4, transactionID); + addOptional(v, 5, senderNonce); + addOptional(v, 6, recipNonce); + addOptional(v, 7, freeText); + addOptional(v, 8, generalInfo); + + messageTime = null; + protectionAlg = null; + senderKID = null; + recipKID = null; + transactionID = null; + senderNonce = null; + recipNonce = null; + freeText = null; + generalInfo = null; + + return PKIHeader.getInstance(new DERSequence(v)); + } + + private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(true, tagNo, obj)); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIMessage.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIMessage.java new file mode 100644 index 00000000..fbb4dfe7 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIMessage.java @@ -0,0 +1,166 @@ +package org.spongycastle.asn1.cmp; + +import java.util.Enumeration; + +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.DERBitString; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.DERTaggedObject; + +public class PKIMessage + extends ASN1Object +{ + private PKIHeader header; + private PKIBody body; + private DERBitString protection; + private ASN1Sequence extraCerts; + + private PKIMessage(ASN1Sequence seq) + { + Enumeration en = seq.getObjects(); + + header = PKIHeader.getInstance(en.nextElement()); + body = PKIBody.getInstance(en.nextElement()); + + while (en.hasMoreElements()) + { + ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); + + if (tObj.getTagNo() == 0) + { + protection = DERBitString.getInstance(tObj, true); + } + else + { + extraCerts = ASN1Sequence.getInstance(tObj, true); + } + } + } + + public static PKIMessage getInstance(Object o) + { + if (o instanceof PKIMessage) + { + return (PKIMessage)o; + } + else if (o != null) + { + return new PKIMessage(ASN1Sequence.getInstance(o)); + } + + return null; + } + + /** + * Creates a new PKIMessage. + * + * @param header message header + * @param body message body + * @param protection message protection (may be null) + * @param extraCerts extra certificates (may be null) + */ + public PKIMessage( + PKIHeader header, + PKIBody body, + DERBitString protection, + CMPCertificate[] extraCerts) + { + this.header = header; + this.body = body; + this.protection = protection; + if (extraCerts != null) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < extraCerts.length; i++) + { + v.add(extraCerts[i]); + } + this.extraCerts = new DERSequence(v); + } + } + + public PKIMessage( + PKIHeader header, + PKIBody body, + DERBitString protection) + { + this(header, body, protection, null); + } + + public PKIMessage( + PKIHeader header, + PKIBody body) + { + this(header, body, null, null); + } + + public PKIHeader getHeader() + { + return header; + } + + public PKIBody getBody() + { + return body; + } + + public DERBitString getProtection() + { + return protection; + } + + public CMPCertificate[] getExtraCerts() + { + if (extraCerts == null) + { + return null; + } + + CMPCertificate[] results = new CMPCertificate[extraCerts.size()]; + + for (int i = 0; i < results.length; i++) + { + results[i] = CMPCertificate.getInstance(extraCerts.getObjectAt(i)); + } + return results; + } + + /** + * <pre> + * PKIMessage ::= SEQUENCE { + * header PKIHeader, + * body PKIBody, + * protection [0] PKIProtection OPTIONAL, + * extraCerts [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate + * OPTIONAL + * } + * </pre> + * + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(header); + v.add(body); + + addOptional(v, 0, protection); + addOptional(v, 1, extraCerts); + + return new DERSequence(v); + } + + private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(true, tagNo, obj)); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIMessages.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIMessages.java new file mode 100644 index 00000000..33b47323 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIMessages.java @@ -0,0 +1,71 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class PKIMessages + extends ASN1Object +{ + private ASN1Sequence content; + + private PKIMessages(ASN1Sequence seq) + { + content = seq; + } + + public static PKIMessages getInstance(Object o) + { + if (o instanceof PKIMessages) + { + return (PKIMessages)o; + } + + if (o != null) + { + return new PKIMessages(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public PKIMessages(PKIMessage msg) + { + content = new DERSequence(msg); + } + + public PKIMessages(PKIMessage[] msgs) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + for (int i = 0; i < msgs.length; i++) + { + v.add(msgs[i]); + } + content = new DERSequence(v); + } + + public PKIMessage[] toPKIMessageArray() + { + PKIMessage[] result = new PKIMessage[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = PKIMessage.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIStatus.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIStatus.java new file mode 100644 index 00000000..af4235f1 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIStatus.java @@ -0,0 +1,64 @@ +package org.spongycastle.asn1.cmp; + +import java.math.BigInteger; + +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; + +public class PKIStatus + extends ASN1Object +{ + public static final int GRANTED = 0; + public static final int GRANTED_WITH_MODS = 1; + public static final int REJECTION = 2; + public static final int WAITING = 3; + public static final int REVOCATION_WARNING = 4; + public static final int REVOCATION_NOTIFICATION = 5; + public static final int KEY_UPDATE_WARNING = 6; + + public static final PKIStatus granted = new PKIStatus(GRANTED); + public static final PKIStatus grantedWithMods = new PKIStatus(GRANTED_WITH_MODS); + public static final PKIStatus rejection = new PKIStatus(REJECTION); + public static final PKIStatus waiting = new PKIStatus(WAITING); + public static final PKIStatus revocationWarning = new PKIStatus(REVOCATION_WARNING); + public static final PKIStatus revocationNotification = new PKIStatus(REVOCATION_NOTIFICATION); + public static final PKIStatus keyUpdateWaiting = new PKIStatus(KEY_UPDATE_WARNING); + + private ASN1Integer value; + + private PKIStatus(int value) + { + this(new ASN1Integer(value)); + } + + private PKIStatus(ASN1Integer value) + { + this.value = value; + } + + public static PKIStatus getInstance(Object o) + { + if (o instanceof PKIStatus) + { + return (PKIStatus)o; + } + + if (o != null) + { + return new PKIStatus(ASN1Integer.getInstance(o)); + } + + return null; + } + + public BigInteger getValue() + { + return value.getValue(); + } + + public ASN1Primitive toASN1Primitive() + { + return value; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PKIStatusInfo.java b/core/src/main/java/org/spongycastle/asn1/cmp/PKIStatusInfo.java new file mode 100644 index 00000000..5deae95f --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PKIStatusInfo.java @@ -0,0 +1,165 @@ +package org.spongycastle.asn1.cmp; + +import java.math.BigInteger; + +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.ASN1TaggedObject; +import org.spongycastle.asn1.DERBitString; +import org.spongycastle.asn1.DERSequence; + +public class PKIStatusInfo + extends ASN1Object +{ + ASN1Integer status; + PKIFreeText statusString; + DERBitString failInfo; + + public static PKIStatusInfo getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + return getInstance(ASN1Sequence.getInstance(obj, explicit)); + } + + public static PKIStatusInfo getInstance( + Object obj) + { + if (obj instanceof PKIStatusInfo) + { + return (PKIStatusInfo)obj; + } + else if (obj != null) + { + return new PKIStatusInfo(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + private PKIStatusInfo( + ASN1Sequence seq) + { + this.status = ASN1Integer.getInstance(seq.getObjectAt(0)); + + this.statusString = null; + this.failInfo = null; + + if (seq.size() > 2) + { + this.statusString = PKIFreeText.getInstance(seq.getObjectAt(1)); + this.failInfo = DERBitString.getInstance(seq.getObjectAt(2)); + } + else if (seq.size() > 1) + { + Object obj = seq.getObjectAt(1); + if (obj instanceof DERBitString) + { + this.failInfo = DERBitString.getInstance(obj); + } + else + { + this.statusString = PKIFreeText.getInstance(obj); + } + } + } + + /** + * @param status + */ + public PKIStatusInfo(PKIStatus status) + { + this.status = ASN1Integer.getInstance(status.toASN1Primitive()); + } + + /** + * + * @param status + * @param statusString + */ + public PKIStatusInfo( + PKIStatus status, + PKIFreeText statusString) + { + this.status = ASN1Integer.getInstance(status.toASN1Primitive()); + this.statusString = statusString; + } + + public PKIStatusInfo( + PKIStatus status, + PKIFreeText statusString, + PKIFailureInfo failInfo) + { + this.status = ASN1Integer.getInstance(status.toASN1Primitive()); + this.statusString = statusString; + this.failInfo = failInfo; + } + + public BigInteger getStatus() + { + return status.getValue(); + } + + public PKIFreeText getStatusString() + { + return statusString; + } + + public DERBitString getFailInfo() + { + return failInfo; + } + + /** + * <pre> + * PKIStatusInfo ::= SEQUENCE { + * status PKIStatus, (INTEGER) + * statusString PKIFreeText OPTIONAL, + * failInfo PKIFailureInfo OPTIONAL (BIT STRING) + * } + * + * PKIStatus: + * granted (0), -- you got exactly what you asked for + * grantedWithMods (1), -- you got something like what you asked for + * rejection (2), -- you don't get it, more information elsewhere in the message + * waiting (3), -- the request body part has not yet been processed, expect to hear more later + * revocationWarning (4), -- this message contains a warning that a revocation is imminent + * revocationNotification (5), -- notification that a revocation has occurred + * keyUpdateWarning (6) -- update already done for the oldCertId specified in CertReqMsg + * + * PKIFailureInfo: + * badAlg (0), -- unrecognized or unsupported Algorithm Identifier + * badMessageCheck (1), -- integrity check failed (e.g., signature did not verify) + * badRequest (2), -- transaction not permitted or supported + * badTime (3), -- messageTime was not sufficiently close to the system time, as defined by local policy + * badCertId (4), -- no certificate could be found matching the provided criteria + * badDataFormat (5), -- the data submitted has the wrong format + * wrongAuthority (6), -- the authority indicated in the request is different from the one creating the response token + * incorrectData (7), -- the requester's data is incorrect (for notary services) + * missingTimeStamp (8), -- when the timestamp is missing but should be there (by policy) + * badPOP (9) -- the proof-of-possession failed + * + * </pre> + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(status); + + if (statusString != null) + { + v.add(statusString); + } + + if (failInfo!= null) + { + v.add(failInfo); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/POPODecKeyChallContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/POPODecKeyChallContent.java new file mode 100644 index 00000000..2c636143 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/POPODecKeyChallContent.java @@ -0,0 +1,54 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; + +public class POPODecKeyChallContent + extends ASN1Object +{ + private ASN1Sequence content; + + private POPODecKeyChallContent(ASN1Sequence seq) + { + content = seq; + } + + public static POPODecKeyChallContent getInstance(Object o) + { + if (o instanceof POPODecKeyChallContent) + { + return (POPODecKeyChallContent)o; + } + + if (o != null) + { + return new POPODecKeyChallContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public Challenge[] toChallengeArray() + { + Challenge[] result = new Challenge[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = Challenge.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * POPODecKeyChallContent ::= SEQUENCE OF Challenge + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/POPODecKeyRespContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/POPODecKeyRespContent.java new file mode 100644 index 00000000..48466b89 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/POPODecKeyRespContent.java @@ -0,0 +1,55 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; + +public class POPODecKeyRespContent + extends ASN1Object +{ + private ASN1Sequence content; + + private POPODecKeyRespContent(ASN1Sequence seq) + { + content = seq; + } + + public static POPODecKeyRespContent getInstance(Object o) + { + if (o instanceof POPODecKeyRespContent) + { + return (POPODecKeyRespContent)o; + } + + if (o != null) + { + return new POPODecKeyRespContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public ASN1Integer[] toASN1IntegerArray() + { + ASN1Integer[] result = new ASN1Integer[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = ASN1Integer.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * POPODecKeyRespContent ::= SEQUENCE OF INTEGER + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PollRepContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/PollRepContent.java new file mode 100644 index 00000000..d2116b9a --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PollRepContent.java @@ -0,0 +1,119 @@ +package org.spongycastle.asn1.cmp; + +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.DERSequence; + +public class PollRepContent + extends ASN1Object +{ + private ASN1Integer[] certReqId; + private ASN1Integer[] checkAfter; + private PKIFreeText[] reason; + + private PollRepContent(ASN1Sequence seq) + { + certReqId = new ASN1Integer[seq.size()]; + checkAfter = new ASN1Integer[seq.size()]; + reason = new PKIFreeText[seq.size()]; + + for (int i = 0; i != seq.size(); i++) + { + ASN1Sequence s = ASN1Sequence.getInstance(seq.getObjectAt(i)); + + certReqId[i] = ASN1Integer.getInstance(s.getObjectAt(0)); + checkAfter[i] = ASN1Integer.getInstance(s.getObjectAt(1)); + + if (s.size() > 2) + { + reason[i] = PKIFreeText.getInstance(s.getObjectAt(2)); + } + } + } + + public static PollRepContent getInstance(Object o) + { + if (o instanceof PollRepContent) + { + return (PollRepContent)o; + } + + if (o != null) + { + return new PollRepContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public PollRepContent(ASN1Integer certReqId, ASN1Integer checkAfter) + { + this(certReqId, checkAfter, null); + } + + public PollRepContent(ASN1Integer certReqId, ASN1Integer checkAfter, PKIFreeText reason) + { + this.certReqId = new ASN1Integer[1]; + this.checkAfter = new ASN1Integer[1]; + this.reason = new PKIFreeText[1]; + + this.certReqId[0] = certReqId; + this.checkAfter[0] = checkAfter; + this.reason[0] = reason; + } + + public int size() + { + return certReqId.length; + } + + public ASN1Integer getCertReqId(int index) + { + return certReqId[index]; + } + + public ASN1Integer getCheckAfter(int index) + { + return checkAfter[index]; + } + + public PKIFreeText getReason(int index) + { + return reason[index]; + } + + /** + * <pre> + * PollRepContent ::= SEQUENCE OF SEQUENCE { + * certReqId INTEGER, + * checkAfter INTEGER, -- time in seconds + * reason PKIFreeText OPTIONAL + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector outer = new ASN1EncodableVector(); + + for (int i = 0; i != certReqId.length; i++) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(certReqId[i]); + v.add(checkAfter[i]); + + if (reason[i] != null) + { + v.add(reason[i]); + } + + outer.add(new DERSequence(v)); + } + + return new DERSequence(outer); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/PollReqContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/PollReqContent.java new file mode 100644 index 00000000..58bfbd08 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/PollReqContent.java @@ -0,0 +1,80 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class PollReqContent + extends ASN1Object +{ + private ASN1Sequence content; + + private PollReqContent(ASN1Sequence seq) + { + content = seq; + } + + public static PollReqContent getInstance(Object o) + { + if (o instanceof PollReqContent) + { + return (PollReqContent)o; + } + + if (o != null) + { + return new PollReqContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + /** + * Create a pollReqContent for a single certReqId. + * + * @param certReqId the certificate request ID. + */ + public PollReqContent(ASN1Integer certReqId) + { + this(new DERSequence(new DERSequence(certReqId))); + } + + public ASN1Integer[][] getCertReqIds() + { + ASN1Integer[][] result = new ASN1Integer[content.size()][]; + + for (int i = 0; i != result.length; i++) + { + result[i] = sequenceToASN1IntegerArray((ASN1Sequence)content.getObjectAt(i)); + } + + return result; + } + + private static ASN1Integer[] sequenceToASN1IntegerArray(ASN1Sequence seq) + { + ASN1Integer[] result = new ASN1Integer[seq.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = ASN1Integer.getInstance(seq.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * PollReqContent ::= SEQUENCE OF SEQUENCE { + * certReqId INTEGER + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/ProtectedPart.java b/core/src/main/java/org/spongycastle/asn1/cmp/ProtectedPart.java new file mode 100644 index 00000000..7594e8ec --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/ProtectedPart.java @@ -0,0 +1,70 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class ProtectedPart + extends ASN1Object +{ + private PKIHeader header; + private PKIBody body; + + private ProtectedPart(ASN1Sequence seq) + { + header = PKIHeader.getInstance(seq.getObjectAt(0)); + body = PKIBody.getInstance(seq.getObjectAt(1)); + } + + public static ProtectedPart getInstance(Object o) + { + if (o instanceof ProtectedPart) + { + return (ProtectedPart)o; + } + + if (o != null) + { + return new ProtectedPart(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public ProtectedPart(PKIHeader header, PKIBody body) + { + this.header = header; + this.body = body; + } + + public PKIHeader getHeader() + { + return header; + } + + public PKIBody getBody() + { + return body; + } + + /** + * <pre> + * ProtectedPart ::= SEQUENCE { + * header PKIHeader, + * body PKIBody + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(header); + v.add(body); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/RevAnnContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/RevAnnContent.java new file mode 100644 index 00000000..39d4de9e --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/RevAnnContent.java @@ -0,0 +1,103 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1GeneralizedTime; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.crmf.CertId; +import org.spongycastle.asn1.x509.Extensions; + +public class RevAnnContent + extends ASN1Object +{ + private PKIStatus status; + private CertId certId; + private ASN1GeneralizedTime willBeRevokedAt; + private ASN1GeneralizedTime badSinceDate; + private Extensions crlDetails; + + private RevAnnContent(ASN1Sequence seq) + { + status = PKIStatus.getInstance(seq.getObjectAt(0)); + certId = CertId.getInstance(seq.getObjectAt(1)); + willBeRevokedAt = ASN1GeneralizedTime.getInstance(seq.getObjectAt(2)); + badSinceDate = ASN1GeneralizedTime.getInstance(seq.getObjectAt(3)); + + if (seq.size() > 4) + { + crlDetails = Extensions.getInstance(seq.getObjectAt(4)); + } + } + + public static RevAnnContent getInstance(Object o) + { + if (o instanceof RevAnnContent) + { + return (RevAnnContent)o; + } + + if (o != null) + { + return new RevAnnContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public PKIStatus getStatus() + { + return status; + } + + public CertId getCertId() + { + return certId; + } + + public ASN1GeneralizedTime getWillBeRevokedAt() + { + return willBeRevokedAt; + } + + public ASN1GeneralizedTime getBadSinceDate() + { + return badSinceDate; + } + + public Extensions getCrlDetails() + { + return crlDetails; + } + + /** + * <pre> + * RevAnnContent ::= SEQUENCE { + * status PKIStatus, + * certId CertId, + * willBeRevokedAt GeneralizedTime, + * badSinceDate GeneralizedTime, + * crlDetails Extensions OPTIONAL + * -- extra CRL details (e.g., crl number, reason, location, etc.) + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(status); + v.add(certId); + v.add(willBeRevokedAt); + v.add(badSinceDate); + + if (crlDetails != null) + { + v.add(crlDetails); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/RevDetails.java b/core/src/main/java/org/spongycastle/asn1/cmp/RevDetails.java new file mode 100644 index 00000000..6009a3be --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/RevDetails.java @@ -0,0 +1,100 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.crmf.CertTemplate; +import org.spongycastle.asn1.x509.Extensions; +import org.spongycastle.asn1.x509.X509Extensions; + +public class RevDetails + extends ASN1Object +{ + private CertTemplate certDetails; + private Extensions crlEntryDetails; + + private RevDetails(ASN1Sequence seq) + { + certDetails = CertTemplate.getInstance(seq.getObjectAt(0)); + if (seq.size() > 1) + { + crlEntryDetails = Extensions.getInstance(seq.getObjectAt(1)); + } + } + + public static RevDetails getInstance(Object o) + { + if (o instanceof RevDetails) + { + return (RevDetails)o; + } + + if (o != null) + { + return new RevDetails(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public RevDetails(CertTemplate certDetails) + { + this.certDetails = certDetails; + } + + /** + * @deprecated use method taking Extensions + * @param certDetails + * @param crlEntryDetails + */ + public RevDetails(CertTemplate certDetails, X509Extensions crlEntryDetails) + { + this.certDetails = certDetails; + this.crlEntryDetails = Extensions.getInstance(crlEntryDetails.toASN1Primitive()); + } + + public RevDetails(CertTemplate certDetails, Extensions crlEntryDetails) + { + this.certDetails = certDetails; + this.crlEntryDetails = crlEntryDetails; + } + + public CertTemplate getCertDetails() + { + return certDetails; + } + + public Extensions getCrlEntryDetails() + { + return crlEntryDetails; + } + + /** + * <pre> + * RevDetails ::= SEQUENCE { + * certDetails CertTemplate, + * -- allows requester to specify as much as they can about + * -- the cert. for which revocation is requested + * -- (e.g., for cases in which serialNumber is not available) + * crlEntryDetails Extensions OPTIONAL + * -- requested crlEntryExtensions + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(certDetails); + + if (crlEntryDetails != null) + { + v.add(crlEntryDetails); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/RevRepContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/RevRepContent.java new file mode 100644 index 00000000..b6774193 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/RevRepContent.java @@ -0,0 +1,137 @@ +package org.spongycastle.asn1.cmp; + +import java.util.Enumeration; + +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; +import org.spongycastle.asn1.crmf.CertId; +import org.spongycastle.asn1.x509.CertificateList; + +public class RevRepContent + extends ASN1Object +{ + private ASN1Sequence status; + private ASN1Sequence revCerts; + private ASN1Sequence crls; + + private RevRepContent(ASN1Sequence seq) + { + Enumeration en = seq.getObjects(); + + status = ASN1Sequence.getInstance(en.nextElement()); + while (en.hasMoreElements()) + { + ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement()); + + if (tObj.getTagNo() == 0) + { + revCerts = ASN1Sequence.getInstance(tObj, true); + } + else + { + crls = ASN1Sequence.getInstance(tObj, true); + } + } + } + + public static RevRepContent getInstance(Object o) + { + if (o instanceof RevRepContent) + { + return (RevRepContent)o; + } + + if (o != null) + { + return new RevRepContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public PKIStatusInfo[] getStatus() + { + PKIStatusInfo[] results = new PKIStatusInfo[status.size()]; + + for (int i = 0; i != results.length; i++) + { + results[i] = PKIStatusInfo.getInstance(status.getObjectAt(i)); + } + + return results; + } + + public CertId[] getRevCerts() + { + if (revCerts == null) + { + return null; + } + + CertId[] results = new CertId[revCerts.size()]; + + for (int i = 0; i != results.length; i++) + { + results[i] = CertId.getInstance(revCerts.getObjectAt(i)); + } + + return results; + } + + public CertificateList[] getCrls() + { + if (crls == null) + { + return null; + } + + CertificateList[] results = new CertificateList[crls.size()]; + + for (int i = 0; i != results.length; i++) + { + results[i] = CertificateList.getInstance(crls.getObjectAt(i)); + } + + return results; + } + + /** + * <pre> + * RevRepContent ::= SEQUENCE { + * status SEQUENCE SIZE (1..MAX) OF PKIStatusInfo, + * -- in same order as was sent in RevReqContent + * revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL, + * -- IDs for which revocation was requested + * -- (same order as status) + * crls [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL + * -- the resulting CRLs (there may be more than one) + * } + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(status); + + addOptional(v, 0, revCerts); + addOptional(v, 1, crls); + + return new DERSequence(v); + } + + private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(true, tagNo, obj)); + } + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/RevRepContentBuilder.java b/core/src/main/java/org/spongycastle/asn1/cmp/RevRepContentBuilder.java new file mode 100644 index 00000000..d154f17c --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/RevRepContentBuilder.java @@ -0,0 +1,59 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.DERTaggedObject; +import org.spongycastle.asn1.crmf.CertId; +import org.spongycastle.asn1.x509.CertificateList; + +public class RevRepContentBuilder +{ + private ASN1EncodableVector status = new ASN1EncodableVector(); + private ASN1EncodableVector revCerts = new ASN1EncodableVector(); + private ASN1EncodableVector crls = new ASN1EncodableVector(); + + public RevRepContentBuilder add(PKIStatusInfo status) + { + this.status.add(status); + + return this; + } + + public RevRepContentBuilder add(PKIStatusInfo status, CertId certId) + { + if (this.status.size() != this.revCerts.size()) + { + throw new IllegalStateException("status and revCerts sequence must be in common order"); + } + this.status.add(status); + this.revCerts.add(certId); + + return this; + } + + public RevRepContentBuilder addCrl(CertificateList crl) + { + this.crls.add(crl); + + return this; + } + + public RevRepContent build() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new DERSequence(status)); + + if (revCerts.size() != 0) + { + v.add(new DERTaggedObject(true, 0, new DERSequence(revCerts))); + } + + if (crls.size() != 0) + { + v.add(new DERTaggedObject(true, 1, new DERSequence(crls))); + } + + return RevRepContent.getInstance(new DERSequence(v)); + } +} diff --git a/core/src/main/java/org/spongycastle/asn1/cmp/RevReqContent.java b/core/src/main/java/org/spongycastle/asn1/cmp/RevReqContent.java new file mode 100644 index 00000000..e232417b --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/cmp/RevReqContent.java @@ -0,0 +1,73 @@ +package org.spongycastle.asn1.cmp; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.DERSequence; + +public class RevReqContent + extends ASN1Object +{ + private ASN1Sequence content; + + private RevReqContent(ASN1Sequence seq) + { + content = seq; + } + + public static RevReqContent getInstance(Object o) + { + if (o instanceof RevReqContent) + { + return (RevReqContent)o; + } + + if (o != null) + { + return new RevReqContent(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public RevReqContent(RevDetails revDetails) + { + this.content = new DERSequence(revDetails); + } + + public RevReqContent(RevDetails[] revDetailsArray) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (int i = 0; i != revDetailsArray.length; i++) + { + v.add(revDetailsArray[i]); + } + + this.content = new DERSequence(v); + } + + public RevDetails[] toRevDetailsArray() + { + RevDetails[] result = new RevDetails[content.size()]; + + for (int i = 0; i != result.length; i++) + { + result[i] = RevDetails.getInstance(content.getObjectAt(i)); + } + + return result; + } + + /** + * <pre> + * RevReqContent ::= SEQUENCE OF RevDetails + * </pre> + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + return content; + } +} |