1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/**
19* @author Boris Kuznetsov
20* @version $Revision$
21*/
22package org.apache.harmony.security.pkcs7;
23
24import java.util.List;
25import org.apache.harmony.security.asn1.ASN1Implicit;
26import org.apache.harmony.security.asn1.ASN1Integer;
27import org.apache.harmony.security.asn1.ASN1Sequence;
28import org.apache.harmony.security.asn1.ASN1SetOf;
29import org.apache.harmony.security.asn1.ASN1Type;
30import org.apache.harmony.security.asn1.BerInputStream;
31import org.apache.harmony.security.x509.AlgorithmIdentifier;
32import org.apache.harmony.security.x509.Certificate;
33import org.apache.harmony.security.x509.CertificateList;
34
35
36/**
37 * As defined in PKCS #7: Cryptographic Message Syntax Standard
38 * (http://www.ietf.org/rfc/rfc2315.txt)
39 *
40 * SignedData ::= SEQUENCE {
41 *   version Version,
42 *   digestAlgorithms DigestAlgorithmIdentifiers,
43 *   contentInfo ContentInfo,
44 *   certificates
45 *     [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
46 *   crls
47 *     [1] IMPLICIT CertificateRevocationLists OPTIONAL,
48 *   signerInfos SignerInfos }
49 */
50public final class SignedData {
51    private final int version;
52    private final List<?> digestAlgorithms;
53    private final ContentInfo contentInfo;
54    private final List<Certificate> certificates;
55    private final List<CertificateList> crls;
56    private final List<SignerInfo> signerInfos;
57
58    private SignedData(int version, List<?> digestAlgorithms, ContentInfo contentInfo,
59            List<Certificate> certificates, List<CertificateList> crls,
60            List<SignerInfo> signerInfos) {
61        this.version = version;
62        this.digestAlgorithms = digestAlgorithms;
63        this.contentInfo = contentInfo;
64        this.certificates = certificates;
65        this.crls = crls;
66        this.signerInfos = signerInfos;
67    }
68
69    public List<Certificate> getCertificates() {
70        return certificates;
71    }
72
73    public List<CertificateList> getCRLs() {
74        return crls;
75    }
76
77    public List<SignerInfo> getSignerInfos() {
78        return signerInfos;
79    }
80
81    public int getVersion() {
82        return version;
83    }
84
85    @Override public String toString() {
86        StringBuilder res = new StringBuilder();
87        res.append("---- SignedData:");
88        res.append("\nversion: ");
89        res.append(version);
90        res.append("\ndigestAlgorithms: ");
91        res.append(digestAlgorithms.toString());
92        res.append("\ncontentInfo: ");
93        res.append(contentInfo.toString());
94        res.append("\ncertificates: ");
95        if (certificates != null) {
96            res.append(certificates.toString());
97        }
98        res.append("\ncrls: ");
99        if (crls != null) {
100            res.append(crls.toString());
101        }
102        res.append("\nsignerInfos:\n");
103        res.append(signerInfos.toString());
104        res.append("\n---- SignedData End\n]");
105        return res.toString();
106    }
107
108    public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
109            ASN1Integer.getInstance(),
110            new ASN1SetOf(AlgorithmIdentifier.ASN1),
111            ContentInfo.ASN1,
112            new ASN1Implicit(0, new ASN1SetOf(Certificate.ASN1)),
113            new ASN1Implicit(1, new ASN1SetOf(CertificateList.ASN1)),
114            new ASN1SetOf(SignerInfo.ASN1)
115            }) {
116        {
117            setOptional(3); // certificates is optional
118            setOptional(4); // crls is optional
119        }
120
121        @Override protected void getValues(Object object, Object[] values) {
122            SignedData sd = (SignedData) object;
123            values[0] = new byte[] {(byte)sd.version};
124            values[1] = sd.digestAlgorithms;
125            values[2] = sd.contentInfo;
126            values[3] = sd.certificates;
127            values[4] = sd.crls;
128            values[5] = sd.signerInfos;
129        }
130
131        @Override protected Object getDecodedObject(BerInputStream in) {
132            Object[] values = (Object[]) in.content;
133            return new SignedData(
134                        ASN1Integer.toIntValue(values[0]),
135                        (List<?>) values[1],
136                        (ContentInfo) values[2],
137                        (List<Certificate>) values[3],
138                        (List<CertificateList>) values[4],
139                        (List<SignerInfo>) values[5]
140                    );
141        }
142    };
143
144}
145