Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions crypto/src/cms/KEKRecipientInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,54 @@

namespace Org.BouncyCastle.Cms
{
/**
* the RecipientInfo class for a recipient who has been sent a message
* encrypted using a secret key known to the other side.
*/
/// <summary>
/// CMS recipient information for key-encryption-key (KEK) recipients that share a symmetric wrapping key.
/// </summary>
public class KekRecipientInformation
: RecipientInformation
{
private KekRecipientInfo info;

internal KekRecipientInformation(
KekRecipientInfo info,
CmsSecureReadable secureReadable)
: base(info.KeyEncryptionAlgorithm, secureReadable)
{
internal KekRecipientInformation(
KekRecipientInfo info,
CmsSecureReadable secureReadable)
: base(info.KeyEncryptionAlgorithm, secureReadable)
{
this.info = info;
this.rid = new RecipientID();

KekIdentifier kekId = info.KekID;
KekIdentifier kekId = info.KekID;

rid.KeyIdentifier = kekId.KeyIdentifier.GetOctets();
rid.KeyIdentifier = kekId.KeyIdentifier.GetOctets();
}

/**
* decrypt the content and return an input stream.
*/
/// <summary>Decrypts the content using the recipient's shared key-encryption key.</summary>
/// <param name="key">The shared key-encryption key.</param>
/// <returns>A typed stream over the decrypted content.</returns>
/// <exception cref="CmsException">Thrown if the content-encryption key cannot be recovered.</exception>
public override CmsTypedStream GetContentStream(
ICipherParameters key)
{
try
{
byte[] encryptedKey = info.EncryptedKey.GetOctets();
try
{
byte[] encryptedKey = info.EncryptedKey.GetOctets();
IWrapper keyWrapper = WrapperUtilities.GetWrapper(keyEncAlg.Algorithm);

keyWrapper.Init(false, key);

KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));

return GetContentFromSessionKey(sKey);
}
catch (SecurityUtilityException e)
{
throw new CmsException("couldn't create cipher.", e);
}
catch (InvalidKeyException e)
{
throw new CmsException("key invalid in message.", e);
}
keyWrapper.Init(false, key);

KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));

return GetContentFromSessionKey(sKey);
}
catch (SecurityUtilityException e)
{
throw new CmsException("couldn't create cipher.", e);
}
catch (InvalidKeyException e)
{
throw new CmsException("key invalid in message.", e);
}
}
}
}
16 changes: 9 additions & 7 deletions crypto/src/cms/KeyAgreeRecipientInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@

namespace Org.BouncyCastle.Cms
{
/**
* the RecipientInfo class for a recipient who has been sent a message
* encrypted using key agreement.
*/
/// <summary>
/// CMS recipient information for key agreement, where a sender and recipient derive the key-encryption key.
/// </summary>
public class KeyAgreeRecipientInformation
: RecipientInformation
{
Expand Down Expand Up @@ -197,9 +196,12 @@ internal KeyParameter GetSessionKey(AsymmetricKeyParameter receiverPrivateKey)
}
}

/**
* decrypt the content and return an input stream.
*/
/// <summary>Decrypts the content using the recipient's key-agreement private key.</summary>
/// <param name="key">The recipient's private asymmetric key.</param>
/// <returns>A typed stream over the decrypted content.</returns>
/// <exception cref="ArgumentException">Thrown if <paramref name="key"/> is not a private asymmetric key.
/// </exception>
/// <exception cref="CmsException">Thrown if key agreement or content-key recovery fails.</exception>
public override CmsTypedStream GetContentStream(
ICipherParameters key)
{
Expand Down
14 changes: 8 additions & 6 deletions crypto/src/cms/KeyTransRecipientInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@

namespace Org.BouncyCastle.Cms
{
/**
* the KeyTransRecipientInformation class for a recipient who has been sent a secret
* key encrypted using their public key that needs to be used to
* extract the message.
*/
/// <summary>
/// CMS recipient information for key transport, where the content-encryption key is encrypted for a recipient's
/// public key.
/// </summary>
public class KeyTransRecipientInformation
: RecipientInformation
{
Expand Down Expand Up @@ -142,7 +141,10 @@ internal KeyParameter UnwrapKey(ICipherParameters key)
}
}

/// <summary>Decrypt the content and return it as a byte array.</summary>
/// <summary>Decrypts the content using the recipient's private key and returns a stream over it.</summary>
/// <param name="key">The recipient's private key.</param>
/// <returns>A typed stream over the decrypted content.</returns>
/// <exception cref="CmsException">Thrown if the content-encryption key cannot be recovered.</exception>
public override CmsTypedStream GetContentStream(ICipherParameters key) => GetContentFromSessionKey(UnwrapKey(key));
}
}
11 changes: 6 additions & 5 deletions crypto/src/cms/PasswordRecipientInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Org.BouncyCastle.Cms
{
/// <summary>The RecipientInfo class for a recipient who has been sent a message encrypted using a password.</summary>
/// <summary>CMS recipient information for a recipient that recovers content using a password-derived key.</summary>
public class PasswordRecipientInformation
: RecipientInformation
{
Expand All @@ -22,12 +22,13 @@ internal PasswordRecipientInformation(PasswordRecipientInfo info, CmsSecureReada
this.rid = new RecipientID();
}

/// <summary>
/// Return the object identifier for the key derivation algorithm, or null if there is none present.
/// </summary>
/// <summary>Gets the key-derivation algorithm, or <c>null</c> when the message does not include one.</summary>
public virtual AlgorithmIdentifier KeyDerivationAlgorithm => m_info.KeyDerivationAlgorithm;

/// <summary>Decrypt the content and return an input stream.</summary>
/// <summary>Decrypts the content using a password-based recipient key.</summary>
/// <param name="key">The password-based recipient key.</param>
/// <returns>A typed stream over the decrypted content.</returns>
/// <exception cref="CmsException">Thrown if the content-encryption key cannot be recovered.</exception>
public override CmsTypedStream GetContentStream(ICipherParameters key)
{
try
Expand Down
22 changes: 16 additions & 6 deletions crypto/src/cms/RecipientId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@

namespace Org.BouncyCastle.Cms
{
/// <summary>
/// Identifies a CMS recipient by issuer and serial number, subject key identifier, or KEK key identifier.
/// </summary>
// TODO[api] sealed
public class RecipientID
: X509CertStoreSelector, IEquatable<RecipientID>
{
private byte[] m_keyIdentifier;

public byte[] KeyIdentifier
{
get { return Arrays.Clone(m_keyIdentifier); }
set { m_keyIdentifier = Arrays.Clone(value); }
}
/// <summary>Gets or sets the recipient key identifier.</summary>
public byte[] KeyIdentifier
{
get { return Arrays.Clone(m_keyIdentifier); }
set { m_keyIdentifier = Arrays.Clone(value); }
}

/// <summary>Determines whether this identifier selects the same recipient as <paramref name="other"/>.
/// </summary>
/// <param name="other">The identifier to compare.</param>
/// <returns><c>true</c> if the identifiers match; otherwise, <c>false</c>.</returns>
public virtual bool Equals(RecipientID other)
{
return other == null ? false
Expand All @@ -27,12 +35,14 @@ public virtual bool Equals(RecipientID other)
&& MatchesIssuer(other);
}

/// <inheritdoc/>
public override bool Equals(object obj) => Equals(obj as RecipientID);

/// <inheritdoc/>
public override int GetHashCode()
{
return Arrays.GetHashCode(m_keyIdentifier)
^ GetHashCodeOfSubjectKeyIdentifier()
^ GetHashCodeOfSubjectKeyIdentifier()
^ Objects.GetHashCode(SerialNumber)
^ Objects.GetHashCode(Issuer);
}
Expand Down
12 changes: 12 additions & 0 deletions crypto/src/cms/RecipientInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

namespace Org.BouncyCastle.Cms
{
/// <summary>
/// Base class for CMS recipient information. Use <see cref="RecipientID"/> to select a recipient, then supply
/// the matching key material to <see cref="GetContentStream(ICipherParameters)"/> or <see cref="GetContent"/>.
/// </summary>
public abstract class RecipientInformation
{
internal RecipientID rid = new RecipientID();
Expand All @@ -31,8 +35,10 @@ internal string GetContentAlgorithmName()
return algorithm.Algorithm.Id;
}

/// <summary>Gets the identifier used to match this recipient.</summary>
public RecipientID RecipientID => rid;

/// <summary>Gets the algorithm identifier used to encrypt or wrap the content-encryption key.</summary>
public AlgorithmIdentifier KeyEncryptionAlgorithmID => keyEncAlg;

/// <summary>Return the object identifier for the key encryption algorithm.</summary>
Expand All @@ -57,6 +63,9 @@ internal CmsTypedStream GetContentFromSessionKey(KeyParameter sKey)
}
}

/// <summary>Decrypts the content using <paramref name="key"/> and returns all of its bytes.</summary>
/// <param name="key">The recipient key material needed to recover the content-encryption key.</param>
/// <returns>The decrypted or authenticated content.</returns>
public byte[] GetContent(ICipherParameters key)
{
try
Expand Down Expand Up @@ -87,6 +96,9 @@ public byte[] GetMac()
return Arrays.Clone(resultMac);
}

/// <summary>Returns a stream that exposes the recovered content.</summary>
/// <param name="key">The recipient key material needed to recover the content-encryption key.</param>
/// <returns>A typed stream over the recovered content.</returns>
public abstract CmsTypedStream GetContentStream(ICipherParameters key);
}
}