Skip to content

Commit 335c42d

Browse files
committed
Other providers GCM fix
1 parent eb0a6e3 commit 335c42d

File tree

3 files changed

+111
-2
lines changed

3 files changed

+111
-2
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package org.bouncycastle.tls.crypto.impl.jcajce;
2+
3+
import java.lang.reflect.Constructor;
4+
import java.security.AccessController;
5+
import java.security.PrivilegedAction;
6+
import java.security.spec.AlgorithmParameterSpec;
7+
import java.security.spec.InvalidParameterSpecException;
8+
9+
import org.bouncycastle.util.Integers;
10+
11+
class GcmSpecUtil
12+
{
13+
static final Class gcmSpecClass = lookup("javax.crypto.spec.GCMParameterSpec");
14+
15+
static boolean gcmSpecExists()
16+
{
17+
return gcmSpecClass != null;
18+
}
19+
20+
static AlgorithmParameterSpec createGcmSpec(final byte[] nonce, final int macLen)
21+
throws InvalidParameterSpecException
22+
{
23+
Object rv = AccessController.doPrivileged(new PrivilegedAction<Object>()
24+
{
25+
public Object run()
26+
{
27+
try
28+
{
29+
Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
30+
31+
return constructor.newInstance(new Object[]{Integers.valueOf(macLen * 8), nonce});
32+
}
33+
catch (NoSuchMethodException e)
34+
{
35+
return new InvalidParameterSpecException("no constructor found!"); // should never happen
36+
}
37+
catch (Exception e)
38+
{
39+
return new InvalidParameterSpecException("construction failed: " + e.getMessage()); // should never happen
40+
}
41+
}
42+
});
43+
if (rv instanceof AlgorithmParameterSpec)
44+
{
45+
return (AlgorithmParameterSpec)rv;
46+
}
47+
else
48+
{
49+
throw (InvalidParameterSpecException)rv;
50+
}
51+
}
52+
53+
static Class lookup(final String className)
54+
{
55+
return AccessController.doPrivileged(new PrivilegedAction<Class>()
56+
{
57+
public Class run()
58+
{
59+
try
60+
{
61+
ClassLoader loader = GcmSpecUtil.class.getClassLoader();
62+
if (loader == null)
63+
{
64+
loader = ClassLoader.getSystemClassLoader();
65+
}
66+
67+
return loader.loadClass(className);
68+
}
69+
catch (Exception e)
70+
{
71+
return null;
72+
}
73+
}
74+
});
75+
}
76+
}

tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,16 @@ public void init(byte[] nonce, int macSize, byte[] additionalData)
9595
{
9696
AlgorithmParameters algParams = helper.createAlgorithmParameters(algorithmParamsName);
9797

98-
// fortunately CCM and GCM parameters have the same ASN.1 structure
99-
algParams.init(new GCMParameters(nonce, macSize).getEncoded());
98+
// believe it or not but there are things out there that do not support the ASN.1 encoding...
99+
if (GcmSpecUtil.gcmSpecExists())
100+
{
101+
algParams.init(GcmSpecUtil.createGcmSpec(nonce, macSize));
102+
}
103+
else
104+
{
105+
// fortunately CCM and GCM parameters have the same ASN.1 structure
106+
algParams.init(new GCMParameters(nonce, macSize).getEncoded());
107+
}
100108

101109
cipher.init(cipherMode, key, algParams, null);
102110

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.bouncycastle.tls.crypto.impl.jcajce;
2+
3+
import java.lang.reflect.Constructor;
4+
import java.security.AccessController;
5+
import java.security.PrivilegedAction;
6+
import java.security.spec.AlgorithmParameterSpec;
7+
import java.security.spec.InvalidParameterSpecException;
8+
9+
import javax.crypto.spec.GCMParameterSpec;
10+
11+
import org.bouncycastle.util.Integers;
12+
13+
class GcmSpecUtil
14+
{
15+
static boolean gcmSpecExists()
16+
{
17+
return true;
18+
}
19+
20+
static AlgorithmParameterSpec createGcmSpec(byte[] nonce, int macLen)
21+
throws InvalidParameterSpecException
22+
{
23+
return new GCMParameterSpec(macLen * 8, nonce);
24+
}
25+
}

0 commit comments

Comments
 (0)