iaik.cms
Class KeyAgreeRecipientInfo

java.lang.Object
  extended by iaik.cms.RecipientInfo
      extended by iaik.cms.KeyAgreeRecipientInfo
All Implemented Interfaces:
ASN1Type

public class KeyAgreeRecipientInfo
extends RecipientInfo

This class implements the CMS KeyAgreeRecipientInfo type.

The Cryptographic Message Syntax (CMS) (RFC 5652) specifies the KeyAgreeRecipientInfo type as RecipientInfo choice for collecting all recipient-related information about one or more recipients a CMS EnvelopedData, AuthEnvelopedData or AuthenticatedData object shall contain when a key agreement algorithm is used for encrypting the secret content encryption key. A KeyAgreeRecipientInfo may hold encrypted content encryption keys for any number of recipients using the same key agreement method and domain parameters for that key agreement algorithm:

 KeyAgreeRecipientInfo ::= SEQUENCE {
     version CMSVersion,  -- always set to 3
     originator [0] EXPLICIT OriginatorIdentifierOrKey,
     ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
     recipientEncryptedKeys RecipientEncryptedKeys }
 
 OriginatorIdentifierOrKey ::= CHOICE {
    issuerAndSerialNumber IssuerAndSerialNumber,
    subjectKeyIdentifier [0] SubjectKeyIdentifier,
    originatorKey [1] OriginatorPublicKey }

 OriginatorPublicKey ::= SEQUENCE {
    algorithm AlgorithmIdentifier,
    publicKey BIT STRING }

 RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey

 RecipientEncryptedKey ::= SEQUENCE {
    rid KeyAgreeRecipientIdentifier,
    encryptedKey EncryptedKey }

 KeyAgreeRecipientIdentifier ::= CHOICE {
    issuerAndSerialNumber IssuerAndSerialNumber,
    rKeyId [0] IMPLICIT RecipientKeyIdentifier }

 RecipientKeyIdentifier ::= SEQUENCE {
    subjectKeyIdentifier SubjectKeyIdentifier,
    date GeneralizedTime OPTIONAL,       
    other OtherKeyAttribute OPTIONAL }

 SubjectKeyIdentifier ::= OCTET STRING
 
The originator field is a CHOICE with three alternatives specifying the sender's key agreement public key. The sender uses the corresponding private key and the recipient's public key to generate a pairwise key. The content-encryption key is encrypted in the pairwise key. The issuerAndSerialNumber alternative identifies the sender's certificate, and thereby the sender's public key, by the issuer's distinguished name and the certificate serial number. The subjectKeyIdentifier alternative identifies the sender's certificate, and thereby the sender's public key, by the X.509 subjectKeyIdentifier extension value. The originatorKey alternative includes the algorithm identifier and sender's key agreement public key. Permitting originator anonymity since the public key is not certified.
ukm is optional. With some key agreement algorithms, the sender provides a User Keying Material (UKM) to ensure that a different key is generated each time the same two parties generate a pairwise key.
keyEncryptionAlgorithm identifies the key-encryption algorithm, and any associated parameters, used to encrypt the content-encryption key in the key-encryption key.
recipientEncryptedKeys includes a recipient identifier and encrypted key for one or more recipients. The KeyAgreeRecipientIdentifier is a CHOICE with two alternatives specifying the recipient's certificate, and thereby the recipient's public key, that was used by the sender to generate a pairwise key-encryption key. The recipient's certificate must contain a key agreement public key. The content-encryption key is encrypted in the pairwise key-encryption key. The issuerAndSerialNumber alternative identifies the recipient's certificate by the issuer's distinguished name and the certificate serial number; the RecipientKeyIdentifier identifies the recipient certificate and public key by X.509 SubjectKeyIdentifier and optional date and OtherKeyAttribute. When present, the date specifies which of the recipient's previously distributed UKMs was used by the sender. OtherKeyAttribute shall not be used for interoperability reasons but may contain additional information used by the recipient to locate the public keying material used by the sender.
The encryptedKey is the result of encrypting the content-encryption key in the pairwise key-encryption key generated using the key agreement algorithm.

The default key agreement method used by CMS is Ephemeral Static Diffie-Hellman (ESDH) (RFC 2631) using a ephemeral originator public key which has to be specified by using the OriginatorPublicKey option for the originator field.


This class provides several constructors and methods for creating a KeyAgreeRecipientInfo object, obtaining the component values, and encrypting (respectively decrypting) the content-encryption key.

When creating a new KeyAgreeRecipientInfo you have to decide whether to use the originatorPublicKey option for representing the public key of the originator or to use a static originator certificate. If using the originatorPublicKey option the originator key automatically will be created the first time when adding some particular recipient information, e.g.:

 // the key encryption (key agreement) algorithm to use:
 AlgorithmID keyEA = (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone();
 // the key wrap algorithm to use:
 AlgorithmID keyWrapAlg = (AlgorithmID)AlgorithmID.cms_aes256_wrap.clone();
 // the length of the key encryption key to be generated:
 int kekLength = 256;
 // create a KeyAgreeRecipientInfo using the OriginatorPublicKey option:
 KeyAgreeRecipientInfo keyAgreeRecipientInfo = 
   new KeyAgreeRecipientInfo(keyEA, keyWrapAlg, kekLength);
 // the ephemeral originator public key is created when adding the first recipient:
 X509Certificate recipientCertiificate = ...;
 keyAgreeRecipientInfo.addRecipient(recipientCertificate, CertificateIdentifier.ISSUER_AND_SERIALNUMBER);
 
Note that CMS per default uses Ephemeral Static Diffie-Hellman as key agreement algorithm for a KeyAgreeRecipientInfo. The originator has to be represented by the OriginatorPublicKey choice using a ephemeral originator key as in the sample above.

The following example shows the typical usage for including a KeyAgreeRecipientInfo into a EnvelopedData object, encoding it, decoding it at the recipient side and decrypt the content (we use the stream-based EnvelopedData implementation for this sample):

 // the key encryption (key agreement) algorithm to use:
 AlgorithmID keyEA = (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone();
 // the key wrap algorithm to use:
 AlgorithmID keyWrapAlg = (AlgorithmID)AlgorithmID.cms_aes256_wrap.clone();
 // the length of the key encryption key to be generated:
 int kekLength = 256;
 // create a KeyAgreeRecipientInfo using the OriginatorPublicKey option:
 KeyAgreeRecipientInfo recipient = 
   new KeyAgreeRecipientInfo(keyEA, keyWrapAlg, kekLength);
 // the ephemeral originator public key is created when adding the first recipient:
 X509Certificate recipientCertiificate = ...;
 keyAgreeRecipientInfo.addRecipient(recipientCertificate, CertificateIdentifier.ISSUER_AND_SERIALNUMBER);
 // create an EnvelopedData for the content to be encrypted:
 EnvelopedDataStream envelopedData = new EnvelopedDataStream(is, (AlgorithmID)AlgorithmID.aes256_CBC.clone());
 // add the recipient information:
 envelopedData.addRecipientInfo(recipient);
 // write the EnvelopedData to a stream thereby performing the content encryption:
 int blockSize = ...;
 OutputStream encoded_stream = ...;
 envelopedData.writeTo(encoded_stream, blockSize);
 ...
 // on the recipient side decode the EnvelopedData:
 InputStream encodedStream = ...;
 EnvelopedDataStream envelopedData = new EnvelopedData(encodedStream);
 // Get information about the inherent EncryptedContentInfo:
 EncryptedContentInfoStream eci = (EncryptedContentInfoStream)enveloped_data.getEncryptedContentInfo();
 System.out.println("Content type: "+eci.getContentType().getName());
 System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
 // setup the cipher for decryption:
 envelopedData.setupCipher(recipientPrivateKey, recipientCertificate);
 // read the content thereby performing the content decryption:
 InputStream data_is = enveloped_data.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 }
 
Have a look at the IAIK-CMS Demo library for examples how to use the KeyAgreeRecipientInfo type for ephemeral static or static static (finite field or elliptic curve based) DH.

See Also:
OriginatorPublicKey, IssuerAndSerialNumber, RecipientKeyIdentifier, RecipientInfo

Field Summary
 
Fields inherited from class iaik.cms.RecipientInfo
KEK_RECIPIENT_INFO, KEY_AGREE_RECIPIENT_INFO, KEY_TRANSPORT_RECIPIENT_INFO, keyEncryptionAlgorithm_, OTHER_RECIPIENT_INFO, PASSWORD_RECIPIENT_INFO, securityProvider_, version_
 
Constructor Summary
KeyAgreeRecipientInfo()
          Default Constructor.
KeyAgreeRecipientInfo(AlgorithmID keyEA, AlgorithmID keyWrapAlg, int kekLength)
          Creates a KeyAgreeRecipientInfo for the given key encryption (key agreement) algorithm, key wrap algorithm and user keying material.
KeyAgreeRecipientInfo(ASN1Object obj)
          Creates a KeyAgreeRecipientInfo from an ASN1Object.
KeyAgreeRecipientInfo(ASN1Object obj, SecurityProvider securityProvider)
          Creates a KeyAgreeRecipientInfo from an ASN1Object.
KeyAgreeRecipientInfo(KeyIdentifier originator, AlgorithmID keyEA, byte[] ukm)
          Creates a KeyAgreeRecipientInfo for the given Originator, key encryption (key agreement) algorithm and user keying material.
KeyAgreeRecipientInfo(X509Certificate originatorCertificate, java.security.PrivateKey originatorPrivateKey, int originatorIdentifierType, AlgorithmID keyEA, AlgorithmID keyWrapAlg, int kekLength, byte[] ukm)
          Creates a KeyAgreeRecipientInfo object from the given originator certificate.
 
Method Summary
 void addRecipient(CertificateIdentifier recipientIdentifier, byte[] encryptedKey)
          Adds a recipient with given recipient identifier and already encrypted key.
 java.security.KeyPair addRecipient(CertificateIdentifier recipientIdentifier, java.security.PublicKey recipientKey)
          Adds a recipient with given recipient identifier and public key agreement key.
 java.security.KeyPair addRecipient(X509Certificate recipientCertificate, int recipientIdentifierType)
          Adds a recipient with the given certificate.
 int countRecipientEncryptedKeys()
          Counts the number of RecipientEncryptedKeys included in this KeyAgreeRecipientInfo.
 void decode(ASN1Object obj)
          Decodes the given ASN.1 KeyAgreeRecipientInfo object for parsing the internal structure.
 javax.crypto.SecretKey decryptKey(java.security.Key privateKey)
          Uses the given private key for trying to decrypt the encrypted content-encryption key.
 javax.crypto.SecretKey decryptKey(java.security.Key privateKey, KeyIdentifier recipientIdentifier, java.lang.String cekAlgName)
          Uses the given private key to decrypt the encrypted content-encryption key for the recipient with the given recipient identifier.
 javax.crypto.SecretKey decryptKey(java.security.PrivateKey privateKey, KeyIdentifier recipientIdentifier, java.security.PublicKey originatorPublicKey, java.lang.String cekAlgName)
          Uses the given private key and originator public key to decrypt the encrypted content-encryption key for the recipient with the given recipient identifier.
 javax.crypto.SecretKey decryptKey(java.security.PrivateKey privateKey, X509Certificate recipientCertificate, java.security.PublicKey originatorPublicKey, java.lang.String cekAlgName)
          Uses the given private key and originator public key to decrypt the encrypted content-encryption key for the recipient with the given recipient certificate.
 javax.crypto.SecretKey decryptKey(java.security.PrivateKey privateKey, X509Certificate recipientCertificate, java.lang.String cekAlgName)
          Uses the given private key to decrypt the encrypted content-encryption key for the recipient with the given recipient certificate.
 void encryptKey(javax.crypto.SecretKey cek)
          Encrypts the given secret content-encryption key.
 byte[] getEncryptedKey(KeyIdentifier recipientIdentifier)
          Returns the encrypted content-encryption key for the recipient with the given keyIdentfier.
 AlgorithmID getKeyWrapAlgorithm()
          Returns the key wrap algorithm used for encrypting the content-encryption key with the shared key encryption key.
 KeyIdentifier getOriginator()
          Returns the originator information identifying the public key of the originator.
 KeyIdentifier[] getRecipientIdentifiers()
          Gets the key identifier belonging to the recipient of this KeyAgreeRecipientInfo.
 byte[] getUKM()
          Gets the user keying material, if included.
 boolean isRecipientInfoFor(KeyIdentifier recipientIdentifier)
          Checks if this is a RecipientInfo for the recipient identified by the given key identifier.
 CertificateIdentifier isRecipientInfoFor(X509Certificate recipientCertificate)
          Checks if this is a RecipientInfo for the given recipient certificate.
 void setSecurityProvider(SecurityProvider securityProvider)
          Sets the SecurityProvider for this KeyAgreeRecipientInfo.
 void setUKM(byte[] ukm)
          Sets the optional user keying material.
 ASN1Object toASN1Object()
          Returns this KeyAgreeRecipientInfo as ASN1Object.
 java.lang.String toString()
          Returns a string giving some information about this KeyAgreeRecipientInfo object.
 
Methods inherited from class iaik.cms.RecipientInfo
createRecipientInfos, decryptKey, decryptKey, getKeyEncryptionAlgorithm, getRecipientInfoType, getSecurityProvider, getVersion, parseRecipientInfo, parseRecipientInfo, parseRecipientInfo, parseRecipientInfo, parseRecipientInfos, parseRecipientInfos
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

KeyAgreeRecipientInfo

public KeyAgreeRecipientInfo()
Default Constructor. Creates an empty KeyAgreeRecipientInfo object and sets the version number to 3.


KeyAgreeRecipientInfo

public KeyAgreeRecipientInfo(AlgorithmID keyEA,
                             AlgorithmID keyWrapAlg,
                             int kekLength)
Creates a KeyAgreeRecipientInfo for the given key encryption (key agreement) algorithm, key wrap algorithm and user keying material.

When using this constructor for creating a KeyAgreeRecipientInfo the OriginatorPublicKey option is used for representing the public key in the originator field. The OriginatorPublicKey is automatically created the first time when adding recipient information. Any further recipient information added is required to have a public key with domain parameters matching to those of the originator key.

Note that RFC 5652 per default use Ephemeral Static Diffie Hellman for KeyAgreeRecipientInfos and the OriginatorPublicKey option has to be used for representing the ESDH ephemeral public key of the originator.

Any user keying material to be used may be set by calling method setUKM.

Parameters:
keyEA - the key encryption (key agreement) algorithm used for creating a shared key encryption key for encrypting the secret content encryption key with it (will not be cloned)
keyWrapAlg - the key wrap algorithm to be used for wrapping (encrypting) the content encryption key (will not be cloned)
kekLength - the length of the key encryption key to be created for encrypting the content encryption key with it

KeyAgreeRecipientInfo

public KeyAgreeRecipientInfo(X509Certificate originatorCertificate,
                             java.security.PrivateKey originatorPrivateKey,
                             int originatorIdentifierType,
                             AlgorithmID keyEA,
                             AlgorithmID keyWrapAlg,
                             int kekLength,
                             byte[] ukm)
                      throws X509ExtensionException
Creates a KeyAgreeRecipientInfo object from the given originator certificate.

From the given certificate a IssuerAndSerialNumber or SubjectKeyIdentifier (depending on the requested originator identifier type) is created for pointing to the certificate and thereby public key of the originator.
Any time when adding recipient information the public key of the recipient is required to have domain parameters matching to those of the originator key.

Note that RFC 5652 per default use Ephemeral Static Diffie Hellman for KeyAgreeRecipientInfos where the OriginatorPublicKey has to be used for representing the ESDH ephemeral public key of the originator. Using a certificate on the originator side would mean to use a static originator. When using static-static mode, the user keying material (ukm) should NOT be null.

Parameters:
originatorCertificate - the certificate of the originator
originatorIdentifierType - the type of the originatorIdentifier, either CertificateIdentifier.ISSUER_AND_SERIALNUMBER or CertificateIdentifier.SUBJECT_KEY_IDENTIFIER
keyEA - the key encryption (key agreement) algorithm used for creating a shared key encryption key for encrypting the secret content encryption key with it (will not be cloned)
keyWrapAlg - the key wrap algorithm to be used for wrapping (encrypting) the content encryption key (will not be cloned)
kekLength - the length (in bits) of the key encryption key to be created for encrypting the content encryption key with it
ukm - user keying material that may be used to ensure that a different key is generated each time the same two parties generate a pairwise key; if null, random user keying material of kekLength size (or at least 512 bits) is automatically generated when encrypting the content (authenticated) encryption key; use setUKM(null) if you explicitly wish to not use any user keying material (however, not providing an ukm value is not recommended, especially if static-static DH is used)
Throws:
X509ExtensionException - if a SubjectKeyIdentifier shall be used as originatorIdentifier, but the given cert does contain the SubjectKeyIdentifier extension or the SubjectKeyIdentifier extension cannot be parsed
java.lang.IllegalArgumentException - if the request originatorIdentifier type is not ISSUER_AND_SERIALNUMBER or SUBJECT_KEY_IDENTIFIER

KeyAgreeRecipientInfo

public KeyAgreeRecipientInfo(KeyIdentifier originator,
                             AlgorithmID keyEA,
                             byte[] ukm)
Creates a KeyAgreeRecipientInfo for the given Originator, key encryption (key agreement) algorithm and user keying material.

When using this constructor for creating a KeyAgreeRecipientInfo recipient information only can be added for an already encrypted content encryption key by calling method addRecipient(CertificateIdentifier recipientIdentifier, byte[] encryptedKey).

Parameters:
originator - information identifying the public key of the originator, either by IssuerAndSerialNumber, SubjectKeyIdentifier, or OriginatorPublicKey
keyEA - the key encryption (key agreement) algorithm used for encrypting the secret content encryption key with a shared key encryption key (will not be cloned)
ukm - user keying material that may be used to ensure that a different key is generated each time the same two parties generate a pairwise key; if null, random user keying material of kekLength size (or at least 512 bits) is automatically generated when encrypting the content (authenticated) encryption key; use setUKM(null) if you explicitly wish to not use any user keying material (however, not providing an ukm value is not recommended, especially if static-static DH is used)
Throws:
java.lang.IllegalArgumentException - if the specified originator key identifier is not a IssuerAndSerialNumber, SubjectKeyIdentifier, or OriginatorPublicKey

KeyAgreeRecipientInfo

public KeyAgreeRecipientInfo(ASN1Object obj)
                      throws CodingException
Creates a KeyAgreeRecipientInfo from an ASN1Object.

The ASN1Object supplied to this constructor represents an already existing KeyAgreeRecipientInfo object that may have been created by calling toASN1Object.

Parameters:
obj - the KeyAgreeRecipientInfo as ASN1Object
Throws:
CodingException - if the object can not be parsed

KeyAgreeRecipientInfo

public KeyAgreeRecipientInfo(ASN1Object obj,
                             SecurityProvider securityProvider)
                      throws CodingException
Creates a KeyAgreeRecipientInfo from an ASN1Object.

The ASN1Object supplied to this constructor represents an already existing KeyAgreeRecipientInfo object that may have been created by calling toASN1Object.

Parameters:
obj - the KeyAgreeRecipientInfo as ASN1Object
securityProvider - the SecurityProvider to be used by this object
Throws:
CodingException - if the object can not be parsed
Method Detail

setUKM

public void setUKM(byte[] ukm)
Sets the optional user keying material.

User keying material may be specified to ensure that a different key is generated each time the same two parties generate a pairwise key. When no user keying material is specified (or has not been specified when creating the KeyAgreeRecipientInfo) random user keying material of kekLength size (or at least 512 bits) is automatically generated when encrypting the content (authenticated) encryption key. Use setUKM(null) if you explicitly wish to not use any user keying material (however, not using an ukm value is not recommended, especially if static-static DH is used)

Parameters:
ukm - optional user keying material that may be used to ensure that a different key is generated each time the same two parties generate a pairwise key; null if no ukm shall be used

getOriginator

public KeyIdentifier getOriginator()
Returns the originator information identifying the public key of the originator.

Returns:
the originator information identifying the public key of the originator, either by IssuerAndSerialNumber, SubjectKeyIdentifier, or OriginatorPublicKey

getUKM

public byte[] getUKM()
Gets the user keying material, if included.

User keying material may be included to ensure that a different key is generated each time the same two parties generate a pairwise key. When using ephmeral-static Diffie Hellman user keying material should be specified when using a static originator certificate (which however should not be used with CMS).

This method also may be used for setting the previously distributed ukm for a KeyAgreeRecipientInfo received.

Returns:
the user keying material, if included (not cloned!); otherwise null

addRecipient

public java.security.KeyPair addRecipient(CertificateIdentifier recipientIdentifier,
                                          java.security.PublicKey recipientKey)
                                   throws java.security.InvalidKeyException
Adds a recipient with given recipient identifier and public key agreement key.

This method may be called repeatedly for adding information for each recipient having a public key agreement key with domain parameters matching to those of the originator key. When calling this method the first time (for adding the first recipient) and the originator key yet has not been set, this method itself creates a OriginatorPublicKey with domain parameters matching to those of the supplied recipient key. Any further call to this method only will be successful if the new recipient has a public key with domain parameters matching to those of the originator key.

Parameters:
recipientIdentifier - the CertificateIdentifier identifying the recipient certificate and thereby public key (by IssuerAndSerialNumber or RecipientKeyIdentifier
recipientKey - the public key agreement key of the recipient
Returns:
the originator key pair which may have been just created when calling this method the first time
Throws:
java.security.InvalidKeyException - if an error occurs when creating the OriginatorPublicKey or the supplied recipient key has domain parameters not matching to those of the already set originator key
java.lang.IllegalArgumentException - if the given recipient identifier is not a IssuerAndSerialNumber or RecipientKeyIdentifier

addRecipient

public java.security.KeyPair addRecipient(X509Certificate recipientCertificate,
                                          int recipientIdentifierType)
                                   throws java.security.InvalidKeyException,
                                          X509ExtensionException
Adds a recipient with the given certificate.

This method may called repeatedly for adding information for each recipient having a certificate with a public key agreement key with domain parameters matching to those of the originator key. When calling this method the first time (for adding the first recipient) and the originator key yet has not been set, this method itself creates a OriginatorPublicKey with domain parameters matching to those of the supplied recipient key. Any further call to this method only will be successful if the new recipient has a certificate with a public key with domain parameters matching to those of the originator key.

Parameters:
recipientCertificate - the certificate of the recipient
recipientIdentifierType - the type of the recipientIdentifier, either CertificateIdentifier.ISSUER_AND_SERIALNUMBER or CertificateIdentifier.RECIPIENT_KEY_IDENTIFIER. If the recipient certificate shall be identified by using the RECIPIENT_KEY_IDENTIFIER choice, a RecipientKeyIdentifier without date and otherKeyAttribute is created
Returns:
the originator key pair which may have been just created when calling this method the first time
Throws:
java.security.InvalidKeyException - if an error occurs when creating the OriginatorPublicKey or the public key of the recipient certificate has domain parameters not matching to those of the already set originator key
X509ExtensionException - if the recipient certificate shall be represented by a RecipientKeyIdentifier, but does not contain the SubjectKeyIdentifier extension
java.lang.IllegalArgumentException - if the given recipient identifier type is not a ISSUER_AND_SERIALNUMBER or RECIPIENT_KEY_IDENTIFIER

addRecipient

public void addRecipient(CertificateIdentifier recipientIdentifier,
                         byte[] encryptedKey)
                  throws CMSException
Adds a recipient with given recipient identifier and already encrypted key.

Attention: This method cannot not check if the key agreement method or domain parameters of the recipient key are suitable for this KeyAgreeRecipientInfo.

Parameters:
recipientIdentifier - the CertificateIdentifier identifying the recipient certificate and thereby public key (by IssuerAndSerialNumber or RecipientKeyIdentifier
encryptedKey - the already encrypted content encryption key
Throws:
CMSException - if no originator has been set when creating this KeyAgreeRecipientInfo
java.lang.IllegalArgumentException - if the given recipient identifier is not a IssuerAndSerialNumber or RecipientKeyIdentifier

setSecurityProvider

public void setSecurityProvider(SecurityProvider securityProvider)
Sets the SecurityProvider for this KeyAgreeRecipientInfo.

The SecurityProvider can be only used by methods called after this method, for instance, for encrypting or decrypting the content encryption key.

Overrides:
setSecurityProvider in class RecipientInfo
Parameters:
securityProvider - the SecurityProvider to be set

decode

public void decode(ASN1Object obj)
            throws CodingException
Decodes the given ASN.1 KeyAgreeRecipientInfo object for parsing the internal structure.

This method internally is called when creating a CMS KeyAgreeRecipientInfo object from an already existing KeyAgreeRecipientInfo object, supplied as ASN1Object.

Parameters:
obj - the CMS KeyAgreeRecipientInfo as ASN1Object
Throws:
CodingException - if the object can not be parsed

toASN1Object

public ASN1Object toASN1Object()
                        throws CodingException
Returns this KeyAgreeRecipientInfo as ASN1Object.

The ASN1Object returned by this method represents the ASN.1 structure of a KeyAgreeRecipientInfo:

 KeyAgreeRecipientInfo ::= SEQUENCE {
     version CMSVersion,  -- always set to 3
     originator [0] EXPLICIT OriginatorIdentifierOrKey,
     ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
     recipientEncryptedKeys RecipientEncryptedKeys }
 
 OriginatorIdentifierOrKey ::= CHOICE {
    issuerAndSerialNumber IssuerAndSerialNumber,
    subjectKeyIdentifier [0] SubjectKeyIdentifier,
    originatorKey [1] OriginatorPublicKey }

 OriginatorPublicKey ::= SEQUENCE {
    algorithm AlgorithmIdentifier,
    publicKey BIT STRING }

 RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey

 RecipientEncryptedKey ::= SEQUENCE {
    rid KeyAgreeRecipientIdentifier,
    encryptedKey EncryptedKey }

 KeyAgreeRecipientIdentifier ::= CHOICE {
    issuerAndSerialNumber IssuerAndSerialNumber,
    rKeyId [0] IMPLICIT RecipientKeyIdentifier }

 RecipientKeyIdentifier ::= SEQUENCE {
    subjectKeyIdentifier SubjectKeyIdentifier,
    date GeneralizedTime OPTIONAL,       
    other OtherKeyAttribute OPTIONAL }

 SubjectKeyIdentifier ::= OCTET STRING
 

Returns:
this KeyAgreeRecipientInfo as ASN1Object.
Throws:
CodingException

decryptKey

public javax.crypto.SecretKey decryptKey(java.security.Key privateKey)
                                  throws CMSException,
                                         java.security.InvalidKeyException
Uses the given private key for trying to decrypt the encrypted content-encryption key. The recovered key is returned as SecretKey.

Since an KeyAgreeRecipientInfo may contain encrypted content encryption keys for more than only one recipient, but no recipient identifier can be supplied when calling this method, any included encrypted content encryption key is tried to be decrypted with the given private key, which may give some processing overhead and might bring no result if the right recipient encrypted key is not included.

Note that the originator public key is required to create the shared secret key encryption key for subsequently decrypting the encrypted content encryption key with it. For that reason you only can use this method if the originator field of this KeyAgreeRecipientInfo holds the OriginatorPublicKey choice (RFC 5652 per default use Ephemeral Static Diffie Hellman (ESDH) for KeyAgreeRecipientInfos representing the ephemeral public key of the originator with the OriginatorPublicKey choice). Otherwise you have to supply the originator public key yourself for decrypting the encrypted content encryption key.

Overrides:
decryptKey in class RecipientInfo
Parameters:
privateKey - the private key of the recipient to be used for decrypting the encrypted content-encryption key.
Returns:
the recovered (decrypted) key as SecretKey in RAW format; the algorithm name will be set to "RAW"
Throws:
CMSException - if the key-decryption process fails for some reason (e.g. the key-encryption or key-wrap algorithm used by this KeyAgreeRecipientInfo is not implemented, a padding error occurs,...)
java.security.InvalidKeyException - if the specified private key is not valid

decryptKey

public javax.crypto.SecretKey decryptKey(java.security.Key privateKey,
                                         KeyIdentifier recipientIdentifier,
                                         java.lang.String cekAlgName)
                                  throws CMSException,
                                         java.security.InvalidKeyException
Uses the given private key to decrypt the encrypted content-encryption key for the recipient with the given recipient identifier. The recovered key is returned as SecretKey.

Since an KeyAgreeRecipientInfo may contain encrypted content encryption keys for more than only one recipient, this method first looks if any of the included recipient encrypted keys belongs to the recipient identified by the given recipient identifier. If a recipient encrypted key is included for the recipient in mind it is decrypted with the given private key of this recipient. If no recipient identifier is supplied when calling this method, any included encrypted content encryption key is tried to be decrypted with the given private key, which may give some processing overhead and might bring no result if the right recipient encrypted key is not included.

Note that the originator public key is required to create the shared secret key encryption key for subsequently decrypting the encrypted content encryption key with it. For that reason you only can use this method if the originator field of this KeyAgreeRecipientInfo holds the OriginatorPublicKey choice (RFC 5652 per default use Ephemeral Static Diffie Hellman (ESDH) for KeyAgreeRecipientInfos representing the ephemeral public key of the originator with the OriginatorPublicKey choice). Otherwise you have to supply the originator public key yourself for decrypting the encrypted content encryption key.

Specified by:
decryptKey in class RecipientInfo
Parameters:
privateKey - the private key of the recipient to be used for decrypting the encrypted content-encryption key.
recipientIdentifier - an IssuerAndSerialNumber or RecipientKeyIdentifier identifying the recipient of this KeyAgreeRecipientInfo
cekAlgName - the name of the content encryption key (e.g. "AES") to be set for the SecretKey object created by this method
Returns:
the recovered (decrypted) key as SecretKey in RAW format
Throws:
CMSException - if the key-decryption process fails for some reason (e.g. the key-encryption or key-wrap algorithm used by this KeyAgreeRecipientInfo is not implemented, a padding error occurs,...)
java.security.InvalidKeyException - if the specified private key is not valid

decryptKey

public javax.crypto.SecretKey decryptKey(java.security.PrivateKey privateKey,
                                         KeyIdentifier recipientIdentifier,
                                         java.security.PublicKey originatorPublicKey,
                                         java.lang.String cekAlgName)
                                  throws CMSException,
                                         java.security.InvalidKeyException
Uses the given private key and originator public key to decrypt the encrypted content-encryption key for the recipient with the given recipient identifier. The recovered key is returned as SecretKey.

Since an KeyAgreeRecipientInfo may contain encrypted content encryption keys for more than only one recipient, this method first looks if any of the included recipient encrypted keys belongs to the recipient identified by the given recipient identifier. If a recipient encrypted key is included for the recipient in mind it is decrypted with the given private key of this recipient. If no recipient identifier is supplied when calling this method, any included encrypted content encryption key is tried to be decrypted with the given private key, which may give some processing overhead and might bring no result if the right recipient encrypted key is not included.

Parameters:
privateKey - the private key of the recipient to be used for decrypting the encrypted content-encryption key.
recipientIdentifier - an IssuerAndSerialNumber or RecipientKeyIdentifier identifying the recipient of this KeyAgreeRecipientInfo
originatorPublicKey - the public key of the originator; required for calculating the shared key encryption algorithm used for en/decrypting the content encryption key
cekAlgName - the name of the content encryption key (e.g. "AES") to be set for the SecretKey object created by this method
Returns:
the recovered (decrypted) key as SecretKey in RAW format
Throws:
CMSException - if the key-decryption process fails for some reason (e.g. the key-encryption or key-wrap algorithm used by this KeyAgreeRecipientInfo is not implemented, a padding error occurs,...)
java.security.InvalidKeyException - if the specified private key is not valid

decryptKey

public javax.crypto.SecretKey decryptKey(java.security.PrivateKey privateKey,
                                         X509Certificate recipientCertificate,
                                         java.lang.String cekAlgName)
                                  throws CMSException,
                                         java.security.InvalidKeyException
Uses the given private key to decrypt the encrypted content-encryption key for the recipient with the given recipient certificate. The recovered key is returned as SecretKey.

Since an KeyAgreeRecipientInfo may contain encrypted content encryption keys for more than only one recipient, this method first looks if any of the included recipient encrypted keys belongs to the recipient with the given certfiicate. If a recipient encrypted key is included for the recipient in mind it is decrypted with the given private key of this recipient.

Note that the originator public key is required to create the shared secret key encryption key for subsequently decrypting the encrypted content encryption key with it. For that reason you only can use this method if the originator field of this KeyAgreeRecipientInfo holds the OriginatorPublicKey choice (RFC 5652 per default use Ephemeral Static Diffie Hellman (ESDH) for KeyAgreeRecipientInfos representing the ephemeral public key of the originator with the OriginatorPublicKey choice). Otherwise you have to supply the originator public key yourself for decrypting the encrypted content encryption key.

Parameters:
privateKey - the private key of the recipient to be used for decrypting the encrypted content-encryption key.
recipientCertificate - the certifcate of the recipient
cekAlgName - the name of the content encryption key (e.g. "AES") to be set for the SecretKey object created by this method
Returns:
the recovered (decrypted) key as SecretKey in RAW format
Throws:
CMSException - if the key-decryption process fails for some reason (e.g. the key-encryption or key-wrap algorithm used by this KeyAgreeRecipientInfo is not implemented, a padding error occurs,...)
java.security.InvalidKeyException - if the specified private key is not valid

decryptKey

public javax.crypto.SecretKey decryptKey(java.security.PrivateKey privateKey,
                                         X509Certificate recipientCertificate,
                                         java.security.PublicKey originatorPublicKey,
                                         java.lang.String cekAlgName)
                                  throws CMSException,
                                         java.security.InvalidKeyException
Uses the given private key and originator public key to decrypt the encrypted content-encryption key for the recipient with the given recipient certificate. The recovered key is returned as SecretKey.

Since an KeyAgreeRecipientInfo may contain encrypted content encryption keys for more than only one recipient, this method first looks if any of the included recipient encrypted keys belongs to the recipient with the given recipient certificate. If a recipient encrypted key is included for the recipient in mind it is decrypted with the given private key of this recipient.

Parameters:
privateKey - the private key of the recipient to be used for decrypting the encrypted content-encryption key.
recipientCertificate - the certificate of the recipient
originatorPublicKey - the public key of the originator; required for calculating the shared key encryption algorithm used for en/decrypting the content encryption key
cekAlgName - the name of the content encryption key (e.g. "AES") to be set for the SecretKey object created by this method
Returns:
the recovered (decrypted) key as SecretKey in RAW format
Throws:
CMSException - if the key-decryption process fails for some reason (e.g. the key-encryption or key-wrap algorithm used by this KeyAgreeRecipientInfo is not implemented, a padding error occurs,...)
java.security.InvalidKeyException - if the specified private key is not valid

encryptKey

public void encryptKey(javax.crypto.SecretKey cek)
                throws CMSException
Encrypts the given secret content-encryption key.

All information (key encryption (key agreement) algorithm, key wrap algorithm, kek length, ukm, originator key, public key of the recipient) has been supplied when creating this KeyAgreeRecipientInfo respectively adding information about some recipient. This method encrypts the supplied content encryption key for any recipient that has been added to this KeyAgreeRecipientInfo.
When no user keying material has been specified when creating the KeyAgreeRecipientInfo (or by calling method setUKM()) random user keying material of kekLength size (or at least 512 bits) is automatically generated when encrypting the content (authenticated) encryption key. If method setUKM() has been explicitly called with null as value no user keying material is used (however, not using an ukm value is not recommended, especially if static-static DH is used).

Specified by:
encryptKey in class RecipientInfo
Parameters:
cek - the symmetric content-encryption key to encrypt
Throws:
CMSException - if the key encryption process fails for some reason (e.g. the key-encryption or key-wrap algorithm used by this KeyAgreeRecipientInfo is not implemented, the public key of the recipient is invalid, a padding error occurs,...)

getRecipientIdentifiers

public KeyIdentifier[] getRecipientIdentifiers()
Gets the key identifier belonging to the recipient of this KeyAgreeRecipientInfo.

This method implements the same named method of the abstract parent RecipientInfo class for returning the identifiers of the recipient certificates (and thereby public keys) by issuer distinguished name and issuer-specific serial number, or RecipientKeyIdentifier.

Specified by:
getRecipientIdentifiers in class RecipientInfo
Returns:
an KeyIdentifier array holding the identifiers of the recipient certificates (and thereby public keys) by IssuerAndSerialNumber or RecipientKeyIdentifier

countRecipientEncryptedKeys

public int countRecipientEncryptedKeys()
Counts the number of RecipientEncryptedKeys included in this KeyAgreeRecipientInfo.

Returns:
the number of RecipientEncryptedKeys included in this KeyAgreeRecipientInfo.

isRecipientInfoFor

public boolean isRecipientInfoFor(KeyIdentifier recipientIdentifier)
Checks if this is a RecipientInfo for the recipient identified by the given key identifier.

Specified by:
isRecipientInfoFor in class RecipientInfo
Parameters:
recipientIdentifier - the key identifier belonging to the recipient we are searching for
Returns:
true if this RecipientInfo belongs to the particular recipient in mind, false if not

isRecipientInfoFor

public CertificateIdentifier isRecipientInfoFor(X509Certificate recipientCertificate)
Checks if this is a RecipientInfo for the given recipient certificate.

This method steps through the RecipientEncryptedKeys included in this KeyAgreeRecipientInfo. As long as no match is found, from the given certificate a recipient identifier is created to be compared to the same-type recipient identifier of the current RecipientEncryptedKey. If a match is found the corresponding recipient identifier is returned. If no match is found, null is returned indicating that this KeyAgreeRecipientInfo does not belong to the recipient in mind.

Note that in the case of recipient identifier type RecipientKeyIdentifier no date or OtherKeyAttribute can be created by this method. If date and/or OtherKeyAttribute are used by any of the recipient key identifiers of this KeyAgreeRecipientIdentifier you may create the search identifier by yourself and call method isRecipientInfoFor to ask if this KeyAgreeRecipientInfo belongs to the particular recipient in mind.

Specified by:
isRecipientInfoFor in class RecipientInfo
Parameters:
recipientCertificate - the certificate of the recipient
Returns:
the CertificateIdentifier indicating that the recipient with the given certificate is the owner of this RecipientInfo, null if not

getEncryptedKey

public byte[] getEncryptedKey(KeyIdentifier recipientIdentifier)
                       throws CMSException
Returns the encrypted content-encryption key for the recipient with the given keyIdentfier.

This method implements the same named method of the abstract parent RecipientInfo class for asking if this KeyAgreeRecipientInfo holds an encrypted key for the recipient identified by the given key identifier (IssuerAndSerialNumber or SubjectKeyIdentifier).

Specified by:
getEncryptedKey in class RecipientInfo
Parameters:
recipientIdentifier - information to be used for getting the right encrypted content encryption key for the right recipient; may be not required for a KeyAgreeRecipientInfo, but for KeyAgreeRecipientInfo) which may hold encrypted content encryption keys for more than one recipient; may be null for only getting the encrypted content-encryption key included
Returns:
the encrypted content-encryption key for the recipient with the given key identifier
Throws:
CMSException - if this KeyAgreeRecipientInfo does not belong to the recipient with the given key identifier is included

getKeyWrapAlgorithm

public AlgorithmID getKeyWrapAlgorithm()
Returns the key wrap algorithm used for encrypting the content-encryption key with the shared key encryption key.

Returns:
the key wrap algorithm or null if not set

toString

public java.lang.String toString()
Returns a string giving some information about this KeyAgreeRecipientInfo object.

Specified by:
toString in class RecipientInfo
Returns:
the string representation

This Javadoc may contain text parts from text parts from IETF Internet Standard specifications (see copyright note).

IAIK-CMS 6.0, (c) 2002 IAIK, (c) 2003, 2023 SIC