Path: blob/master/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java
67766 views
/*1* Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.pkcs;2627import java.io.*;2829import sun.security.util.*;3031/**32* A ContentInfo type, as defined in PKCS#7.33*34* @author Benjamin Renaud35*/3637public class ContentInfo {3839// pkcs7 pre-defined content types40public static ObjectIdentifier PKCS7_OID =41ObjectIdentifier.of(KnownOIDs.PKCS7);42public static ObjectIdentifier DATA_OID =43ObjectIdentifier.of(KnownOIDs.Data);44public static ObjectIdentifier SIGNED_DATA_OID =45ObjectIdentifier.of(KnownOIDs.SignedData);46public static ObjectIdentifier ENVELOPED_DATA_OID =47ObjectIdentifier.of(KnownOIDs.EnvelopedData);48public static ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID =49ObjectIdentifier.of(KnownOIDs.SignedAndEnvelopedData);50public static ObjectIdentifier DIGESTED_DATA_OID =51ObjectIdentifier.of(KnownOIDs.DigestedData);52public static ObjectIdentifier ENCRYPTED_DATA_OID =53ObjectIdentifier.of(KnownOIDs.EncryptedData);5455// this is for backwards-compatibility with JDK 1.1.x56public static ObjectIdentifier OLD_SIGNED_DATA_OID =57ObjectIdentifier.of(KnownOIDs.JDK_OLD_SignedData);58public static ObjectIdentifier OLD_DATA_OID =59ObjectIdentifier.of(KnownOIDs.JDK_OLD_Data);6061// The ASN.1 systax for the Netscape Certificate Sequence data type is62// defined at:63// http://wp.netscape.com/eng/security/comm4-cert-download.html64public static ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID =65ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertSequence);6667// timestamp token (id-ct-TSTInfo) from RFC 316168public static ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID =69ObjectIdentifier.of(KnownOIDs.TimeStampTokenInfo);7071ObjectIdentifier contentType;72DerValue content; // OPTIONAL7374public ContentInfo(ObjectIdentifier contentType, DerValue content) {75this.contentType = contentType;76this.content = content;77}7879/**80* Make a contentInfo of type data.81*/82public ContentInfo(byte[] bytes) {83DerValue octetString = new DerValue(DerValue.tag_OctetString, bytes);84this.contentType = DATA_OID;85this.content = octetString;86}8788/**89* Parses a PKCS#7 content info.90*/91public ContentInfo(DerInputStream derin)92throws IOException, ParsingException93{94this(derin, false);95}9697/**98* Parses a PKCS#7 content info.99*100* <p>This constructor is used only for backwards compatibility with101* PKCS#7 blocks that were generated using JDK1.1.x.102*103* @param derin the ASN.1 encoding of the content info.104* @param oldStyle flag indicating whether or not the given content info105* is encoded according to JDK1.1.x.106*/107public ContentInfo(DerInputStream derin, boolean oldStyle)108throws IOException, ParsingException109{110DerInputStream disType;111DerInputStream disTaggedContent;112DerValue type;113DerValue taggedContent;114DerValue[] typeAndContent;115DerValue[] contents;116117typeAndContent = derin.getSequence(2);118if (typeAndContent.length < 1 || typeAndContent.length > 2) {119throw new ParsingException("Invalid length for ContentInfo");120}121122// Parse the content type123type = typeAndContent[0];124disType = new DerInputStream(type.toByteArray());125contentType = disType.getOID();126127if (oldStyle) {128// JDK1.1.x-style encoding129if (typeAndContent.length > 1) { // content is OPTIONAL130content = typeAndContent[1];131}132} else {133// This is the correct, standards-compliant encoding.134// Parse the content (OPTIONAL field).135// Skip the [0] EXPLICIT tag by pretending that the content is the136// one and only element in an implicitly tagged set137if (typeAndContent.length > 1) { // content is OPTIONAL138taggedContent = typeAndContent[1];139disTaggedContent140= new DerInputStream(taggedContent.toByteArray());141contents = disTaggedContent.getSet(1, true);142if (contents.length != 1) {143throw new ParsingException("ContentInfo encoding error");144}145content = contents[0];146}147}148}149150public DerValue getContent() {151return content;152}153154public ObjectIdentifier getContentType() {155return contentType;156}157158public byte[] getData() throws IOException {159if (contentType.equals(DATA_OID) ||160contentType.equals(OLD_DATA_OID) ||161contentType.equals(TIMESTAMP_TOKEN_INFO_OID)) {162if (content == null)163return null;164else165return content.getOctetString();166}167throw new IOException("content type is not DATA: " + contentType);168}169170public void encode(DerOutputStream out) throws IOException {171DerOutputStream contentDerCode;172DerOutputStream seq;173174seq = new DerOutputStream();175seq.putOID(contentType);176177// content is optional, it could be external178if (content != null) {179DerValue taggedContent = null;180contentDerCode = new DerOutputStream();181content.encode(contentDerCode);182183// Add the [0] EXPLICIT tag in front of the content encoding184taggedContent = new DerValue((byte)0xA0,185contentDerCode.toByteArray());186seq.putDerValue(taggedContent);187}188189out.write(DerValue.tag_Sequence, seq);190}191192/**193* Returns a byte array representation of the data held in194* the content field.195*/196public byte[] getContentBytes() throws IOException {197if (content == null)198return null;199200DerValue v = new DerValue(content.toByteArray());201return v.getOctetString();202}203204public String toString() {205String out = "";206207out += "Content Info Sequence\n\tContent type: " + contentType + "\n";208out += "\tContent: " + content;209return out;210}211}212213214