Skip to content

Commit 108fcf5

Browse files
committed
updated KEMRecipientInfo to RFC 9629
1 parent 9c96f9a commit 108fcf5

File tree

2 files changed

+138
-2
lines changed

2 files changed

+138
-2
lines changed

util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@
1212
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
1313

1414
/**
15+
* <p>
16+
* Defined in <a href="https://datatracker.ietf.org/doc/rfc9629/">RFC 9629</a>.
17+
* </p>
18+
* <pre>
1519
* KEMRecipientInfo ::= SEQUENCE {
1620
* version CMSVersion, -- always set to 0
1721
* rid RecipientIdentifier,
1822
* kem KEMAlgorithmIdentifier,
1923
* kemct OCTET STRING,
2024
* kdf KeyDerivationAlgorithmIdentifier,
21-
* kekLength INTEGER (1..MAX),
25+
* kekLength INTEGER (1..65535),
2226
* ukm [0] EXPLICIT UserKeyingMaterial OPTIONAL,
2327
* wrap KeyEncryptionAlgorithmIdentifier,
2428
* encryptedKey EncryptedKey }
29+
* </pre>
2530
*/
2631
public class KEMRecipientInfo
2732
extends ASN1Object
@@ -47,6 +52,10 @@ public KEMRecipientInfo(RecipientIdentifier rid, AlgorithmIdentifier kem, ASN1Oc
4752
{
4853
throw new NullPointerException("wrap cannot be null");
4954
}
55+
if (kekLength.intValueExact() > 65535)
56+
{
57+
throw new IllegalArgumentException("kekLength must be <= 65535");
58+
}
5059
this.cmsVersion = new ASN1Integer(0);
5160
this.rid = rid;
5261
this.kem = kem;
@@ -76,7 +85,7 @@ private KEMRecipientInfo(ASN1Sequence seq)
7685
{
7786
if (seq.size() < 8 || seq.size() > 9)
7887
{
79-
throw new IllegalArgumentException("Bad sequence size: " + seq.size());
88+
throw new IllegalArgumentException("bad sequence size: " + seq.size());
8089
}
8190

8291
cmsVersion = ASN1Integer.getInstance(seq.getObjectAt(0));
@@ -86,6 +95,11 @@ private KEMRecipientInfo(ASN1Sequence seq)
8695
kdf = AlgorithmIdentifier.getInstance(seq.getObjectAt(4));
8796
kekLength = ASN1Integer.getInstance(seq.getObjectAt(5));
8897

98+
if (kekLength.intValueExact() > 65535)
99+
{
100+
throw new IllegalArgumentException("kekLength must be <= 65535");
101+
}
102+
89103
int elt = 6;
90104
if (seq.getObjectAt(6) instanceof ASN1TaggedObject)
91105
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package org.bouncycastle.asn1.cms.test;
2+
3+
import junit.framework.TestCase;
4+
import org.bouncycastle.asn1.ASN1Encodable;
5+
import org.bouncycastle.asn1.ASN1Integer;
6+
import org.bouncycastle.asn1.ASN1Primitive;
7+
import org.bouncycastle.asn1.DEROctetString;
8+
import org.bouncycastle.asn1.DERSequence;
9+
import org.bouncycastle.asn1.cms.KEMRecipientInfo;
10+
import org.bouncycastle.asn1.cms.RecipientIdentifier;
11+
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
12+
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
13+
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
14+
import org.bouncycastle.util.encoders.Base64;
15+
16+
public class KEMRecipientInfoTest
17+
extends TestCase
18+
{
19+
private static byte[] outOfRangeEnc = Base64.decode("MDoCAQCAADALBglghkgBZQMEBAEEADAMBgorgQUQhkgJLAECAgMKrmCgAgQAMAsGCWCGSAFlAwQBMAQA");
20+
21+
public void testOutOfRange()
22+
throws Exception
23+
{
24+
try
25+
{
26+
new KEMRecipientInfo(
27+
new RecipientIdentifier(new DEROctetString(new byte[0])),
28+
new AlgorithmIdentifier(NISTObjectIdentifiers.id_alg_ml_kem_512),
29+
new DEROctetString(new byte[0]),
30+
new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3),
31+
new ASN1Integer(700000), new DEROctetString(new byte[0]),
32+
new AlgorithmIdentifier(NISTObjectIdentifiers.id_aes256_wrap_pad),
33+
new DEROctetString(new byte[0]));
34+
fail("no exception");
35+
}
36+
catch (IllegalArgumentException e)
37+
{
38+
assertEquals("kekLength must be <= 65535", e.getMessage());
39+
}
40+
41+
try
42+
{
43+
KEMRecipientInfo.getInstance(ASN1Primitive.fromByteArray(outOfRangeEnc));
44+
fail("no exception");
45+
}
46+
catch (IllegalArgumentException e)
47+
{
48+
assertEquals("kekLength must be <= 65535", e.getMessage());
49+
}
50+
}
51+
52+
public void testNullWrap()
53+
throws Exception
54+
{
55+
try
56+
{
57+
new KEMRecipientInfo(
58+
new RecipientIdentifier(new DEROctetString(new byte[0])),
59+
new AlgorithmIdentifier(NISTObjectIdentifiers.id_alg_ml_kem_512),
60+
new DEROctetString(new byte[0]),
61+
new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3),
62+
new ASN1Integer(7000), new DEROctetString(new byte[0]),
63+
null,
64+
new DEROctetString(new byte[0]));
65+
fail("no exception");
66+
}
67+
catch (NullPointerException e)
68+
{
69+
assertEquals("wrap cannot be null", e.getMessage());
70+
}
71+
}
72+
73+
public void testNullKem()
74+
throws Exception
75+
{
76+
try
77+
{
78+
new KEMRecipientInfo(
79+
new RecipientIdentifier(new DEROctetString(new byte[0])),
80+
null,
81+
new DEROctetString(new byte[0]),
82+
new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3),
83+
new ASN1Integer(7000), new DEROctetString(new byte[0]),
84+
new AlgorithmIdentifier(NISTObjectIdentifiers.id_aes256_wrap_pad),
85+
new DEROctetString(new byte[0]));
86+
fail("no exception");
87+
}
88+
catch (NullPointerException e)
89+
{
90+
assertEquals("kem cannot be null", e.getMessage());
91+
}
92+
}
93+
94+
public void testSequenceSize()
95+
throws Exception
96+
{
97+
try
98+
{
99+
KEMRecipientInfo.getInstance(new DERSequence(new RecipientIdentifier(new DEROctetString(new byte[0]))));
100+
fail("no exception");
101+
}
102+
catch (IllegalArgumentException e)
103+
{
104+
assertEquals("bad sequence size: 1", e.getMessage());
105+
}
106+
107+
try
108+
{
109+
ASN1Encodable[] elements = new ASN1Encodable[10];
110+
for (int i = 0; i != elements.length; i++)
111+
{
112+
elements[i] = new ASN1Integer(1);
113+
}
114+
KEMRecipientInfo.getInstance(new DERSequence(elements));
115+
fail("no exception");
116+
}
117+
catch (IllegalArgumentException e)
118+
{
119+
assertEquals("bad sequence size: 10", e.getMessage());
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)