0N/A/*
2362N/A * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.pkcs;
0N/A
0N/Aimport java.io.*;
0N/A
0N/Aimport sun.security.util.*;
0N/A
0N/A/**
0N/A * A ContentInfo type, as defined in PKCS#7.
0N/A *
0N/A * @author Benjamin Renaud
0N/A */
0N/A
0N/Apublic class ContentInfo {
0N/A
0N/A // pkcs7 pre-defined content types
0N/A private static int[] pkcs7 = {1, 2, 840, 113549, 1, 7};
0N/A private static int[] data = {1, 2, 840, 113549, 1, 7, 1};
0N/A private static int[] sdata = {1, 2, 840, 113549, 1, 7, 2};
0N/A private static int[] edata = {1, 2, 840, 113549, 1, 7, 3};
0N/A private static int[] sedata = {1, 2, 840, 113549, 1, 7, 4};
0N/A private static int[] ddata = {1, 2, 840, 113549, 1, 7, 5};
0N/A private static int[] crdata = {1, 2, 840, 113549, 1, 7, 6};
0N/A private static int[] nsdata = {2, 16, 840, 1, 113730, 2, 5};
0N/A // timestamp token (id-ct-TSTInfo) from RFC 3161
0N/A private static int[] tstInfo = {1, 2, 840, 113549, 1, 9, 16, 1, 4};
0N/A // this is for backwards-compatibility with JDK 1.1.x
0N/A private static final int[] OLD_SDATA = {1, 2, 840, 1113549, 1, 7, 2};
0N/A private static final int[] OLD_DATA = {1, 2, 840, 1113549, 1, 7, 1};
0N/A public static ObjectIdentifier PKCS7_OID;
0N/A public static ObjectIdentifier DATA_OID;
0N/A public static ObjectIdentifier SIGNED_DATA_OID;
0N/A public static ObjectIdentifier ENVELOPED_DATA_OID;
0N/A public static ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID;
0N/A public static ObjectIdentifier DIGESTED_DATA_OID;
0N/A public static ObjectIdentifier ENCRYPTED_DATA_OID;
0N/A public static ObjectIdentifier OLD_SIGNED_DATA_OID;
0N/A public static ObjectIdentifier OLD_DATA_OID;
0N/A public static ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID;
0N/A public static ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID;
0N/A
0N/A static {
0N/A PKCS7_OID = ObjectIdentifier.newInternal(pkcs7);
0N/A DATA_OID = ObjectIdentifier.newInternal(data);
0N/A SIGNED_DATA_OID = ObjectIdentifier.newInternal(sdata);
0N/A ENVELOPED_DATA_OID = ObjectIdentifier.newInternal(edata);
0N/A SIGNED_AND_ENVELOPED_DATA_OID = ObjectIdentifier.newInternal(sedata);
0N/A DIGESTED_DATA_OID = ObjectIdentifier.newInternal(ddata);
0N/A ENCRYPTED_DATA_OID = ObjectIdentifier.newInternal(crdata);
0N/A OLD_SIGNED_DATA_OID = ObjectIdentifier.newInternal(OLD_SDATA);
0N/A OLD_DATA_OID = ObjectIdentifier.newInternal(OLD_DATA);
0N/A /**
0N/A * The ASN.1 systax for the Netscape Certificate Sequence
0N/A * data type is defined
0N/A * <a href=http://wp.netscape.com/eng/security/comm4-cert-download.html>
0N/A * here.</a>
0N/A */
0N/A NETSCAPE_CERT_SEQUENCE_OID = ObjectIdentifier.newInternal(nsdata);
0N/A TIMESTAMP_TOKEN_INFO_OID = ObjectIdentifier.newInternal(tstInfo);
0N/A }
0N/A
0N/A ObjectIdentifier contentType;
0N/A DerValue content; // OPTIONAL
0N/A
0N/A public ContentInfo(ObjectIdentifier contentType, DerValue content) {
0N/A this.contentType = contentType;
0N/A this.content = content;
0N/A }
0N/A
0N/A /**
0N/A * Make a contentInfo of type data.
0N/A */
0N/A public ContentInfo(byte[] bytes) {
0N/A DerValue octetString = new DerValue(DerValue.tag_OctetString, bytes);
0N/A this.contentType = DATA_OID;
0N/A this.content = octetString;
0N/A }
0N/A
0N/A /**
0N/A * Parses a PKCS#7 content info.
0N/A */
0N/A public ContentInfo(DerInputStream derin)
0N/A throws IOException, ParsingException
0N/A {
0N/A this(derin, false);
0N/A }
0N/A
0N/A /**
0N/A * Parses a PKCS#7 content info.
0N/A *
0N/A * <p>This constructor is used only for backwards compatibility with
0N/A * PKCS#7 blocks that were generated using JDK1.1.x.
0N/A *
0N/A * @param derin the ASN.1 encoding of the content info.
0N/A * @param oldStyle flag indicating whether or not the given content info
0N/A * is encoded according to JDK1.1.x.
0N/A */
0N/A public ContentInfo(DerInputStream derin, boolean oldStyle)
0N/A throws IOException, ParsingException
0N/A {
0N/A DerInputStream disType;
0N/A DerInputStream disTaggedContent;
0N/A DerValue type;
0N/A DerValue taggedContent;
0N/A DerValue[] typeAndContent;
0N/A DerValue[] contents;
0N/A
0N/A typeAndContent = derin.getSequence(2);
0N/A
0N/A // Parse the content type
0N/A type = typeAndContent[0];
0N/A disType = new DerInputStream(type.toByteArray());
0N/A contentType = disType.getOID();
0N/A
0N/A if (oldStyle) {
0N/A // JDK1.1.x-style encoding
0N/A content = typeAndContent[1];
0N/A } else {
0N/A // This is the correct, standards-compliant encoding.
0N/A // Parse the content (OPTIONAL field).
0N/A // Skip the [0] EXPLICIT tag by pretending that the content is the
0N/A // one and only element in an implicitly tagged set
0N/A if (typeAndContent.length > 1) { // content is OPTIONAL
0N/A taggedContent = typeAndContent[1];
0N/A disTaggedContent
0N/A = new DerInputStream(taggedContent.toByteArray());
0N/A contents = disTaggedContent.getSet(1, true);
0N/A content = contents[0];
0N/A }
0N/A }
0N/A }
0N/A
0N/A public DerValue getContent() {
0N/A return content;
0N/A }
0N/A
0N/A public ObjectIdentifier getContentType() {
0N/A return contentType;
0N/A }
0N/A
0N/A public byte[] getData() throws IOException {
0N/A if (contentType.equals(DATA_OID) ||
0N/A contentType.equals(OLD_DATA_OID) ||
0N/A contentType.equals(TIMESTAMP_TOKEN_INFO_OID)) {
0N/A if (content == null)
0N/A return null;
0N/A else
0N/A return content.getOctetString();
0N/A }
0N/A throw new IOException("content type is not DATA: " + contentType);
0N/A }
0N/A
0N/A public void encode(DerOutputStream out) throws IOException {
0N/A DerOutputStream contentDerCode;
0N/A DerOutputStream seq;
0N/A
0N/A seq = new DerOutputStream();
0N/A seq.putOID(contentType);
0N/A
0N/A // content is optional, it could be external
0N/A if (content != null) {
0N/A DerValue taggedContent = null;
0N/A contentDerCode = new DerOutputStream();
0N/A content.encode(contentDerCode);
0N/A
0N/A // Add the [0] EXPLICIT tag in front of the content encoding
0N/A taggedContent = new DerValue((byte)0xA0,
0N/A contentDerCode.toByteArray());
0N/A seq.putDerValue(taggedContent);
0N/A }
0N/A
0N/A out.write(DerValue.tag_Sequence, seq);
0N/A }
0N/A
0N/A /**
0N/A * Returns a byte array representation of the data held in
0N/A * the content field.
0N/A */
0N/A public byte[] getContentBytes() throws IOException {
0N/A if (content == null)
0N/A return null;
0N/A
0N/A DerInputStream dis = new DerInputStream(content.toByteArray());
0N/A return dis.getOctetString();
0N/A }
0N/A
0N/A public String toString() {
0N/A String out = "";
0N/A
0N/A out += "Content Info Sequence\n\tContent type: " + contentType + "\n";
0N/A out += "\tContent: " + content;
0N/A return out;
0N/A }
0N/A}