|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.pkcs; |
|
|
|
import java.io.*; |
|
|
|
import sun.security.util.*; |
|
|
|
/** |
|
* A ContentInfo type, as defined in PKCS#7. |
|
* |
|
* @author Benjamin Renaud |
|
*/ |
|
|
|
public class ContentInfo { |
|
|
|
|
|
public static ObjectIdentifier PKCS7_OID = |
|
ObjectIdentifier.of(KnownOIDs.PKCS7); |
|
public static ObjectIdentifier DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.Data); |
|
public static ObjectIdentifier SIGNED_DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.SignedData); |
|
public static ObjectIdentifier ENVELOPED_DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.EnvelopedData); |
|
public static ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.SignedAndEnvelopedData); |
|
public static ObjectIdentifier DIGESTED_DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.DigestedData); |
|
public static ObjectIdentifier ENCRYPTED_DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.EncryptedData); |
|
|
|
|
|
public static ObjectIdentifier OLD_SIGNED_DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.JDK_OLD_SignedData); |
|
public static ObjectIdentifier OLD_DATA_OID = |
|
ObjectIdentifier.of(KnownOIDs.JDK_OLD_Data); |
|
|
|
// The ASN.1 systax for the Netscape Certificate Sequence data type is |
|
// defined at: |
|
|
|
public static ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID = |
|
ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertSequence); |
|
|
|
|
|
public static ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID = |
|
ObjectIdentifier.of(KnownOIDs.TimeStampTokenInfo); |
|
|
|
ObjectIdentifier contentType; |
|
DerValue content; |
|
|
|
public ContentInfo(ObjectIdentifier contentType, DerValue content) { |
|
this.contentType = contentType; |
|
this.content = content; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public ContentInfo(byte[] bytes) { |
|
DerValue octetString = new DerValue(DerValue.tag_OctetString, bytes); |
|
this.contentType = DATA_OID; |
|
this.content = octetString; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public ContentInfo(DerInputStream derin) |
|
throws IOException, ParsingException |
|
{ |
|
this(derin, false); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public ContentInfo(DerInputStream derin, boolean oldStyle) |
|
throws IOException, ParsingException |
|
{ |
|
DerInputStream disType; |
|
DerInputStream disTaggedContent; |
|
DerValue type; |
|
DerValue taggedContent; |
|
DerValue[] typeAndContent; |
|
DerValue[] contents; |
|
|
|
typeAndContent = derin.getSequence(2); |
|
if (typeAndContent.length < 1 || typeAndContent.length > 2) { |
|
throw new ParsingException("Invalid length for ContentInfo"); |
|
} |
|
|
|
|
|
type = typeAndContent[0]; |
|
disType = new DerInputStream(type.toByteArray()); |
|
contentType = disType.getOID(); |
|
|
|
if (oldStyle) { |
|
|
|
content = typeAndContent[1]; |
|
} else { |
|
// This is the correct, standards-compliant encoding. |
|
// Parse the content (OPTIONAL field). |
|
// Skip the [0] EXPLICIT tag by pretending that the content is the |
|
|
|
if (typeAndContent.length > 1) { |
|
taggedContent = typeAndContent[1]; |
|
disTaggedContent |
|
= new DerInputStream(taggedContent.toByteArray()); |
|
contents = disTaggedContent.getSet(1, true); |
|
if (contents.length != 1) { |
|
throw new ParsingException("ContentInfo encoding error"); |
|
} |
|
content = contents[0]; |
|
} |
|
} |
|
} |
|
|
|
public DerValue getContent() { |
|
return content; |
|
} |
|
|
|
public ObjectIdentifier getContentType() { |
|
return contentType; |
|
} |
|
|
|
public byte[] getData() throws IOException { |
|
if (contentType.equals(DATA_OID) || |
|
contentType.equals(OLD_DATA_OID) || |
|
contentType.equals(TIMESTAMP_TOKEN_INFO_OID)) { |
|
if (content == null) |
|
return null; |
|
else |
|
return content.getOctetString(); |
|
} |
|
throw new IOException("content type is not DATA: " + contentType); |
|
} |
|
|
|
public void encode(DerOutputStream out) throws IOException { |
|
DerOutputStream contentDerCode; |
|
DerOutputStream seq; |
|
|
|
seq = new DerOutputStream(); |
|
seq.putOID(contentType); |
|
|
|
|
|
if (content != null) { |
|
DerValue taggedContent = null; |
|
contentDerCode = new DerOutputStream(); |
|
content.encode(contentDerCode); |
|
|
|
|
|
taggedContent = new DerValue((byte)0xA0, |
|
contentDerCode.toByteArray()); |
|
seq.putDerValue(taggedContent); |
|
} |
|
|
|
out.write(DerValue.tag_Sequence, seq); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public byte[] getContentBytes() throws IOException { |
|
if (content == null) |
|
return null; |
|
|
|
DerValue v = new DerValue(content.toByteArray()); |
|
return v.getOctetString(); |
|
} |
|
|
|
public String toString() { |
|
String out = ""; |
|
|
|
out += "Content Info Sequence\n\tContent type: " + contentType + "\n"; |
|
out += "\tContent: " + content; |
|
return out; |
|
} |
|
} |