001: package org.bouncycastle.asn1.pkcs;
002:
003: import java.util.Enumeration;
004:
005: import org.bouncycastle.asn1.ASN1Encodable;
006: import org.bouncycastle.asn1.ASN1EncodableVector;
007: import org.bouncycastle.asn1.ASN1Sequence;
008: import org.bouncycastle.asn1.ASN1Set;
009: import org.bouncycastle.asn1.BERSequence;
010: import org.bouncycastle.asn1.DERInteger;
011: import org.bouncycastle.asn1.DERObject;
012: import org.bouncycastle.asn1.DERTaggedObject;
013:
014: /**
015: * a PKCS#7 signed data object.
016: */
017: public class SignedData extends ASN1Encodable implements
018: PKCSObjectIdentifiers {
019: private DERInteger version;
020: private ASN1Set digestAlgorithms;
021: private ContentInfo contentInfo;
022: private ASN1Set certificates;
023: private ASN1Set crls;
024: private ASN1Set signerInfos;
025:
026: public static SignedData getInstance(Object o) {
027: if (o instanceof SignedData) {
028: return (SignedData) o;
029: } else if (o instanceof ASN1Sequence) {
030: return new SignedData((ASN1Sequence) o);
031: }
032:
033: throw new IllegalArgumentException(
034: "unknown object in factory: " + o);
035: }
036:
037: public SignedData(DERInteger _version, ASN1Set _digestAlgorithms,
038: ContentInfo _contentInfo, ASN1Set _certificates,
039: ASN1Set _crls, ASN1Set _signerInfos) {
040: version = _version;
041: digestAlgorithms = _digestAlgorithms;
042: contentInfo = _contentInfo;
043: certificates = _certificates;
044: crls = _crls;
045: signerInfos = _signerInfos;
046: }
047:
048: public SignedData(ASN1Sequence seq) {
049: Enumeration e = seq.getObjects();
050:
051: version = (DERInteger) e.nextElement();
052: digestAlgorithms = ((ASN1Set) e.nextElement());
053: contentInfo = ContentInfo.getInstance(e.nextElement());
054:
055: while (e.hasMoreElements()) {
056: DERObject o = (DERObject) e.nextElement();
057:
058: //
059: // an interesting feature of SignedData is that there appear to be varying implementations...
060: // for the moment we ignore anything which doesn't fit.
061: //
062: if (o instanceof DERTaggedObject) {
063: DERTaggedObject tagged = (DERTaggedObject) o;
064:
065: switch (tagged.getTagNo()) {
066: case 0:
067: certificates = ASN1Set.getInstance(tagged, false);
068: break;
069: case 1:
070: crls = ASN1Set.getInstance(tagged, false);
071: break;
072: default:
073: throw new IllegalArgumentException(
074: "unknown tag value " + tagged.getTagNo());
075: }
076: } else {
077: signerInfos = (ASN1Set) o;
078: }
079: }
080: }
081:
082: public DERInteger getVersion() {
083: return version;
084: }
085:
086: public ASN1Set getDigestAlgorithms() {
087: return digestAlgorithms;
088: }
089:
090: public ContentInfo getContentInfo() {
091: return contentInfo;
092: }
093:
094: public ASN1Set getCertificates() {
095: return certificates;
096: }
097:
098: public ASN1Set getCRLs() {
099: return crls;
100: }
101:
102: public ASN1Set getSignerInfos() {
103: return signerInfos;
104: }
105:
106: /**
107: * Produce an object suitable for an ASN1OutputStream.
108: * <pre>
109: * SignedData ::= SEQUENCE {
110: * version Version,
111: * digestAlgorithms DigestAlgorithmIdentifiers,
112: * contentInfo ContentInfo,
113: * certificates
114: * [0] IMPLICIT ExtendedCertificatesAndCertificates
115: * OPTIONAL,
116: * crls
117: * [1] IMPLICIT CertificateRevocationLists OPTIONAL,
118: * signerInfos SignerInfos }
119: * </pre>
120: */
121: public DERObject toASN1Object() {
122: ASN1EncodableVector v = new ASN1EncodableVector();
123:
124: v.add(version);
125: v.add(digestAlgorithms);
126: v.add(contentInfo);
127:
128: if (certificates != null) {
129: v.add(new DERTaggedObject(false, 0, certificates));
130: }
131:
132: if (crls != null) {
133: v.add(new DERTaggedObject(false, 1, crls));
134: }
135:
136: v.add(signerInfos);
137:
138: return new BERSequence(v);
139: }
140: }
|