1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @author Boris Kuznetsov
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @version $Revision$
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.security.pkcs7;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Any;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Explicit;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1OctetString;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Oid;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Sequence;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Type;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.BerInputStream;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * As defined in PKCS #7: Cryptographic Message Syntax Standard
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (http://www.ietf.org/rfc/rfc2315.txt)
37f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ContentInfo ::= SEQUENCE {
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       contentType  ContentType,
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       content      [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     }
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
435c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilsonpublic final class ContentInfo {
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // OIDs
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int[] DATA = new int[] {1, 2, 840, 113549, 1, 7, 1};
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int[] SIGNED_DATA = new int[] {1, 2, 840, 113549, 1, 7, 2};
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int[] ENVELOPED_DATA = new int[] {1, 2, 840, 113549, 1, 7, 3};
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int[] SIGNED_AND_ENVELOPED_DATA = new int[] {1, 2, 840, 113549, 1, 7, 4};
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int[] DIGESTED_DATA = new int[] {1, 2, 840, 113549, 1, 7, 5};
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int[] ENCRYPTED_DATA = new int[] {1, 2, 840, 113549, 1, 7, 6};
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
535c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    private final int[] oid;
545c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    private final Object content;
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] encoding;
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ContentInfo(int[] oid, Object content, byte[] encoding) {
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.oid = oid;
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.content = content;
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.encoding = encoding;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SignedData getSignedData() {
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (Arrays.equals(oid, SIGNED_DATA)) {
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (SignedData)content;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object getContent() {
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return content;
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
73f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int[] getContentType() {
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return oid;
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
77f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncoded() {
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding == null) {
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            encoding = ASN1.encode(this);
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Note: this is internal object and can not be accessible from
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // public API, so encoding is not copied. The classes which use
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // this class should copy encoding before passing it out.
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return encoding;
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
87f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
885c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    @Override public String toString() {
892f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        StringBuilder res = new StringBuilder();
90f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        res.append("==== ContentInfo:");
91f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        res.append("\n== ContentType (OID): ");
925c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        for (int i : oid) {
935c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            res.append(i);
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            res.append(' ');
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
96f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        res.append("\n== Content: ");
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (content != null) {
98f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            res.append("\n");
99f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            res.append(content.toString());
100f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        }
101f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        res.append("\n== Content End");
102f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        res.append("\n==== ContentInfo End\n");
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return res.toString();
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
106f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public static final ASN1Sequence ASN1 =
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        new ASN1Sequence(new ASN1Type[] {
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ASN1Oid.getInstance(),
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                new ASN1Explicit(0, ASN1Any.getInstance())
110f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                })  {
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        {
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setOptional(1); // content is optional
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
114f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
1155c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        @Override protected void getValues(Object object, Object[] values) {
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ContentInfo ci = (ContentInfo) object;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            values[0] = ci.oid;
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ci.content != null) {
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (Arrays.equals(ci.oid, DATA)) {
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (ci.content != null) {
121f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        values[1] =
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            ASN1OctetString.getInstance().encode(ci.content);
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (ci.content instanceof SignedData) {
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    values[1] = SignedData.ASN1.encode(ci.content);
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    values[1] = ci.content;
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1325c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        @Override protected Object getDecodedObject(BerInputStream in) throws IOException {
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object[] values = (Object[]) in.content;
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int[] oid = (int[]) values[0];
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (Arrays.equals(oid, DATA)) {
136f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                if (values[1] != null) {
137f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    return new ContentInfo(oid,
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            ASN1OctetString.getInstance().decode((byte[])values[1]),
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            in.getEncoded());
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }  else {
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return new ContentInfo((int[])values[0], null,
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            in.getEncoded());
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (Arrays.equals(oid, SIGNED_DATA)) {
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return new ContentInfo((int[])values[0],
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        SignedData.ASN1.decode((byte[])values[1]),
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        in.getEncoded());
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1505c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson            return new ContentInfo((int[]) values[0], values[1], in.getEncoded());
151f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        }
152f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes   };
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
154