Skip to content

Commit fbf53d6

Browse files
authored
Correctly support P256_SHA256, P384_SHA348, P521_SHA512 when using BouncyCastle (#139)
Motivation: We not really supported P256_SHA256, P384_SHA348, P521_SHA512 correctly when using BouncyCastle as we missed some implementation for the AsymmentricKeyParameter and also did not correctly support generating a random key pair Modifications: - Add missing implementation - Adjust unit tests to also tests these KEMs when supported by the provider implementation Result: Correctly support P256_SHA256, P384_SHA348, P521_SHA512 when using BouncyCastle
1 parent d7ad22e commit fbf53d6

3 files changed

Lines changed: 37 additions & 1 deletion

File tree

codec-ohttp-hpke-bouncycastle/src/main/java/io/netty/incubator/codec/hpke/bouncycastle/BouncyCastleAsymmetricKeyParameter.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package io.netty.incubator.codec.hpke.bouncycastle;
1717

1818
import io.netty.incubator.codec.hpke.AsymmetricKeyParameter;
19+
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
20+
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
1921
import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
2022
import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
2123
import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
@@ -42,12 +44,31 @@ public byte[] encoded() throws UnsupportedOperationException {
4244
if (param instanceof X448PublicKeyParameters) {
4345
return ((X448PublicKeyParameters) param).getEncoded();
4446
}
47+
if (param instanceof ECPublicKeyParameters) {
48+
return ((ECPublicKeyParameters) param).getQ().getEncoded(false);
49+
}
4550
if (param instanceof X25519PrivateKeyParameters) {
4651
return ((X25519PrivateKeyParameters) param).getEncoded();
4752
}
4853
if (param instanceof X448PrivateKeyParameters) {
4954
return ((X448PrivateKeyParameters) param).getEncoded();
5055
}
56+
if (param instanceof ECPrivateKeyParameters) {
57+
ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) param;
58+
byte[] rawD = privateKey.getD().toByteArray();
59+
// Removing any extra leading 0x00 signs from BigInteger if needed.
60+
switch (rawD.length) {
61+
case 33: // P256_SHA256
62+
case 49: // P384_SHA348
63+
case 65: // P521_SHA512
64+
if (rawD[0] == 0) {
65+
return java.util.Arrays.copyOfRange(rawD, 1, rawD.length);
66+
}
67+
// fall-through
68+
default:
69+
return rawD;
70+
}
71+
}
5172
return null;
5273
}
5374
}

codec-ohttp-hpke-bouncycastle/src/main/java/io/netty/incubator/codec/hpke/bouncycastle/BouncyCastleOHttpCryptoProvider.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import io.netty.incubator.codec.hpke.KEM;
2626
import io.netty.incubator.codec.hpke.OHttpCryptoProvider;
2727
import org.bouncycastle.asn1.nist.NISTNamedCurves;
28+
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
2829
import org.bouncycastle.crypto.params.ECDomainParameters;
30+
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
2931
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
3032
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
3133
import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
@@ -177,6 +179,19 @@ private static org.bouncycastle.crypto.AsymmetricCipherKeyPair newRandomPair(KEM
177179
X448PrivateKeyParameters x448PrivateKey = new X448PrivateKeyParameters(random);
178180
return new org.bouncycastle.crypto.AsymmetricCipherKeyPair(
179181
x448PrivateKey.generatePublicKey(), x448PrivateKey);
182+
case P256_SHA256:
183+
case P384_SHA348:
184+
case P521_SHA512:
185+
ECDomainParameters parameters = ecDomainParameters(kem);
186+
187+
// Initialize Key Generator
188+
ECKeyGenerationParameters keyParams = new ECKeyGenerationParameters(parameters, random);
189+
190+
ECKeyPairGenerator generator = new ECKeyPairGenerator();
191+
generator.init(keyParams);
192+
193+
// Generate the key pair
194+
return generator.generateKeyPair();
180195
default:
181196
throw new UnsupportedOperationException("Can't generate random key for kem: " + kem);
182197
}

codec-ohttp/src/test/java/io/netty/incubator/codec/ohttp/OHttpCodecsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
8484
List<Arguments> arguments = new ArrayList<>();
8585
for (int i = 0; i < 2; i++) {
8686
boolean trailers = i == 0;
87-
for (KEM kem: new KEM[] { KEM.X25519_SHA256, KEM.XWING }) {
87+
for (KEM kem: KEM.values()) {
8888
arguments.add(Arguments.of(
8989
OHttpVersionDraft.INSTANCE, BouncyCastleOHttpCryptoProvider.INSTANCE,
9090
BouncyCastleOHttpCryptoProvider.INSTANCE, kem, trailers));

0 commit comments

Comments
 (0)