public class ContentInfoStream
extends java.lang.Object
ContentInfo
type.
The PKCS#7 standard describes a general syntax for data that may have cryptography applied to it, such as digital signatures and digital envelopes.
The ASN.1 type ContentInfo
type associates a content type
(data, signedData, envelopedData, signedAndEnvelopedData, digestedData,
encryptedData
) with some particular content for specifying a
general syntax for content exchanged between entities according the PKCS#7
standard:
ContentInfo ::= SEQUENCE { contentType ContentType, content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
ContentType ::= OBJECT IDENTIFIER
If the optional content
is not present, the content value has to
be supplied by other means.
This class consists of two parts: the first static part implements a factory for registering all the stream implementations of the several PKCS#7 content types. And the second non-static part provides constructors and methods for creating, en- and decoding stream PKCS#7 content type objects in the usual way.
The non-stream supporting equivalent to this class is implemented by the
ContentInfo
class.
When creating a new ContentInfo to be sent use the
ContentInfoStream(ContentStream)
constructor and subsequently call the toASN1Object
or
writeTo
method, e.g.:
// create a PKCS#7 object, e.g. Data: DataStream data = ...; ... // create a ContentInfo for the PKCS#7 object and encode it to a stream: ContentInfoStream cis = new ContentInfoStream(data); OutputStream encoded_stream = ...; cis.writeTo(encoded_stream);However, if you want to sent a ContentInfo without any content, you only have to supply the content type identifier when
creating
a ContentInfoStream object,
e.g.:
ContentInfoStream cis = new ContentInfoStream(ObjectID.pkcs7_data); cis.writeTo(encoded_stream);For parsing an already existing BER encoded ContentInfo object supplied from an input stream, use the
ContentInfoStream(Inputstream)
constructor. This will invoke the
decode
method for starting the decoding
procedure. The decode
method only parses the contentType object
identifier and lets the content itself unparsed. This provides the
possibility for getting the unparsed content by means of the
getContentInputStream
method. This will give
you the possibility of doing the decoding and parsing by yourself.
Alternatively you may call the getContent
method for
getting the content as ContentStream
descendant. Actually when calling getContent
the encoded content
will be decoded and parsed for its internal structure. However, it is
essential to remember that this is a stream implementation, so using
both getContent
and getContentInputStream
would not work!
The different usage may be illustrated by means of the two types of a
SignedData message. When receiving a ContentInfo holding an implicit message
the content is included in the SignedData object, and so the
getContent
method may be appropriate for getting the
already parsed SignedData content, e.g.:
// create a ContentInfoStream from the encoding: ContentInfoStream cis = new ContentInfoStream(encodedStream); // ask for the content type: if (cis.getContentType().equals(ObjectID.pkcs7_signedData)) { // get the SignedData content: SignedDataStream signedData = (SignedDataStream)cis.getContent() // proceed as usual for reading the data, getting the SignerInfos and // verifying the signatures } else { throw new PKCSParsingException("Error! Expected content type SignedData!"); }However, when receiving a ContentInfo holding an explicit message where the content is not included in the SignedData object, you may want to use the the
SignedDataStream(InputStream data_is, AlgorithmID[] hashAlgorithms)
constructor for initializing a SignedDataStream object with raw content and
hash algorithms in the usual way, and subsequently decode the received
SignedData object by feeding the
decode
method
with the DER encoded SignedData object obtained from the ContentInfo by
calling the getContentInputStream
method,
e.g.:
// the raw data received by other means, supplied from an input stream: InputStream data_is = ...; // the hash algorithms (e.g. parsed from the headers of a S/MIME multipart/signed entity): AlgorithmID[] algIDs = { AlgorithmID.sha1, AlgorithmID.md5 }; // the DER encoded content info, supplied from an input stream: InputStream encoded_stream = ...; // create a SignedDataStream object from raw data and hash algorithms: SignedDataStream signed_data = new SignedDataStream(data_is, algIDs); // create a ContentInfoStream from the DER encoding: ContentInfoStream cis = new ContentInfoStream(encoded_stream); // check the content type: if (cis.getContentType().equals(ObjectID.pkcs7_signedData)) { // now decode the DER encoded SignedData obtained from the ContentInfo: signed_data.decode(cis.getContentInputStream()); } else { throw new PKCSParsingException("Error! Expected a SignedData content!"); } // proceed as usual for reading the content, getting SignerInfos and verifying signatures ...Attention! After using the
getContentInputStream
method
for getting the unparsed content an application might not further access the
corresponding ContentInfoStream object. When getting and reading the unparsed
content in the way described above, the stream holding the DER encoded
content will be read outside this class for decoding and parsing the inherent
content. It is quite obviously that in this case the content component of the
corresponding ContentInfoStream object will remain empty, unless you
explicitly set it again by using the setContent(ContentStream content)
method.
DataStream
,
DigestedDataStream
,
EncryptedDataStream
,
EnvelopedDataStream
,
SignedAndEnvelopedDataStream
,
SignedDataStream
,
ContentStream
Constructor and Description |
---|
ContentInfoStream(ContentStream content)
Creates a PKCS#7
ContentInfoStream from the given content
value. |
ContentInfoStream(java.io.InputStream is)
Creates a new ContentInfoStream where the DER encoded data is read from the
given InputStream.
|
ContentInfoStream(ObjectID contentType)
Creates an empty PKCS#7
ContentInfoStream from the given
content type. |
Modifier and Type | Method and Description |
---|---|
static ContentStream |
create(ObjectID oid)
Returns a stream-supporting instance of the specified PKCS#7 content type
implementation, defined by its ASN.1 ObjectID.
|
static ContentStream |
create(ObjectID oid,
java.io.InputStream is)
Returns a stream-supporting instance of the specified PKCS#7 content type
implementation, defined by its ASN.1 ObjectID.
|
protected void |
decode(DerInputStream is)
Reads and decodes the ContentInfo from a DerInputStream.
|
void |
destroyCriticalData()
Destroys the critical data of this object.
|
ContentStream |
getContent()
Returns the content of this PKCS#7 ContentInfoStream.
|
java.io.InputStream |
getContentInputStream()
Returns the unparsed content of this PKCS#7 ContentInfo as DER encoding.
|
ObjectID |
getContentType()
Returns the content type of this PKCS#7 ContentInfoStream.
|
boolean |
hasContent()
Returns
true if this ContentInfoStream has a content. |
static void |
register(ObjectID oid,
java.lang.Class cls)
Registers a new implementation for a ContentStream defined through the
given ObjectID.
|
void |
setContent(ContentStream content)
Sets the content of this ContentInfo.
|
ASN1Object |
toASN1Object()
Returns this PKCS#7 ContentInfoStream as ASN1Object.
|
java.lang.String |
toString()
Returns a string giving some information about this PKCS#7
ContentInfoStream.
|
java.lang.String |
toString(boolean detailed)
Returns a string giving some - if requested - detailed information about
this PKCS#7 ContentInfoStream.
|
void |
writeTo(java.io.OutputStream os)
Writes the DER encoding of this object to the given OutputStream.
|
public ContentInfoStream(ContentStream content)
ContentInfoStream
from the given content
value.
The content type object identifier internally is derived from the given
ContentStream object by using the getContentType
method.
content
- the content object as ContentStream
descendant.ContentStream.getContentType()
public ContentInfoStream(ObjectID contentType)
ContentInfoStream
from the given
content type.
Since no content is specified, it is set to null
. The content
value may be supplied by other means.
contentType
- the type of the content, as ObjectIDpublic ContentInfoStream(java.io.InputStream is) throws java.io.IOException, PKCSParsingException
decode
method for initializing the decoding procedure. The
decode
method only parses the contentType object identifier
and lets the content itself unparsed. This provides the possibility for
getting the unparsed content by means of the
getContentInputStream
method.
Alternatively you may call the getContent
method for
getting the content as ContentStream
descendant. Actually when calling getContent
the encoded
content will be decoded and parsed for its internal structure. However, it
is essential to remember that this is a stream implementation, so
using both getContent
and
getContentInputStream
would not work!is
- the InputStream holding a DER encoded PKCS#7 ContentInfo objectjava.io.IOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic static ContentStream create(ObjectID oid) throws PKCSException
oid
- the ObjectID of the extension.PKCSException
- if an error occurs when creating the PKCS#7 ContentStream
objectpublic static ContentStream create(ObjectID oid, java.io.InputStream is) throws java.io.IOException, PKCSParsingException
This method belongs to the static part of this class.
oid
- the ObjectID of the PKCs#7 contentis
- an InputStream holding a DER encoded version of the content
specified through the oidjava.io.IOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic static void register(ObjectID oid, java.lang.Class cls)
This method registers the given class as stream-supporting implementation of the supplied PKCS#7 content type. The content type has to be specified by its ObjectID. This method belongs to the static part of this class.
oid
- the object id of the PKCS#7 content type to be registeredcls
- the content stream implementing classprotected void decode(DerInputStream is) throws java.io.IOException, PKCSParsingException
DerInputStream
, internally a DerInputStream is created before parsing the
data.
Attention! This method only parses the contentType object identifier
and lets the content itself unparsed. This provides the possibility for
getting the unparsed content by means of the
getContentInputStream
method.
Alternatively you may call the getContent
method for
getting the content as ContentStream
descendant. Actually when calling getContent
the encoded
content will be decoded and parsed for its internal structure. However, it
is essential to remember that this is a stream implementation, so
using both getContent
and
getContentInputStream
would not work!is
- the InputStream holding a DER encoded PKCS#7 ContentInfoStream
objectjava.io.IOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic ASN1Object toASN1Object() throws PKCSException
PKCSException
- if an ASN.1 parsing error occurspublic void writeTo(java.io.OutputStream os) throws java.io.IOException, PKCSException
ContentInfo
structure is encoded as ASN.1 SEQUENCE using the
indefinite length encoding scheme:
30 80 ... ... 00 00
os
- the OutputStream where the encoding shall be written tojava.io.IOException
- if an I/O error occurs during writing to the OutputStreamPKCSException
- if an error occurs while encoding the objectpublic boolean hasContent()
true
if this ContentInfoStream has a content.true
if this ContentInfoStream has a contentpublic ContentStream getContent() throws java.io.IOException, PKCSParsingException
For getting the unparsed DER encoded content as, you may call the
getContentInputStream
method. This will
give you the possibility of doing the decoding and parsing by yourself.
However, since this is a stream implementation, remember that you can read
the stream only once! For that reason you never should use both
methods getContent
and getContentInputStream
!
ContentStream
descendantjava.io.IOException
- if some error occurs while reading from the stream supplying
the DER encoded contentPKCSParsingException
- if an error occurs during parsing the contentpublic java.io.InputStream getContentInputStream()
null
.
This method may be useful for parsing an explicit SignedData object that
has been wrapped into a ContentInfo. You can use the
SignedDataStream(InputStream data_is, AlgorithmID[] hashAlgorithms)
in the
normal way for initializing a SignedDataStream object with raw content and
hash algorithms, and subsequently decode the received SignedData object by
feeding the decode
method with the DER encoded SignedData object obtained from the
ContentInfo by calling this getContentInputStream
method,
e.g.:
// the raw data received by other means, supplied from an input stream: InputStream data_is = ...; // the hash algorithms (e.g. parsed from the headers of a S/MIME multipart/signed entity): AlgorithmID[] algIDs = { AlgorithmID.sha1, AlgorithmID.md5 }; // the DER encoded content info, supplied from an input stream: InputStream der_stream = ...; // create a SignedDataStream object from raw data and hash algorithms: SignedDataStream signed_data = new SignedDataStream(data_is, algIDs); // create a ContentInfoStream from the DER encoding: ContentInfoStream cis = new ContentInfoStream(der_stream); // check the content type: if (cis.getContentType().equals(ObjectID.pkcs7_signedData)) { // now decode the DER encoded SignedData obtained from the ContentInfo: signed_data.decode(cis.getContentInputStream()); } else { throw new PKCSParsingException("Error! Expected a SignedData content!"); } // proceed as usual for reading the content, getting SignerInfos and verifying signatures ...Attention! After using this method for getting the unparsed content an application might not further access the corresponding ContentInfoStream object. When getting and reading the unparsed content in the way described above, the stream holding the DER encoded content will be read outside this class for decoding and parsing the inherent content. It is quite obviously that in this case the content component of the corresponding ContentInfoStream object will remain empty, unless you explicitly set it again by using the
setContent(ContentStream content)
method.
For parsing and getting the content as
ContentStream
descendant, you may
call the getContent
method. However, since this is a
stream implementation, you never should use both methods
getContent
and getContentInputStream
!
Content
descendantpublic ObjectID getContentType()
public void setContent(ContentStream content)
The content type object identifier internally is derived from the given
ContentStream object by using the getContentType
method.
content
- the content object as ContentStream
descendant.public void destroyCriticalData()
public java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String toString(boolean detailed)
detailed
- - whether or not to give detailed information