Skip to content

Commit aa78c04

Browse files
committed
Refactor DHKEKGenerator ASN.1 classes
1 parent b506184 commit aa78c04

3 files changed

Lines changed: 114 additions & 80 deletions

File tree

core/src/main/java/org/bouncycastle/asn1/x9/KeySpecificInfo.java

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package org.bouncycastle.asn1.x9;
22

3-
import java.util.Enumeration;
4-
53
import org.bouncycastle.asn1.ASN1Object;
64
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
75
import org.bouncycastle.asn1.ASN1OctetString;
86
import org.bouncycastle.asn1.ASN1Primitive;
97
import org.bouncycastle.asn1.ASN1Sequence;
8+
import org.bouncycastle.asn1.ASN1TaggedObject;
109
import org.bouncycastle.asn1.DERSequence;
1110

1211
/**
@@ -22,23 +21,6 @@
2221
public class KeySpecificInfo
2322
extends ASN1Object
2423
{
25-
private ASN1ObjectIdentifier algorithm;
26-
private ASN1OctetString counter;
27-
28-
/**
29-
* Base constructor.
30-
*
31-
* @param algorithm algorithm identifier for the CEK.
32-
* @param counter initial counter value for key derivation.
33-
*/
34-
public KeySpecificInfo(
35-
ASN1ObjectIdentifier algorithm,
36-
ASN1OctetString counter)
37-
{
38-
this.algorithm = algorithm;
39-
this.counter = counter;
40-
}
41-
4224
/**
4325
* Return a KeySpecificInfo object from the passed in object.
4426
*
@@ -59,13 +41,50 @@ else if (obj != null)
5941
return null;
6042
}
6143

62-
private KeySpecificInfo(
63-
ASN1Sequence seq)
44+
public static KeySpecificInfo getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
45+
{
46+
return new KeySpecificInfo(ASN1Sequence.getInstance(taggedObject, declaredExplicit));
47+
}
48+
49+
public static KeySpecificInfo getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit)
50+
{
51+
return new KeySpecificInfo(ASN1Sequence.getTagged(taggedObject, declaredExplicit));
52+
}
53+
54+
private final ASN1ObjectIdentifier algorithm;
55+
private final ASN1OctetString counter;
56+
57+
private KeySpecificInfo(ASN1Sequence seq)
6458
{
65-
Enumeration e = seq.getObjects();
59+
int count = seq.size();
60+
if (count != 2)
61+
{
62+
throw new IllegalArgumentException("Bad sequence size: " + count);
63+
}
64+
65+
this.algorithm = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
66+
this.counter = ASN1OctetString.getInstance(seq.getObjectAt(1));
67+
}
6668

67-
algorithm = (ASN1ObjectIdentifier)e.nextElement();
68-
counter = (ASN1OctetString)e.nextElement();
69+
/**
70+
* Base constructor.
71+
*
72+
* @param algorithm algorithm identifier for the CEK.
73+
* @param counter initial counter value for key derivation.
74+
*/
75+
public KeySpecificInfo(ASN1ObjectIdentifier algorithm, ASN1OctetString counter)
76+
{
77+
if (algorithm == null)
78+
{
79+
throw new NullPointerException("'algorithm' cannot be null");
80+
}
81+
if (counter == null)
82+
{
83+
throw new NullPointerException("'counter' cannot be null");
84+
}
85+
86+
this.algorithm = algorithm;
87+
this.counter = counter;
6988
}
7089

7190
/**

core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.bouncycastle.asn1.x9;
22

3-
import java.util.Enumeration;
4-
53
import org.bouncycastle.asn1.ASN1EncodableVector;
64
import org.bouncycastle.asn1.ASN1Object;
75
import org.bouncycastle.asn1.ASN1OctetString;
@@ -25,20 +23,6 @@
2523
public class OtherInfo
2624
extends ASN1Object
2725
{
28-
private KeySpecificInfo keyInfo;
29-
private ASN1OctetString partyAInfo;
30-
private ASN1OctetString suppPubInfo;
31-
32-
public OtherInfo(
33-
KeySpecificInfo keyInfo,
34-
ASN1OctetString partyAInfo,
35-
ASN1OctetString suppPubInfo)
36-
{
37-
this.keyInfo = keyInfo;
38-
this.partyAInfo = partyAInfo;
39-
this.suppPubInfo = suppPubInfo;
40-
}
41-
4226
/**
4327
* Return a OtherInfo object from the passed in object.
4428
*
@@ -59,26 +43,66 @@ else if (obj != null)
5943
return null;
6044
}
6145

62-
private OtherInfo(
63-
ASN1Sequence seq)
46+
public static OtherInfo getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
6447
{
65-
Enumeration e = seq.getObjects();
48+
return new OtherInfo(ASN1Sequence.getInstance(taggedObject, declaredExplicit));
49+
}
6650

67-
keyInfo = KeySpecificInfo.getInstance(e.nextElement());
51+
public static OtherInfo getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit)
52+
{
53+
return new OtherInfo(ASN1Sequence.getTagged(taggedObject, declaredExplicit));
54+
}
55+
56+
private final KeySpecificInfo keyInfo;
57+
private final ASN1OctetString partyAInfo;
58+
private final ASN1OctetString suppPubInfo;
6859

69-
while (e.hasMoreElements())
60+
private OtherInfo(ASN1Sequence seq)
61+
{
62+
int count = seq.size(), pos = 0;
63+
if (count < 2 || count > 3)
7064
{
71-
ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement();
65+
throw new IllegalArgumentException("Bad sequence size: " + count);
66+
}
7267

73-
if (o.hasContextTag(0))
74-
{
75-
partyAInfo = (ASN1OctetString)o.getExplicitBaseObject();
76-
}
77-
else if (o.hasContextTag(2))
68+
this.keyInfo = KeySpecificInfo.getInstance(seq.getObjectAt(pos++));
69+
70+
// partyAInfo [0] OCTET STRING OPTIONAL
71+
ASN1OctetString partyAInfo = null;
72+
if (pos < count)
73+
{
74+
ASN1TaggedObject tag0 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 0);
75+
if (tag0 != null)
7876
{
79-
suppPubInfo = (ASN1OctetString)o.getExplicitBaseObject();
77+
pos++;
78+
partyAInfo = ASN1OctetString.getTagged(tag0, true);
8079
}
8180
}
81+
this.partyAInfo = partyAInfo;
82+
83+
ASN1TaggedObject tag2 = ASN1TaggedObject.getContextInstance(seq.getObjectAt(pos++), 2);
84+
this.suppPubInfo = ASN1OctetString.getTagged(tag2, true);
85+
86+
if (pos != count)
87+
{
88+
throw new IllegalArgumentException("Unexpected elements in sequence");
89+
}
90+
}
91+
92+
public OtherInfo(KeySpecificInfo keyInfo, ASN1OctetString partyAInfo, ASN1OctetString suppPubInfo)
93+
{
94+
if (keyInfo == null)
95+
{
96+
throw new NullPointerException("'keyInfo' cannot be null");
97+
}
98+
if (suppPubInfo == null)
99+
{
100+
throw new NullPointerException("'suppPubInfo' cannot be null");
101+
}
102+
103+
this.keyInfo = keyInfo;
104+
this.partyAInfo = partyAInfo;
105+
this.suppPubInfo = suppPubInfo;
82106
}
83107

84108
/**

core/src/main/java/org/bouncycastle/crypto/agreement/kdf/DHKEKGenerator.java

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
import java.io.IOException;
44

5-
import org.bouncycastle.asn1.ASN1EncodableVector;
65
import org.bouncycastle.asn1.ASN1Encoding;
76
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
7+
import org.bouncycastle.asn1.ASN1OctetString;
88
import org.bouncycastle.asn1.DEROctetString;
9-
import org.bouncycastle.asn1.DERSequence;
10-
import org.bouncycastle.asn1.DERTaggedObject;
9+
import org.bouncycastle.asn1.x9.KeySpecificInfo;
10+
import org.bouncycastle.asn1.x9.OtherInfo;
1111
import org.bouncycastle.crypto.DataLengthException;
1212
import org.bouncycastle.crypto.DerivationFunction;
1313
import org.bouncycastle.crypto.DerivationParameters;
@@ -26,10 +26,9 @@ public class DHKEKGenerator
2626
private ASN1ObjectIdentifier algorithm;
2727
private int keySize;
2828
private byte[] z;
29-
private byte[] partyAInfo;
29+
private byte[] extraInfo;
3030

31-
public DHKEKGenerator(
32-
Digest digest)
31+
public DHKEKGenerator(Digest digest)
3332
{
3433
this.digest = digest;
3534
}
@@ -41,7 +40,7 @@ public void init(DerivationParameters param)
4140
this.algorithm = params.getAlgorithm();
4241
this.keySize = params.getKeySize();
4342
this.z = params.getZ();
44-
this.partyAInfo = params.getExtraInfo();
43+
this.extraInfo = params.getExtraInfo();
4544
}
4645

4746
public Digest getDigest()
@@ -57,8 +56,10 @@ public int generateBytes(byte[] out, int outOff, int len)
5756
throw new OutputLengthException("output buffer too small");
5857
}
5958

60-
long oBytes = len;
61-
int outLen = digest.getDigestSize();
59+
digest.reset();
60+
61+
long oBytes = len;
62+
int outLen = digest.getDigestSize();
6263

6364
//
6465
// this is at odds with the standard implementation, the
@@ -75,32 +76,24 @@ public int generateBytes(byte[] out, int outOff, int len)
7576

7677
byte[] dig = new byte[digest.getDigestSize()];
7778

78-
int counter = 1;
79+
int counter32 = 1;
7980

8081
for (int i = 0; i < cThreshold; i++)
8182
{
8283
digest.update(z, 0, z.length);
8384

84-
// OtherInfo
85-
ASN1EncodableVector v1 = new ASN1EncodableVector();
8685
// KeySpecificInfo
87-
ASN1EncodableVector v2 = new ASN1EncodableVector();
86+
ASN1OctetString counter = DEROctetString.withContents(Pack.intToBigEndian(counter32));
87+
KeySpecificInfo keyInfo = new KeySpecificInfo(algorithm, counter);
8888

89-
v2.add(algorithm);
90-
v2.add(new DEROctetString(Pack.intToBigEndian(counter)));
91-
92-
v1.add(new DERSequence(v2));
93-
94-
if (partyAInfo != null)
95-
{
96-
v1.add(new DERTaggedObject(true, 0, new DEROctetString(partyAInfo)));
97-
}
98-
99-
v1.add(new DERTaggedObject(true, 2, new DEROctetString(Pack.intToBigEndian(keySize))));
89+
// OtherInfo
90+
ASN1OctetString partyAInfo = DEROctetString.withContentsOptional(extraInfo);
91+
ASN1OctetString suppPubInfo = DEROctetString.withContents(Pack.intToBigEndian(keySize));
92+
OtherInfo otherInfo = new OtherInfo(keyInfo, partyAInfo, suppPubInfo);
10093

10194
try
10295
{
103-
byte[] other = new DERSequence(v1).getEncoded(ASN1Encoding.DER);
96+
byte[] other = otherInfo.getEncoded(ASN1Encoding.DER);
10497

10598
digest.update(other, 0, other.length);
10699
}
@@ -122,11 +115,9 @@ public int generateBytes(byte[] out, int outOff, int len)
122115
System.arraycopy(dig, 0, out, outOff, len);
123116
}
124117

125-
counter++;
118+
counter32++;
126119
}
127120

128-
digest.reset();
129-
130121
return (int)oBytes;
131122
}
132123
}

0 commit comments

Comments
 (0)