Skip to content

Commit

Permalink
fix: fixing the problem: invalid length of ec key attributes (length …
Browse files Browse the repository at this point in the history
…> 32): issue oxauth.#1595;
  • Loading branch information
smansoft committed Dec 18, 2021
1 parent 33a96cf commit 0f95913
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ public JSONObject generateKey(Algorithm algorithm, Long expirationTime, Use use,
} else if (publicKey instanceof ECPublicKey) {
ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
jsonObject.put(CURVE, signatureAlgorithm.getCurve().getName());
jsonObject.put(X, Base64Util.base64urlencode(ecPublicKey.getW().getAffineX().toByteArray()));
jsonObject.put(Y, Base64Util.base64urlencode(ecPublicKey.getW().getAffineY().toByteArray()));
jsonObject.put(X, Base64Util.base64urlencodeUnsignedBigInt(ecPublicKey.getW().getAffineX()));
jsonObject.put(Y, Base64Util.base64urlencodeUnsignedBigInt(ecPublicKey.getW().getAffineY()));
}
JSONArray x5c = new JSONArray();
x5c.put(Base64.encodeBase64String(cert.getEncoded()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
@Deprecated
public class RSAKeyFactory extends KeyFactory<RSAPrivateKey, RSAPublicKey> {

public static final int DEF_KEYLENGTH = 2048;

private RSAPrivateKey rsaPrivateKey;
private RSAPublicKey rsaPublicKey;
private Certificate certificate;
Expand All @@ -45,7 +47,7 @@ public RSAKeyFactory(SignatureAlgorithm signatureAlgorithm, String dnName)
}

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");
keyGen.initialize(2048, new SecureRandom());
keyGen.initialize(DEF_KEYLENGTH, new SecureRandom());

KeyPair keyPair = keyGen.generateKeyPair();

Expand Down
35 changes: 22 additions & 13 deletions Model/src/main/java/org/gluu/oxauth/model/jwk/Algorithm.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.fasterxml.jackson.annotation.JsonValue;
import org.gluu.oxauth.model.crypto.signature.AlgorithmFamily;
import org.gluu.oxauth.model.util.StringUtils;
import org.gluu.oxauth.model.crypto.signature.RSAKeyFactory;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -18,33 +19,37 @@
* Identifies the cryptographic algorithm used with the key.
*
* @author Javier Rojas Blum
* @version February 12, 2019
* @author Sergey Manoylo
* @version December 17, 2021
*/
@SuppressWarnings("java:S1874")
public enum Algorithm {

// Signature
RS256("RS256", Use.SIGNATURE, AlgorithmFamily.RSA),
RS384("RS384", Use.SIGNATURE, AlgorithmFamily.RSA),
RS512("RS512", Use.SIGNATURE, AlgorithmFamily.RSA),
ES256("ES256", Use.SIGNATURE, AlgorithmFamily.EC),
ES384("ES384", Use.SIGNATURE, AlgorithmFamily.EC),
ES512("ES512", Use.SIGNATURE, AlgorithmFamily.EC),
PS256("PS256", Use.SIGNATURE, AlgorithmFamily.RSA),
PS384("PS384", Use.SIGNATURE, AlgorithmFamily.RSA),
PS512("PS512", Use.SIGNATURE, AlgorithmFamily.RSA),
RS256("RS256", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),
RS384("RS384", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),
RS512("RS512", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),
ES256("ES256", Use.SIGNATURE, AlgorithmFamily.EC, 256),
ES384("ES384", Use.SIGNATURE, AlgorithmFamily.EC, 384),
ES512("ES512", Use.SIGNATURE, AlgorithmFamily.EC, 528),
PS256("PS256", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),
PS384("PS384", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),
PS512("PS512", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),

// Encryption
RSA1_5("RSA1_5", Use.ENCRYPTION, AlgorithmFamily.RSA),
RSA_OAEP("RSA-OAEP", Use.ENCRYPTION, AlgorithmFamily.RSA);
RSA1_5("RSA1_5", Use.ENCRYPTION, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),
RSA_OAEP("RSA-OAEP", Use.ENCRYPTION, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH);

private final String paramName;
private final Use use;
private final AlgorithmFamily family;
private final int keyLength;

Algorithm(String paramName, Use use, AlgorithmFamily family) {
Algorithm(String paramName, Use use, AlgorithmFamily family, int keyLength) {
this.paramName = paramName;
this.use = use;
this.family = family;
this.keyLength = keyLength; // bits
}

public String getParamName() {
Expand All @@ -59,6 +64,10 @@ public AlgorithmFamily getFamily() {
return family;
}

public int getKeyLength() {
return keyLength;
}

/**
* Returns the corresponding {@link Algorithm} for a parameter.
*
Expand Down
32 changes: 22 additions & 10 deletions Model/src/main/java/org/gluu/oxauth/model/util/Base64Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

/**
* @author Javier Rojas Blum
* @version July 31, 2016
* @author Sergey Manoylo
* @version December 17, 2021
*/
public class Base64Util {

Expand Down Expand Up @@ -58,15 +59,8 @@ public static String removePadding(String base64UrlEncoded) {
return s;
}

public static String base64urlencodeUnsignedBigInt(BigInteger bigInteger) {
byte[] array = bigInteger.toByteArray();
if (array[0] == 0) {
byte[] tmp = new byte[array.length - 1];
System.arraycopy(array, 1, tmp, 0, tmp.length);
array = tmp;
}

return Base64Util.base64urlencode(array);
public static String base64urlencodeUnsignedBigInt(final BigInteger bigInteger) {
return Base64Util.base64urlencode(bigIntegerToUnsignedByteArray(bigInteger));
}

public static byte[] unsignedToBytes(int[] plaintextUnsignedBytes) {
Expand All @@ -78,4 +72,22 @@ public static byte[] unsignedToBytes(int[] plaintextUnsignedBytes) {

return bytes;
}

public static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte aByte : bytes) {
result.append(String.format("%02x", aByte));
}
return result.toString();
}

public static byte[] bigIntegerToUnsignedByteArray(final BigInteger bigInteger) {
byte[] array = bigInteger.toByteArray();
if (array[0] == 0) {
byte[] tmp = new byte[array.length - 1];
System.arraycopy(array, 1, tmp, 0, tmp.length);
array = tmp;
}
return array;
}
}
82 changes: 78 additions & 4 deletions Server/src/test/java/org/gluu/oxauth/comp/CryptoProviderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
import org.gluu.oxauth.model.config.ConfigurationFactory;
import org.gluu.oxauth.model.configuration.AppConfiguration;
import org.gluu.oxauth.model.crypto.AbstractCryptoProvider;
import org.gluu.oxauth.model.crypto.CryptoProviderFactory;
import org.gluu.oxauth.model.crypto.signature.SignatureAlgorithm;
import org.gluu.oxauth.model.jwk.Algorithm;
import org.gluu.oxauth.model.jwk.JWKParameter;
import org.gluu.oxauth.model.util.Base64Util;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import javax.inject.Inject;

import java.security.interfaces.ECPrivateKey;
import java.util.GregorianCalendar;
import java.util.TimeZone;

Expand All @@ -25,7 +29,8 @@

/**
* @author Javier Rojas Blum
* @version February 12, 2019
* @author Sergey Manoylo
* @version December 17, 2021
*/
public class CryptoProviderTest extends ConfigurableTest {

Expand All @@ -35,8 +40,12 @@ public class CryptoProviderTest extends ConfigurableTest {
@Inject
private AbstractCryptoProvider cryptoProvider;

private final String SIGNING_INPUT = "Signing Input";
private final String SHARED_SECRET = "secret";
private final static int NUM_KEY_GENS = 100;

private final static byte testByte01 = (byte)0x01;

private final static String SIGNING_INPUT = "Signing Input";
private final static String SHARED_SECRET = "secret";

private static Long expirationTime;
private static String hs256Signature;
Expand Down Expand Up @@ -373,4 +382,69 @@ public void testDeleteKeyES512() {
fail(e.getMessage(), e);
}
}

@DataProvider(name = "GenerateKeysDataProvider")
public Object[][] testGenerateKeysDataProvider() {
return new Object[][] {
{ Algorithm.ES256 },
{ Algorithm.ES384 },
{ Algorithm.ES512 },
};
}

@Test(dependsOnMethods = {"testDeleteKeyRS256", "testDeleteKeyRS384", "testDeleteKeyRS512",
"testDeleteKeyES256", "testDeleteKeyES384", "testDeleteKeyES512" },
dataProvider = "GenerateKeysDataProvider")
public void testGenerateKeys(Algorithm algorithm) {
for(int i = 0; i < NUM_KEY_GENS; i++) {
System.out.println("----------------------");
System.out.println("Algorithm: " + algorithm);
try {
JSONObject response = cryptoProvider.generateKey(algorithm, expirationTime);
String keyId = response.optString(JWKParameter.KEY_ID);
ECPrivateKey ecPrivateKey = (ECPrivateKey)cryptoProvider.getPrivateKey(keyId);
cryptoProvider.deleteKey(response.optString(keyId));

byte[] s = Base64Util.bigIntegerToUnsignedByteArray(ecPrivateKey.getS());

System.out.println("s.length = " + s.length);
System.out.println("s (hex) = " + Base64Util.bytesToHex(s));

String keyX = (String)response.get(JWKParameter.X);
String keyY = (String)response.get(JWKParameter.Y);

System.out.println("keyX = " + keyX);
System.out.println("keyY = " + keyY);

byte[] x = Base64Util.base64urldecode(keyX);
byte[] y = Base64Util.base64urldecode(keyY);

System.out.println("x.length = " + x.length);
System.out.println("y.length = " + y.length);

System.out.println("x (hex) = " + Base64Util.bytesToHex(x));
System.out.println("y (hex) = " + Base64Util.bytesToHex(y));

assertTrue(s.length <= algorithm.getKeyLength());
assertTrue(x.length <= algorithm.getKeyLength());
assertTrue(y.length <= algorithm.getKeyLength());

if(algorithm == Algorithm.ES512) {
if(s.length * 8 == algorithm.getKeyLength()) {
assertEquals(s[0], testByte01);
}
if(x.length * 8 == algorithm.getKeyLength()) {
assertEquals(x[0], testByte01);
}
if(y.length * 8 == algorithm.getKeyLength()) {
assertEquals(y[0], testByte01);
}
}

} catch (Exception e) {
fail(e.getMessage(), e);
}
System.out.println("----------------------");
}
}
}

0 comments on commit 0f95913

Please sign in to comment.