public class EnvelopedDataStream extends java.lang.Object implements ContentStream, EOFListener
EnvelopedData.
Each CMS 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 EnvelopedData content type is
defined as:
envelopedData OBJECT IDENTIFIER ::= { pkcs-7 3 }
which corresponds to the OID string "1.2.840.1.113549.1.7.3".
The CMS
Cryptographic Message Syntax (RFC 2630) specifies the EnvelopedData
content type for providing a syntax for building digital envelopes. Content
of any type may be enveloped for any number of recipients in parallel. For
each recipient, a commonly at random generated content-encryption key is
encrypted with the particular recipient´s key and - together with
recipient-specific information - collected into a RecipientInfo
value. The content is encrypted with the content-encryption key giving a
EncryptedContent value, which - in combination with a
recipient-specific encrypted content-encryption key - forms the digital
envelope for each particular recipient. All RecipientInfo
values are collected together with the encrypted content into an
EnvelopedData value to be sent to each intended recipient.
This class implements the EnvelopedData structure resulting from
the last step described above. The EnvelopedData type is defined
as ASN.1 SEQUENCE type containing the following components (see RFC 2630:
EnvelopedData ::= SEQUENCE {
version CMSVersion,
originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
recipientInfos RecipientInfos,
encryptedContentInfo EncryptedContentInfo
unprotectedAttrs [1] IMPLICIT UnptotectedAttributes OPTIONAL }
OriginatorInfo ::= SEQUENCE {
certs [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT CertificateRevocationLists OPTIONAL }
RecipientInfos ::= SET OF RecipientInfo
EncryptedContentInfo ::= SEQUENCE {
contentType ContentType,
contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
EncryptedContent ::= OCTET STRING
UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute
The recipientInfos field is a non-empty collection of
per-recipient information. The encryptedContentInfo field
specifies the type of the content being enveloped, the content-encryption
algorithm (the same for all recipients) used for encrypting the content,
and the result of the content encryption. If the encrypted content value
is not present in the encryptedContent field, it has to be
supplied by other means.
CMS provides three alternatives for encrypting the content depending
on the key management algorithm used to protect the content encryption
key for a specific recipient:
KeyTransRecipientInfo for the public key of the recipient´s
certificate, identified by IssuerAndSerialNumber. CMS recommends to use RSA for encrypting
the content encryption key.
KeyAgreeRecipientInfo may transfer the encrypted content
encryption key to one or more recipient using the same key
agreement algorithm and domain parameters for that algorithm.
CMS recommends to use ephemeral-static DH or ECDH with an
ephemeral sender key
KEKRecipientInfo using a CMS key wrap algorithm like
Triple-DES key wrap or RC2 key wrap.
PasswordRecipientInfo using a CMS algorithm like
Triple-DES key wrap or RC2 key wrap.
originatorInfo field may be used to include certificate/CRL
information about the originator if required by the key management protocol.
unprotectedAttrs optionally may provide some attributes that are
not encrypted.
A recipient, when receiving the EnvelopedData message,
decrypts the corresponding encrypted content-encryption key with his/her
key according the right key management protocol for subsequently decrypting the
encrypted content using the content-encryption key just recovered. The recipient's
key is referenced by proper KeyIdentifier included
in the corresponding RecipientInfo object.
See RFC 2630 for more information.
When creating a new EnvelopedDataStream object for the data to be enveloped
the symmetric algorithm has to be specified to be used for content-encryption. After setting
the recipients, the EnvelopedDataStream object may be encoded and written to an output stream
by using a proper writeTo method, e.g.:
EnvelopedDataStream(InputStream is, AlgorithmID contentEA) constructor. Calling
this constructor internally will generate the temporary content-encryption key for the
specified content-encryption algorithm. If using a content-encryption algorithm
allowing keys of different size, you may specify the key length by using the
EnvelopedDataStream(InputStream is, AlgorithmID contentEA, int keyLength)
constructor.
//the data to be enveloped supplied from an input stream:
InputStream dataStream = ...;
//use TripleDES in CBC mode for encrypting the content
EnvelopedDataStream enveloped_data = new EnvelopedDataStream(dataStream, AlgorithmID.des_EDE3_CBC);
RecipientInfo object of requested type (KeyTransRecipientInfo, KeyAgreeRecipientInfo,
KEKRecipientInfo or
PasswordRecipientInfo), and add all RecipientInfos
to the EnvelopedDataStream object by calling the setRecipientInfos method, e.g.
(assuming to use KeyTransRecipientInfos for two recipients with corresponding
certificates cert1 and cert2):
RecipientInfo[] recipients = new RecipientInfo[2];
recipients[0] = new KeyTransRecipientInfo(cert1, AlgorithmID.rsaEncryption);
recipients[1] = new KeyTransRecipientInfo(cert2, AlgorithmID.rsaEncryption);
enveloped_data.setRecipientInfos(recipients);
writeTo method for BER encoding the
EnvelopedData object and writing it to an output stream. You optionally may specify
a particular block size for splitting the encoding of encrypted content. This step
also will perform the encryption of the symmetric content-encryption key for each
participated recipient.
int blockSize = ...;
OutputStream encoded_stream = ...;
enveloped_data.writeTo(encoded_stream, blockSize);
respectively
enveloped_data.writeTo(encoded_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
EnvelopedData implementation to handle large amounts of data. When no block size is
specified whole the encrypted content is encoded as primitive definite octet string, which
advantageously may be done when using the non-stream supporting
EnvelopedData implementation.
When a positive block size is specified for encoding the EnvelopedData to a stream,
the encrypted content is BER encoded as indefinite constructed octet string being composed
of a series of definite primitive encoded octet strings of blockSize length:
0x24 0x80
0x04 <blocksize> <first encrypted content block>
0x04 <blocksize> <second encrypted content block>
0x04 <blocksize> <third encrypted content block>
...
0x00 0x00
instead of:
0x04 <length> <encrypted content>
The indefinite constructed encoding scheme also may be preferable when intending to be
compatible to the encoding practice of some particular application (for instance some
versions of Netscape Navigator).
EnvelopedDataStream(InputStream is)
constructor for parsing the internal structure. Before reading the recovered content by
means of the getInputStream method, the cipher has to be
initialized for decryption with the particular recipient´s key by calling one of the
following setupCipher methods:
setupCipher(Key recipientKey, int recipientInfoIndex):
This method can be used for decrypting the encrypted content-encryption key for
a RecipientInfo of any type; however, you must know the right index into the
recipientInfo field. The recovered content-encryption key is used
for setting up the cipher to decrypt the encrypted content.
setupCipher(Key recipientKey,
KeyIdentifier recipientKeyIdentifier): This method can be used for decrypting the
encrypted content-encryption key for a RecipientInfo of any type; the recipient is
identified by its RecipientKeyIdentifier.
The recovered content-encryption key is used for setting up the cipher to decrypt
the encrypted content.
setupCipher(Key recipientKey,
X509Certificate recipientCertificate): This method only can be used for decrypting
the encrypted content-encryption key for a RecipientInfo of type KeyTransRecipientInfo or KeyAgreeRecipientInfo; the recipient is
identified by its public key certificate. The recovered content-encryption key is used
for setting up the cipher to decrypt the encrypted content.
setupCipher(Key): In contrast to the three setupCipher
above you have to supply the already decrypted content-encryption key when setting
up the cipher for content encryption using this setupCipher method.
KeyTransRecipientInfo,
we can use any of the setupCipher methods to setup the cipher for
decrypting the encrypted content-encryption key and the encrypted content:
EnvelopedDataStream enveloped_data = new EnvelopedDataStream(encoded_stream);
EncryptedContentInfoStream eci = (EncryptedContentInfoStream)enveloped_data.getEncryptedContentInfo();
System.out.println("Content type: "+eci.getContentType().getName());
System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
RecipientInfo[] recipients = enveloped_data.getRecipientInfos();
System.out.println("Included RecipientInfos:");
for (int i=0; i < recipients.length; i++) {
System.out.print("Recipient "+(i+1)+":");
System.out.println(recipients[i]);
}
// the private key of recipient 1:
Key privateKey = ...;
//setup cipher for recipient 1:
int recipientInfoIndex = 0;
enveloped_data.setupCipher(privateKey, recipientInfoIndex);
Unlike the non-stream supporting EnvelopedData class where the encrypted-content decryption
already is performed inside the setupCipher method, the cipher
will be only initialized for decryption in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream method. So don´t call
getInputStream before setting up the cipher!
InputStream data_is = enveloped_data.getInputStream();
byte[] buf = new byte[1024];
int r;
while ((r = data_is.read(buf)) > 0) {
// do something useful
}
| Modifier and Type | Field and Description |
|---|---|
protected int |
blockSize_
The block size for block oriented stream encoding.
|
protected EncryptedContentInfoStream |
encryptedContentInfo_
The EncryptedContentInfo for the encrypted content.
|
protected DerInputStream |
m_envelopedData
An
InputStream holding the enveloped data. |
protected OriginatorInfo |
originatorInfo_
The optional OriginatorInfo.
|
protected java.util.Vector<RecipientInfo> |
recipientInfos_
Repository for the RecipientInfos.
|
protected javax.crypto.SecretKey |
symmetricKey_
The secret content encryption key.
|
protected Attribute[] |
unprotectedAttrs_
Optional unprotected attributes.
|
protected int |
version_
The version number; default 0.
|
| Modifier | Constructor and Description |
|---|---|
protected |
EnvelopedDataStream()
Default constructor for dynamic object creation in ContentInfoStream.
|
|
EnvelopedDataStream(java.io.InputStream is)
Creates a new EnvelopedDataStream where the BER encoded data
is read from the given InputStream.
|
|
EnvelopedDataStream(java.io.InputStream is,
AlgorithmID contentEA)
Creates a new EnvelopedDataStream object where the content to be enveloped
is read from the supplied InputStream.
|
|
EnvelopedDataStream(java.io.InputStream is,
AlgorithmID contentEA,
int keyLength)
Creates a new EnvelopedDataStream object where the content to be enveloped
is read from the supplied InputStream.
|
|
EnvelopedDataStream(ObjectID contentType,
java.io.InputStream is,
AlgorithmID contentEA)
Creates a new EnvelopedDataStream object where the content to be enveloped
is read from the supplied InputStream.
|
|
EnvelopedDataStream(ObjectID contentType,
java.io.InputStream is,
AlgorithmID contentEA,
int keyLength)
Creates a new EnvelopedDataStream object where the content to be enveloped
is read from the supplied InputStream.
|
|
EnvelopedDataStream(RecipientInfo[] recipients,
EncryptedContentInfoStream encryptedCI)
Constructs an EnvelopedDataStream object with an already
created EncryptedContentInfoStream.
|
| Modifier and Type | Method and Description |
|---|---|
void |
addRecipientInfo(RecipientInfo recipient)
Adds one recipient to the list of recipient infos.
|
void |
decode(java.io.InputStream is)
Reads and decodes an BER encoded EnvelopedData from a the given input stream.
|
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.
|
EncryptedContentInfoStream |
getEncryptedContentInfo()
Returns the EncryptedContentInfo included in this
EnvelopedDataStream object. |
java.io.InputStream |
getInputStream()
Returns an InputStream from where the decrypted data can be read.
|
OriginatorInfo |
getOriginatorInfo()
Gets the OriginatorInfo, if included.
|
RecipientInfo |
getRecipientInfo(KeyIdentifier recipientIdentifier)
Returns the RecipientInfo belonging to the recipient identified by the
given recipient identifier.
|
RecipientInfo |
getRecipientInfo(X509Certificate recipientCertificate)
Returns the recipient info matching to the supplied recipient certificate.
|
RecipientInfo[] |
getRecipientInfos()
Returns all the recipient infos included in this
EnvelopedData object. |
Attribute |
getUnprotectedAttribute(ObjectID oid)
Returns the first unprotected attribute matching to the given ObjectID, if
included in this EnvelopedData object.
|
Attribute[] |
getUnprotectedAttributes()
Gets the unprotected attributes included in this EnvelopedData.
|
int |
getVersion()
Returns the syntax version number.
|
void |
notifyEOF()
This method implements the EOFListener interface to preform the final stage
of decoding, once the 'encryptedContentInfo' has been completely decoded.
|
void |
setBlockSize(int blockSize)
Sets the block size for defining the length of each definite primitive
encoded octet string component.
|
void |
setOriginatorInfo(OriginatorInfo originatorInfo)
Sets the optional OriginatorInfo.
|
void |
setRecipientInfos(RecipientInfo[] recipients)
Sets the recipient infos.
|
void |
setUnprotectedAttributes(Attribute[] attributes)
Sets a set of (unprotected) attributes.
|
void |
setupCipher(java.security.Key key)
Uses the given symmetric key to setup the cipher for decrypting the content.
|
void |
setupCipher(java.security.Key recipientKey,
int recipientInfoIndex)
Uses the specified key for decrypting the content-encryption key to setup the
cipher for decrypting the encrypted content of this
EnvelopedDataStream
object for the requesting recipient, specified by its recipientInfoIndex. |
void |
setupCipher(java.security.Key recipientKey,
KeyIdentifier recipientIdentifier)
Uses the specified key for decrypting the content-encryption key to setup the
cipher for decrypting the encrypted content of this
EnvelopedDataStream
object for the requesting recipient, specified by the given recipient identifier. |
void |
setupCipher(java.security.Key recipientKey,
X509Certificate recipientCertificate)
Uses the specified key for decrypting the content-encryption key to setup the
cipher for decrypting the encrypted content of this
EnvelopedDataStream
object for the requesting recipient, specified by the given recipient certificate. |
void |
setupCipher(SecureStringBuffer password,
int recipientInfoIndex)
Uses the specified password to derive a key for decrypting the content-encryption key to setup the
cipher for decrypting the encrypted content of this
EnvelopedDataStream
object for the requesting recipient, specified by its recipientInfoIndex. |
void |
setupCipher(SecureStringBuffer password,
RecipientInfo recipient)
Uses the specified password to derive a key for decrypting the content-encryption key to setup the
cipher for decrypting the encrypted content of this
EnvelopedDataStream
object for the requesting recipient, specified by its recipientInfoIndex. |
ASN1Object |
toASN1Object()
Returns this EnvelopedDataStream as ASN1Object.
|
protected ASN1Object |
toASN1Object(int blockSize)
Returns this EnvelopedData as ASN1Object.
|
java.lang.String |
toString()
Returns a string giving some information about this
EnvelopedData object. |
java.lang.String |
toString(boolean detailed)
Returns a string giving some - if requested - detailed information
about this
EnvelopedData object. |
void |
writeTo(java.io.OutputStream os)
BER encoded this EnvelopedData and writes the encoding to the supplied output stream.
|
void |
writeTo(java.io.OutputStream os,
int blockSize)
Writes the BER encoding of this EnvelopedData to the supplied output stream
where a constructed OCTET STRING may be used for encoding the content.
|
protected int version_
protected OriginatorInfo originatorInfo_
protected java.util.Vector<RecipientInfo> recipientInfos_
protected EncryptedContentInfoStream encryptedContentInfo_
protected javax.crypto.SecretKey symmetricKey_
protected int blockSize_
protected Attribute[] unprotectedAttrs_
protected DerInputStream m_envelopedData
InputStream holding the enveloped data.protected EnvelopedDataStream()
public EnvelopedDataStream(java.io.InputStream is,
AlgorithmID contentEA)
throws java.security.NoSuchAlgorithmException
The content type is set to CMS Data.
When using this constructor, automatically a temporary symmetric key for content
encryption is generated. If using a content-encryption algorithm allowing keys
of different size, you may specify the key length by using the EnvelopedDataStream(InputStream is, AlgorithmID contentEA, int keyLength)
constructor.
Note that the supplied contentEA AlgorithmID internally is cloned.
is - the InputStream supplying the data to be envelopedcontentEA - the content encryption algorithm for encrypting the contentjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic EnvelopedDataStream(ObjectID contentType, java.io.InputStream is, AlgorithmID contentEA) throws java.security.NoSuchAlgorithmException
When using this constructor, automatically a temporary symmetric key for content
encryption is generated. If using a content-encryption algorithm allowing keys
of different size, you may specify the key length by using the EnvelopedDataStream(ObjectID contentType, InputStream is, AlgorithmID contentEA,
int keyLength) constructor.
Note that the supplied contentEA AlgorithmID internally is cloned.
contentType - the content type of the content to be envelopedis - the InputStream containing the data to envelopecontentEA - the content encryption algorithm for encrypting the contentjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic EnvelopedDataStream(java.io.InputStream is,
AlgorithmID contentEA,
int keyLength)
throws java.security.NoSuchAlgorithmException
When using this constructor, automatically a symmetric key for content
encryption is generated. If the specified content encryption algorithm supports
variable key lengths, a particular key length may be set by means of the
keyLength parameter.
If no length is specified, the defined default key length will be used. If the
algorithm only works with keys of fixed-size length, the keyLength parameter
may be set to -1 or the EnvelopedDataStream(InputStream is, AlgorithmID contentEA) constructor may be used.
Note that the supplied contentEA AlgorithmID internally is cloned.
is - the InputStream containing the data to envelopecontentEA - the content encryption algorithm for encrypting the contentkeyLength - the key length that may be set when using a content
encryption algorithm that supports variable key lengthsjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic EnvelopedDataStream(ObjectID contentType, java.io.InputStream is, AlgorithmID contentEA, int keyLength) throws java.security.NoSuchAlgorithmException
When using this constructor, automatically a symmetric key for content
encryption is generated.
If the specified content encryption algorithm supports variable key lengths, a
particular key length may be set by means of the keyLength parameter.
If no length is specified, the defined default key length will be used. If the
algorithm only works with keys of fixed-size length, the keyLength parameter
may be set to -1 or the EnvelopedDataStream(ObjectID contentType, InputStream is, AlgorithmID contentEA)
constructor may be used.
Note that the supplied contentEA AlgorithmID internally is cloned.
contentType - the content type of the content to be envelopedis - the InputStream containing the data to envelopecontentEA - the content encryption algorithm for encrypting the contentkeyLength - the key length that may be set when using a content
encryption algorithm that supports variable key lengthsjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic EnvelopedDataStream(RecipientInfo[] recipients, EncryptedContentInfoStream encryptedCI)
The given array of RecipientInfo specifies a collection of
per-recipient information, and the given EncryptedContentInfoStream
supplies the already encrypted content.
recipients - information about the recipientsencryptedCI - the encrypted content infopublic EnvelopedDataStream(java.io.InputStream is)
throws CMSParsingException,
java.io.IOException
is - the InputStream supplying a BER encoded CMS EnvelopedData objectjava.io.IOException - if an I/O error occurs during reading from the InputStreamCMSParsingException - if an error occurs while parsing the objectpublic void decode(java.io.InputStream is)
throws java.io.IOException,
CMSParsingException
decode in interface ContentStreamis - the InputStream holding a BER encoded EnvelopedData objectjava.io.IOException - if an I/O error occurs during reading from the InputStreamCMSParsingException - if an error occurs while parsing the objectpublic ObjectID getContentType()
Use getEncryptedContentInfo().getContentType() for getting the
type the encrypted content represents.
getContentType in interface ContentStreamObjectID.cms_envelopedDatapublic void setOriginatorInfo(OriginatorInfo originatorInfo)
The originatorInfo may be set for including certificates and/or certificate revocation lists for the originator if required by the key management algorithm used.
originatorInfo - the OriginatorInfo to be setpublic void setRecipientInfos(RecipientInfo[] recipients)
Any RecipientInfo added supplies
recipient-specific information used for identifying the key of
the recipient to be used for en/decrypting the content.
recipients - a collection of per-recipient informationRecipientInfo,
KeyTransRecipientInfo,
KeyAgreeRecipientInfo,
KEKRecipientInfopublic void addRecipientInfo(RecipientInfo recipient)
Any RecipientInfo added supplies
recipient-specific information used for identifying the key of
the recipient to be used for en/decrypting the content.
recipient - the RecipientInfo to be addedRecipientInfo,
KeyTransRecipientInfo,
KeyAgreeRecipientInfo,
KEKRecipientInfo,
PasswordRecipientInfopublic void setUnprotectedAttributes(Attribute[] attributes)
attributes - the unprotected attributes to be setpublic void setBlockSize(int blockSize)
blockSize is smaller or equal to zero the
whole encrypted data is encoded as definite primitive octet string.setBlockSize in interface ContentStreamblockSize - for defining the encoding scheme and setting the octet
string component length, if positivepublic int getBlockSize()
blockSize is smaller or equal to zero the
whole data is encoded as definite primitive octet string.getBlockSize in interface ContentStreampublic void setupCipher(java.security.Key recipientKey,
int recipientInfoIndex)
throws CMSException,
java.security.NoSuchAlgorithmException,
java.security.InvalidKeyException
EnvelopedDataStream
object for the requesting recipient, specified by its recipientInfoIndex.
This method first uses the given key for decrypting the encrypted
temporary symmetric key obtained from the corresponding RecipientInfo
structure, and subsequently uses this key to initialize a CipherInputStream for
decrypting the inherent encrypted content.
Unlike the non-stream supporting EnvelopedData class where the encrypted-content decryption
already is performed inside the setupCipher method, the cipher
will be only initialized for decrypting in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream method. So don´t call
getInputStream before setting up the cipher!
recipientInfos
field when using this method for setting up the cipher for decryption. You may
search for the index by using one of the getRecipientInfo methods
thereby identifying the recipient by its keyIdentifier or -- if suitable for the key management algorithm used -- certificate.
However, when having some recipient using a key agreement protocol the corresponding
RecipientInfo is of type KeyAgreeRecipientInfo
which may hold encrypted content-encryption keys for more than only one recipients
using the same key agreement algorithm with same domain parameters. Since this
setupCipher method only can get the KeyAgreeRecipientInfo with the given
index (but not search for the right recipient in the KeyAgreeRecipientInfo), it
will step through any recipient included in the KeyAgreeRecipientInfo trying to
decrypt the encrypted content-encryption key with the supplied key. This may give
some overhead so it might be appropriate to use another setupCipher method
allowing to immediately identify the particular recipient in mind by its
#setupCipher(Key, KeyIdentifier) keyIdentifier} or certificate.
recipientKey - the key of the recipient to be used for decrypting
the encrypted content-encryption key.recipientInfoIndex - the index into the recipientInfos fieldCMSException - if there occurs an error while decrypting the content-encryption key
or setting up the cipher for decrypting the contentjava.security.NoSuchAlgorithmException - if there is no implementation of the content-encryption algorithmjava.security.InvalidKeyException - if the specified private key is not validpublic void setupCipher(SecureStringBuffer password, int recipientInfoIndex) throws java.lang.Exception
EnvelopedDataStream
object for the requesting recipient, specified by its recipientInfoIndex.
This method first uses the given password to derive a key for decrypting the encrypted
temporary symmetric key obtained from the corresponding RecipientInfo
structure, and subsequently uses this key to initialize a CipherInputStream for
decrypting the inherent encrypted content.
Unlike the non-stream supporting EnvelopedData class where the encrypted-content decryption
already is performed inside the setupCipher method, the cipher
will be only initialized for decrypting in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream method. So don´t call
getInputStream before setting up the cipher!
recipientInfos
field when using this method for setting up the cipher for decryption. You may
search for the index by using one of the getRecipientInfo methods
thereby identifying the recipient by its isPasswordRequired. You can also invoke setupCipher
password - the password to use to derive the key to be used for decrypting
the encrypted content-encryption key.recipientInfoIndex - the index into the recipientInfos fieldjava.lang.Exceptionpublic void setupCipher(SecureStringBuffer password, RecipientInfo recipient) throws java.lang.Exception
EnvelopedDataStream
object for the requesting recipient, specified by its recipientInfoIndex.
This method first uses the given password to derive a key for decrypting the encrypted
temporary symmetric key obtained from the corresponding RecipientInfo
structure, and subsequently uses this key to initialize a CipherInputStream for
decrypting the inherent encrypted content.
Unlike the non-stream supporting EnvelopedData class where the encrypted-content decryption
already is performed inside the setupCipher method, the cipher
will be only initialized for decrypting in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream method. So don´t call
getInputStream before setting up the cipher!
password - the password to use to derive the key to be used for decrypting
the encrypted content-encryption key.recipient - the Password Recipient infojava.lang.Exceptionpublic void setupCipher(java.security.Key recipientKey,
KeyIdentifier recipientIdentifier)
throws CMSException,
java.security.NoSuchAlgorithmException,
java.security.InvalidKeyException
EnvelopedDataStream
object for the requesting recipient, specified by the given recipient identifier.
This method first uses the given key for decrypting the encrypted
temporary symmetric key obtained from the corresponding RecipientInfo
structure, and subsequently uses this key to initialize a CipherInputStream for
decrypting the inherent encrypted content.
Unlike the non-stream supporting EnvelopedData class where the encrypted-content decryption
already is performed inside the setupCipher method, the cipher
will be only initialized for decrypting in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream method. So don´t call
getInputStream before setting up the cipher!
This setupCipher can be used to setup the cipher for decryption for
any type of RecipientInfo. The supplied recipient identifier will be used for
searching for the right RecipientInfo in the recipientInfos field.
recipientKey - the key of the recipient to be used for decrypting
the encrypted content-encryption key.recipientIdentifier - specifies which RecipientInfo the given key belongs toCMSException - if there occurs an error while decrypting the content-encryption key
or setting up the cipher for decrypting the content, or no RecipientInfo
for the requested recipient is includedjava.security.NoSuchAlgorithmException - if there is no implementation of the content-encryption algorithmjava.security.InvalidKeyException - if the specified private key is not validpublic void setupCipher(java.security.Key recipientKey,
X509Certificate recipientCertificate)
throws CMSException,
java.security.NoSuchAlgorithmException,
java.security.InvalidKeyException
EnvelopedDataStream
object for the requesting recipient, specified by the given recipient certificate.
This method first uses the given key for decrypting the encrypted
temporary symmetric key obtained from the corresponding RecipientInfo
structure, and subsequently uses this key to initialize a CipherInputStream for
decrypting the inherent encrypted content.
Unlike the non-stream supporting EnvelopedData class where the encrypted-content decryption
already is performed inside the setupCipher method, the cipher
will be only initialized for decrypting in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream method. So don´t call
getInputStream before setting up the cipher!
Note that this method only can be used for decrypting the encrypted content
if the recipient in mind has a RecipientInfo of type KeyTransRecipientInfo or KeyAgreeRecipientInfo using a public
key from a certificate for its key management protocol.
recipientKey - the private key of the recipient to be used for decrypting
the encrypted content-encryption key.recipientCertificate - the certificate of the recipient specifying which
RecipientInfo the recipient´s private key belongs toCMSException - if there occurs an error while decrypting the content-encryption key
or setting up the cipher for decrypting the content, or no RecipientInfo
for the requested recipient is includedjava.security.NoSuchAlgorithmException - if there is no implementation of the content-encryption algorithmjava.security.InvalidKeyException - if the specified private key is not validpublic void setupCipher(java.security.Key key)
throws CMSException,
java.security.NoSuchAlgorithmException,
java.security.InvalidKeyException
The secret key supplied to this method has to be the already decrypted content encryption key.
Unlike the non-stream supporting EnvelopedData class where the encrypted-content decryption
already is performed inside the setupCipher method, the cipher
will be only initialized for decrypting in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream method. So don´t call
getInputStream before setting up the cipher!
key - the temporary symmetric key that has been used to encrypt the content,
and now is used for decrypting it againCMSException - if there occurs an error while setting up the cipher for decrypting the contentjava.security.NoSuchAlgorithmException - if there is no implementation for the content-encryption algorithmjava.security.InvalidKeyException - if the specified private key is not validpublic java.io.InputStream getInputStream()
Attention! The stream only may be read once.
When having created a new EnvelopedDataStream object to
be encoded to a stream, this method should not be called at all, since the stream
automatically will be read during performing the encoding (which is done
when calling a writeTo method).
When having decoded and parsed a received EnvelopedDataStream object
comimg from some stream, this method may be used for obtaining the raw (decrypted) data
after having setup the cipher for decrypting the content.
public int getVersion()
public OriginatorInfo getOriginatorInfo()
The originatorInfo may be set for including certificates and/or certificate revocation lists if required by the key management algorithm used.
nullpublic RecipientInfo[] getRecipientInfos()
EnvelopedData object.RecipientInfo objects
included into this EnvelopedDatapublic RecipientInfo getRecipientInfo(X509Certificate recipientCertificate)
This method may be used by a recipient for querying for the recipient info
that holds the content encryption key encrypted with the public key of the
given certificate.
Note that this method only can be used for searching for RecipientInfos
of type KeyTransRecipientInfo or
KeyAgreeRecipientInfo, but NOT
KEKRecipientInfo
which does use a certificate.null if no recipient info belonging to the given
certificate can be foundpublic RecipientInfo getRecipientInfo(KeyIdentifier recipientIdentifier)
recipientIdentifier - the recipient identifier identifying the
recipient in mindnull if no recipient info belonging to the given
recipient identifier can be foundpublic EncryptedContentInfoStream getEncryptedContentInfo()
EnvelopedDataStream object.public Attribute[] getUnprotectedAttributes()
public Attribute getUnprotectedAttribute(ObjectID oid)
null if there is no attribute for the given OID.public ASN1Object toASN1Object() throws CMSException
toASN1Object in interface ContentStreamEnvelopedDataStream as ASN1Object.CMSException - if the ASN1Object could not be createdprotected ASN1Object toASN1Object(int blockSize) throws CMSException
If
blockSize - the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positiveCMSException - if the ASN1Object could not be createdpublic void writeTo(java.io.OutputStream os)
throws java.io.IOException
os - the output stream to which this EnvelopedData shall be writtenjava.io.IOExceptionpublic void writeTo(java.io.OutputStream os,
int blockSize)
throws java.io.IOException
When encoding the content data to the given stream it is piped through a cipher stream thereby performing the content encryption.
If the a positive blockSize value is specified, the encrypted content
is encoded as indefinite constructed octet string being composed of a certain number
of definite primitive encoded octet strings of blockSize length:
0x24 0x80
0x04 <blocksize> <first encrypted content block>
0x04 <blocksize> <second encrypted content block>
0x04 <blocksize> <third encrypted content block>
...
0x00 0x00
Otherwise, whole the encrypted content is encoded
as definite primitive octet string:
0x04 <length> <encrypted content>
os - the output stream to which this SignedData shall be writtenblockSize - the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positivejava.io.IOException - if an error occurs during writing the objectpublic java.lang.String toString()
EnvelopedData object.toString in class java.lang.Objectpublic java.lang.String toString(boolean detailed)
EnvelopedData object.toString in interface ContentStreamdetailed - - whether or not to give detailed informationpublic void notifyEOF()
throws java.io.IOException
Since the unprotected attributes are located at the end of the EnvelopedData
structure, they can only be accessed after the data stream (encrypted
content) has been completely read. For that reason, after beginning the
decode operation (after calling decode(InputStream)), but
before reading the data stream (reading input stream
getInputStream), only the version, originator information, and
recipient information can be parsed. Since the decrypted data is supplied
from an input stream, an iaik.utils.NotifyEOFInputStream is
wrapped around this input stream that will automatically notify the this
method when the stream has been completely read. At that point, this method
is automatically executed, which finishes the decoding operation by decoding
the unprotected attributes.
For any application it is strongly recommended recommended not to
explicitly call this method. This method only is qualified as public
method since it implements the iaik.utils.EOFListener
interface.
notifyEOF in interface EOFListenerjava.io.IOException - if an error occurs while decoding the unprotected attributedEOFListener,
NotifyEOFInputStream