Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add auth enveloped recipients for KEK and KeyAgree #1794

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
78 changes: 78 additions & 0 deletions pkix/src/main/java/org/bouncycastle/cms/CMSInputAEADDecryptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.bouncycastle.cms;

import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cms.jcajce.JceKEKAuthEnvelopedRecipient;
import org.bouncycastle.jcajce.io.CipherInputStream;
import org.bouncycastle.operator.InputAEADDecryptor;

import javax.crypto.Cipher;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class CMSInputAEADDecryptor
implements InputAEADDecryptor
{
final AlgorithmIdentifier contentEncryptionAlgorithm;

final Cipher dataCipher;

private InputStream inputStream;

public CMSInputAEADDecryptor(AlgorithmIdentifier contentEncryptionAlgorithm, Cipher dataCipher)
{
this.contentEncryptionAlgorithm = contentEncryptionAlgorithm;
this.dataCipher = dataCipher;
}

public AlgorithmIdentifier getAlgorithmIdentifier()
{
return contentEncryptionAlgorithm;
}

public InputStream getInputStream(InputStream dataIn)
{
inputStream = dataIn;
return new CipherInputStream(dataIn, dataCipher);
}

public OutputStream getAADStream()
{
return new AADStream(dataCipher);
}

public byte[] getMAC()
{
if (inputStream instanceof InputStreamWithMAC)
{
return ((InputStreamWithMAC)inputStream).getMAC();
}
return null;
}

private static class AADStream
extends OutputStream
{
private Cipher cipher;
private byte[] oneByte = new byte[1];

public AADStream(Cipher cipher)
{
this.cipher = cipher;
}

public void write(byte[] buf, int off, int len)
throws IOException
{
cipher.updateAAD(buf, off, len);
}

public void write(int b)
throws IOException
{
oneByte[0] = (byte)b;

cipher.updateAAD(oneByte);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.bouncycastle.cms.jcajce;

import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSInputAEADDecryptor;
import org.bouncycastle.cms.RecipientOperator;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import java.security.Key;

public class JceKEKAuthEnvelopedRecipient
extends JceKEKRecipient
{
public JceKEKAuthEnvelopedRecipient(SecretKey recipientKey)
{
super(recipientKey);
}

public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey)
throws CMSException
{
Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey);

final Cipher dataCipher = contentHelper.createContentCipher(secretKey, contentEncryptionAlgorithm);

return new RecipientOperator(new CMSInputAEADDecryptor(contentEncryptionAlgorithm, dataCipher));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.bouncycastle.cms.jcajce;

import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSInputAEADDecryptor;
import org.bouncycastle.cms.RecipientOperator;

import javax.crypto.Cipher;
import java.security.Key;
import java.security.PrivateKey;

public class JceKeyAgreeAuthEnvelopedRecipient
extends JceKeyAgreeRecipient
{
public JceKeyAgreeAuthEnvelopedRecipient(PrivateKey recipientKey)
{
super(recipientKey);
}

public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, SubjectPublicKeyInfo senderPublicKey, ASN1OctetString userKeyingMaterial, byte[] encryptedContentKey)
throws CMSException
{
Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, senderPublicKey, userKeyingMaterial, encryptedContentKey);

final Cipher dataCipher = contentHelper.createContentCipher(secretKey, contentEncryptionAlgorithm);

return new RecipientOperator(new CMSInputAEADDecryptor(contentEncryptionAlgorithm, dataCipher));
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package org.bouncycastle.cms.jcajce;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.PrivateKey;

import javax.crypto.Cipher;

import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.InputStreamWithMAC;
import org.bouncycastle.cms.CMSInputAEADDecryptor;
import org.bouncycastle.cms.RecipientOperator;
import org.bouncycastle.jcajce.io.CipherInputStream;
import org.bouncycastle.operator.InputAEADDecryptor;

public class JceKeyTransAuthEnvelopedRecipient
extends JceKeyTransRecipient
Expand All @@ -30,60 +25,6 @@ public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionA

final Cipher dataCipher = contentHelper.createContentCipher(secretKey, contentEncryptionAlgorithm);

return new RecipientOperator(new InputAEADDecryptor()
{
private InputStream inputStream;

public AlgorithmIdentifier getAlgorithmIdentifier()
{
return contentEncryptionAlgorithm;
}

public InputStream getInputStream(InputStream dataIn)
{
inputStream = dataIn;
return new CipherInputStream(dataIn, dataCipher);
}

public OutputStream getAADStream()
{
return new AADStream(dataCipher);
}

public byte[] getMAC()
{
if (inputStream instanceof InputStreamWithMAC)
{
return ((InputStreamWithMAC)inputStream).getMAC();
}
return null;
}
});
}

private static class AADStream
extends OutputStream
{
private Cipher cipher;
private byte[] oneByte = new byte[1];

public AADStream(Cipher cipher)
{
this.cipher = cipher;
}

public void write(byte[] buf, int off, int len)
throws IOException
{
cipher.updateAAD(buf, off, len);
}

public void write(int b)
throws IOException
{
oneByte[0] = (byte)b;

cipher.updateAAD(oneByte);
}
return new RecipientOperator(new CMSInputAEADDecryptor(contentEncryptionAlgorithm, dataCipher));
}
}
1 change: 1 addition & 0 deletions pkix/src/test/java/org/bouncycastle/cms/test/AllTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public static Test suite()
suite.addTest(NewAuthenticatedDataStreamTest.suite());
suite.addTest(NewCompressedDataStreamTest.suite());
suite.addTest(NewSignedDataStreamTest.suite());
suite.addTest(NewAuthEnvelopedDataStreamTest.suite());
suite.addTest(NewEnvelopedDataStreamTest.suite());
suite.addTest(AuthEnvelopedDataTest.suite());

Expand Down
Loading