|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--iaik.pkcs.pkcs7.DigestedDataStream
This class represents the stream supporting implementation of the PKCS#7
DigestedData
type.
Each PKCS#7 content type is associated with a specific object identifier, derived from:
pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) US(840) rsadsi(113549) pkcs(1) 7 }
The object identifier for the DigestedData
content type is
defined as:
digestedData OBJECT IDENTIFIER ::= { pkcs-7 5 }
which corresponds to the OID string "1.2.840.1.113549.1.7.5".
The PKCS#7
Cryptographic Message Standard specifies the DigestedData
content type for providing a syntax for building message digests. The
digested-data content type consists of content of any type and a message
digest of the content:
DigestedData ::= SEQUENCE { version Version, digestAlgorithm DigestAlgorithmIdentifier, contentInfo ContentInfo, digest Digest }
Digest ::= OCTET STRING
The digestAlgorithm
field specifies the digest algorithm to be
used for computing the message digest of the content given in the
contentInfo
field. The result of the digest calculation is stored
in the digest
field.
Verifying a received message digest is done by comparing it with an
independently computed message digest.
For more information consult the RSA PKCS#7 specification (section 12.Digested-data content type).
When creating a DigestedDataStream
object for the content to be
digested by using the DigestedDataStream(InputStream data_is, AlgorithmID digestAlgorithm, int mode)
constructor, additionally the transimission mode has to be specified. If the mode is
set to DigestedDataStream.IMPLICIT the raw data will be included in the
DigestedData
message to be transmitted, but it will be not included
if the mode is set to DigestedDataStream.EXPLICIT.
However, in both cases the raw data has to be supplied when creating the
DigestedDataStream
object, because it is needed for the digest
computation:
InputSrteam data_stream = ...; // the raw data supplying input stream AlgorithmID digestAlg = ...; DigestedDataStream digested_data = new DigestedDataStream(data_stream, digestAlg, DigestedDataStream.IMPLICIT);respectively
DigestedDataStream digested_data = new DigestedDataStream(data_stream, digestAlg, DigestedDataStream.EXPLICIT);In contrast to the non-stream-variant of the PKCS#7 DigestedData type (implemented by the
DigestedData
class),
where explicit and implicit mode can be handled in the same way when creating
a DigestedData object, they require a different proceeding for the stream-supporting
DigestedDataStream
class.
In this way, the steps for creating a DigestedDataStream
object and
preparing it for transmission can be summarized in the following way:
DigestedDataStream
object thereby supplying the raw data
to be digested as input stream and specifying digest algorithm and transmission mode
to be used (either DigestedDataStream.IMPLICIT or DigestedDataStream.EXPLICIT):
InputStream data_stream = ...; int mode = ...; AlgorithmID digestAlg = ...; DigestedDataStream digested_data = new DigestedDataStream(data_stream, digestAlg, mode);
if (mode == DigestedDataStream.EXPLICIT) { InputStream data_is = digested_data.getInputStream(); byte[] buf = new byte[1024]; int r; while ((r = data_is.read(buf)) > 0) { // do something useful } }When using the implicit mode, do not explicitly read data from the input stream at all! This will be done automatically during the last step when performing the encoding.
writeTo
method for BER encoding the
the DigestedDataStream object and writing it to an output stream. You optionally
may specify a particular block size for splitting the data encoding:
int blockSize = ...; digested_data.writeTo(output_stream, blockSize);respectively
digested_data.writeTo(output_stream);It is recommended only to use the
writeTo
method where a particular
block size can be specified, because it is the intended purpose of this stream-supporting
DigestedData implementation to handle large amounts of data. When no block size is
specified whole the raw data is encoded as one primitive definite octet string, which
advantageously may be done when using the non-stream supporting
DigestedData
implementation.
When a positve block size is specified for encoding the DigestedData to a stream,
the raw data is BER encoded as indefinite constructed octet string being composed
of a series of definite primitive encoded octet strings of blockSize
length,
e.g.:
0x24 0x80 0x04 0x02 0x01 0xAB 0x04 0x02 0x23 0x7F 0x04 0x01 0xCA 0x00 0x00instead of:
0x04 0x05 0x01 0xAB 0x23 0x7F 0xCAfor encoding the five data bytes
0x01 0xAB 0x23 0x7F 0xCA
.
Again, it has to be distinguished between IMPLICIT and EXPLICIT mode when using the
DigestedDataStream
implementation for parsing a received
DigestedData message. When operating in IMPLICIT mode, the raw data is included in
the received DigestedData object, and so the parsing immediately may be
performed when creating a DigestedDataStream
object from the DER encoded
DigestedData object by calling the DigestedDataStream(InputStream is)
constructor. On the other side, when
the raw data has been transmitted outside the DigestedData message (EXPLICIT mode), the
DigestedDataStream(InputStream data_is, AlgorithmID digestAlgorithm)
constructor
has to be used for initializing the new DigestedDataStream object with raw data and
hash algorithm to be used for digest computation; and the decoding has to be performed
explicitly by calling the decode
method.
The initialization is necessary for preparing the digest computation on the raw data for the
specified digest algorithm. Later, during digest verification the
digest value computaion is finished and the result is compared against the hash value
sent within the final digest
field.
The individual steps necessary for parsing a received DigestedData message and verifying the
digest may be summarized as follows:
DigestedDataStream(InputStream is)
constructor for creating a DigestedDataStream object and implicitly performing the
decoding:
DigestedDataStream digestedData = new DigestedDataStream(encoded_stream);On the other hand, if the BER encoding represents an explicit DigestedData object, use the
DigestedDataStream(InputStream data_is, AlgorithmID digestAlgorithm)
constructor for initializing a new DigestedDataStream object with raw data and
digest algorithm for hash computation (assuming that the hash algorithm is SHA):
AlgorithmID algID = AlgorithmID.sha1; DigestedDataStream digestedData = new DigestedDataStream(data_is, algID);
InputStream dataIs = digestedDdata.getInputStream(); byte[] buf = new byte[1024]; int r; while ((r = dataIs.read(buf)) > 0) { // do something useful }
decode
method:
digestedData.decode(encoded_stream);
verify
method for comparing the
computed digest against the value sent in the digest
field:
if (digestedData.verify()) System.out.println("Hash o.k!"); else System.out.println("hash verification failed!");
Field Summary | |
protected int |
block_size
The block size for block oriented stream encoding. |
protected ObjectID |
content_type
The content type. |
static int |
EXPLICIT
Denotes a mode where the data to be digested is not included. |
static int |
IMPLICIT
Denotes a mode where the data to be digested is included. |
protected InputStream |
input_stream
An InputStream holding the data. |
protected int |
mode
The mode specifying if the data shall be included (IMPLICIT), or if is not included (EXPLICIT). |
protected DerInputStream |
this_object
An InputStream from which a DER encoded DigestedData object is read. |
Constructor Summary | |
protected |
DigestedDataStream()
Default constructor for dynamic object creation in ContentInfo. |
|
DigestedDataStream(InputStream is)
Creates a PKCS#7 DigestedData from an InputStream. |
|
DigestedDataStream(InputStream data_is,
AlgorithmID digestAlgorithm)
Creates a new DigestedDataStream from an InputStream holding the content that has been transmitted by other means, and the hash algorithm to be used for digesting. |
|
DigestedDataStream(InputStream data_is,
AlgorithmID digestAlgorithm,
int mode)
Creates a new DigestedDataStream object from given content and
and digest algorithm.
|
|
DigestedDataStream(ObjectID contentType,
AlgorithmID digestAlgorithm,
byte[] digest)
Creates a new DigestedDataStream object without content.
|
Method Summary | |
void |
decode(InputStream is)
Reads and decodes the DigestedDataStream from a DerInputStream. |
void |
encodeCalled(ASN1Object o,
int id)
This method implements the EncodeListener interface. |
int |
getBlockSize()
Gets the block size defining the length of each definite primitive encoded octet string component. |
ObjectID |
getContentType()
Returns the content type this class implements. |
byte[] |
getDigest()
Returns the message-digest computed on the content value. |
AlgorithmID |
getDigestAlgorithm()
Returns the message-digest algorithm used for computing the digest. |
InputStream |
getInputStream()
Returns an input stream with the raw data. |
int |
getVersion()
Returns the version syntax number. |
void |
notifyEOF()
This method implements the EOFListener interface for performing the final decoding. |
void |
setBlockSize(int blockSize)
Sets the block size for defining the length of each definite primitive encoded octet string component. |
void |
setDigest(byte[] digest)
Sets the message-digest value. |
ASN1Object |
toASN1Object()
Returns this DigestedDataStream as ASN1Object. |
protected ASN1Object |
toASN1Object(int blockSize)
Returns this DigestedData as ASN1Object where a constructed OCTET STRING is used for encoding the content. |
String |
toString()
Returns a string giving some information about this DigestedData object. |
String |
toString(boolean detailed)
Returns a string giving some - if requested - detailed information about this DigestedData object. |
boolean |
verify()
Verifies the digest. |
void |
writeTo(OutputStream os)
Writes this DigestedData DER encoded to the supplied output stream. |
void |
writeTo(OutputStream os,
int blockSize)
Writes this object to the supplied output stream where a constructed OCTET STRING is used for encoding the content. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
public static final int IMPLICIT
public static final int EXPLICIT
protected ObjectID content_type
protected DerInputStream this_object
protected int block_size
protected InputStream input_stream
protected int mode
Constructor Detail |
protected DigestedDataStream()
public DigestedDataStream(InputStream data_is, AlgorithmID digestAlgorithm, int mode) throws PKCSException
DigestedDataStream
object from given content and
and digest algorithm.
The data to be digested is supplied as input stream. The mode
parameter
specifies whether to include the data (mode = DigestedDataStream.IMPLICIT) or
not include it (mode = DigestedDataStream.EXPLICIT). The content type of the
inherent ContentInfo automatically is set to PKCS#7 Data.data_is
- the data to be digested supplied from an input streamdigestAlgorithm
- the message-digest algorithm to be used for creating the digestmode
- either DigestedDataStream.IMPLICIT for including the data, or
DigestedDataStream.EXPLICIT for not including itPKCSException
- if the supplied paramteres to not satisfy the requirements ot there is no
implementation for the requested hash algorithmpublic DigestedDataStream(ObjectID contentType, AlgorithmID digestAlgorithm, byte[] digest)
DigestedDataStream
object without content.
For instance:
byte[] message = "Test data to be digested".getBytes(); MessageDigest md = MessageDigest.getInstance("SHA"); md.update(message); byte[] digest = md.digest(); DigestedDataStream digested_data = new DigestedDataStream(ObjectID.pkcs7_data, AlgorithmID.sha, digest);
The content must be supplied by other means.
contentType
- the content type of the digested datadigestAlgorithm
- the message-digest algorithm (and any associated parameters)
used for creating the digestdigest
- the already calculated digest valuepublic DigestedDataStream(InputStream is) throws IOException, PKCSParsingException
DigestedDataStream(InputStream data_is, AlgorithmID hashAlgorithm)
constructor, and perform the decoding explicitly by calling the
decode
method.
A sender shall use the DigestedDataStream(InputStream data_is, AlgorithmID digestAlgorithm, int mode)
constructor for supplying the content to be digested when creating a
DigestedDataStream
object.
is
- the InputStream holding the DER encoded PKCS#7 DigestedData objectIOException
- if an error occurs when reasding from the streamPKCSParsingException
- if the object can not be parsedpublic DigestedDataStream(InputStream data_is, AlgorithmID digestAlgorithm) throws IOException
Do not use this constructor for supplying the content value
to be digested. This constructor may be used by the recipient for initializing
the digest computation for an already existing explicit DigestedDataStream message
where the raw data is not included. The initialization is done by wrapping a digest
stream around the supplied raw data stream for the specified hash algorithm.
Subsequently the hash value will be updated when reading the stream thereby
piping the data through the digest stream.
Later, during digest verification the digest computaion is finished and the result
is compared with the hash values derived parsed from the encoding.
For an explicit message the actual decoding has to be performed by calling
the decode
method just after reading the
data:
// initialize for hash computation: DigestedDataStream digestedData = new DigestedDataStream(data_is, hashAlgorithm); //read the stream thereby updating the hash values: InputStream dataIs = digestedData.getInputStream(); byte[] buf = new byte[1024]; int r; while ((r = dataIs.read(buf)) > 0) { // do something useful } // explicitly perform the decoding digestedData.decode(encoded_stream);
A sender shall use the DigestedDataStream(InputStream data_is, AlgorithmID digestAlgorithm, int mode)
constructor for supplying the content to be digested when creating a
DigestedDataStream
object.
For decoding an implicit DigestedDataStream message, use the
DigestedDataStream(InputStream is)
constructor.
data_is
- the InputStream supplying the raw data which has been transmitted by other meanshashAlgorithm
- the hash algorithm used by for digesting the content dataIOException
- if there is no implementation for the specified hash algorithmMethod Detail |
public void decode(InputStream is) throws IOException, PKCSParsingException
DerInputStream
,
internally a DerInputStream is created before parsing the data.decode
in interface ContentStream
is
- the InputStream holding a DER encoded PKCS#7 DigestedData objectIOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic ObjectID getContentType()
getContentType
in interface ContentStream
ObjectID.pkcs7_digestedData
public int getVersion()
public AlgorithmID getDigestAlgorithm()
public byte[] getDigest()
public void setDigest(byte[] digest)
digest
- the digest value as byte arraypublic void setBlockSize(int blockSize)
blockSize
is smaller or equal to zero the
whole data is encoded as definite primitive octet string.
This method may be used for enforcing block encoding when wrapping the
DigestedData into a ContentInfo.setBlockSize
in interface ContentStream
blockSize
- for defining the encoding scheme and setting the octet
string component length, if positiveOCTET_STRING
public int getBlockSize()
blockSize
is smaller or equal to zero the
whole data is encoded as definite primitive octet string.
This method may be used for enforcing block encoding when wrapping the
EncryptedData into a ContentInfo.getBlockSize
in interface ContentStream
OCTET_STRING
public InputStream getInputStream()
public ASN1Object toASN1Object() throws PKCSException
toASN1Object
in interface ContentStream
PKCSException
- if the ASN1Object could not be createdprotected ASN1Object toASN1Object(int blockSize) throws PKCSException
blockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positivePKCSException
- if the ASN1Object could not be createdpublic void encodeCalled(ASN1Object o, int id) throws CodingException
EncodeListener
utility. The toASN1Object()
method of this DigestedDataStream
class instantiates an empty OCTET_STRING for the digest
field, and registers itself as EncodeListener for this empty OCTET_STRING.
Now, during the encoding process, when the content stream entirely has
been read, this encodeCalled
method is called for
performing digest computation. The supplied ASN1Object
is the empty OCTET_STRING to be "filled" with the result of the
digest-computation-encryption.encodeCalled
in interface EncodeListener
o
- an OCTET_STRING for being supplied with the message digest valueid
- the id identifying the particular octet string to be processedCodingException
- if an error occurs when computing/encrypting
the message digestpublic void notifyEOF() throws IOException
iaik.utils.NotifyEOFInputStream
is wrapped around this raw data stream
for indicating that the parsing procedure is to be notified when the stream actually
has been read. At that point, the programm exceuting automatically jumps to the
actual notifyEOF
method for finishing the decoding by parsing the
final digest field.
iaik.utils.EOFListener
interface.notifyEOF
in interface EOFListener
IOException
- if an error occurs while parsing the streamEOFListener
,
NotifyEOFInputStream
public boolean verify() throws PKCSException
PKCSException
- if an error occurs during verification processpublic void writeTo(OutputStream os) throws IOException
os
- the output stream to which this DigestedData shall be writtenIOException
- if an IOException occurs while writing to the streampublic void writeTo(OutputStream os, int blockSize) throws IOException
0x24 0x80 0x04 <blocksize> <data> 0x04 <blocksize> <data> 0x04 <blocksize> <data> ... 0x00 0x00If the block size is not positive, whole the inherent data is encoded as one single primitive definite octet string:
0x04 <length> <data>
os
- the output stream to which this DigestedData shall be writtenblockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positiveIOException
- if an error occurs during writing the objectpublic String toString()
DigestedData
object.toString
in class Object
public String toString(boolean detailed)
DigestedData
object.toString
in interface ContentStream
detailed
- - whether or not to give detailed information
|
This Javadoc may contain text parts from Internet Standard specifications (RFC 2459, 3280, 3039, 2560, 1521, 821, 822, 2253, 1319, 1321, ,2630, 2631, 2268, 3058, 2984, 2104, 2144, 2040, 2311, 2279, see copyright note) and RSA Data Security Public-Key Cryptography Standards (PKCS#1,3,5,7,8,9,10,12, see copyright note). | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |