diff --git a/GeneXusJWT/src/main/java/com/genexus/JWT/utils/JWTAlgorithm.java b/GeneXusJWT/src/main/java/com/genexus/JWT/utils/JWTAlgorithm.java index 0e5c1f1..0c5a87c 100644 --- a/GeneXusJWT/src/main/java/com/genexus/JWT/utils/JWTAlgorithm.java +++ b/GeneXusJWT/src/main/java/com/genexus/JWT/utils/JWTAlgorithm.java @@ -6,7 +6,7 @@ import com.genexus.securityapicommons.keys.PrivateKeyManager; public enum JWTAlgorithm { - HS256, HS512, RS256, RS512,; + HS256, HS512, RS256, RS512, ES256, ES384, ES512 ; public static String valueOf(JWTAlgorithm jWTAlgorithm, Error error) { switch (jWTAlgorithm) { @@ -18,6 +18,12 @@ public static String valueOf(JWTAlgorithm jWTAlgorithm, Error error) { return "RS256"; case RS512: return "RS512"; + case ES256: + return "ES256"; + case ES384: + return "ES384"; + case ES512: + return "ES512"; default: error.setError("JA001", "Unrecognized algorithm"); return "Unrecognized algorithm"; @@ -34,6 +40,12 @@ public static JWTAlgorithm getJWTAlgorithm(String jWTAlgorithm, Error error) { return JWTAlgorithm.RS256; case "RS512": return JWTAlgorithm.RS512; + case "ES256": + return JWTAlgorithm.ES256; + case "ES384": + return JWTAlgorithm.ES384; + case "ES512": + return JWTAlgorithm.ES512; default: error.setError("JA002", "Unrecognized algorithm"); return null; @@ -44,6 +56,9 @@ public static boolean isPrivate(JWTAlgorithm jWTAlgorithm) { switch (jWTAlgorithm) { case RS256: case RS512: + case ES256: + case ES384: + case ES512: return true; default: return false; @@ -88,6 +103,27 @@ public static Algorithm getAsymmetricAlgorithm(JWTAlgorithm algorithm, PrivateKe error.setError("JA008", e.getMessage()); return null; } + case ES256: + try { + return Algorithm.ECDSA256(cert.getECPublicKeyJWT(), key.getECPrivateKeyJWT()); + } catch (Exception e) { + error.setError("JA008", e.getMessage()); + return null; + } + case ES384: + try { + return Algorithm.ECDSA384(cert.getECPublicKeyJWT(), key.getECPrivateKeyJWT()); + } catch (Exception e) { + error.setError("JA008", e.getMessage()); + return null; + } + case ES512: + try { + return Algorithm.ECDSA512(cert.getECPublicKeyJWT(), key.getECPrivateKeyJWT()); + } catch (Exception e) { + error.setError("JA008", e.getMessage()); + return null; + } default: error.setError("JA006", "Unknown asymmetric algorithm"); return null; diff --git a/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/CertificateX509.java b/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/CertificateX509.java index 4cfd4a8..cbb1848 100644 --- a/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/CertificateX509.java +++ b/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/CertificateX509.java @@ -13,6 +13,7 @@ import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; @@ -432,5 +433,32 @@ public String getPublicKeyAlgorithm() { String[] aux = this.publicKeyAlgorithm.split("with"); return aux[1].toUpperCase(); } + + /** + * @return ECPublicKey type for the key type + */ + public ECPublicKey getECPublicKeyJWT() { + KeyFactory kf = null; + X509EncodedKeySpec encodedKeySpec = null; + try { + kf = SecurityUtils.getKeyFactory(this.getPublicKeyAlgorithm()); + encodedKeySpec = new X509EncodedKeySpec(this.subjectPublicKeyInfo.getEncoded()); + + } catch (NoSuchAlgorithmException | IOException e) { + this.error.setError("CE017", "Error reading algorithm"); + } + ECPublicKey pk = null; + if ((kf != null) && (encodedKeySpec != null)) { + try { + + pk = (ECPublicKey) kf.generatePublic(encodedKeySpec); + } catch (InvalidKeySpecException e) { + // e.printStackTrace(); + this.error.setError("CE018", "Error casting public key data for JWT signing"); + } + } + return pk; + + } } diff --git a/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/PrivateKeyManager.java b/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/PrivateKeyManager.java index 20fd601..02b3c03 100644 --- a/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/PrivateKeyManager.java +++ b/SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/PrivateKeyManager.java @@ -11,6 +11,7 @@ import java.security.PrivateKey; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.security.interfaces.ECPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; @@ -397,5 +398,31 @@ private boolean loadPrivateKeyFromPEMFile(String path) throws IOException, Certi } return flag; } + + /** + * @return PublicKey type for the key type + */ + public ECPrivateKey getECPrivateKeyJWT() { + + KeyFactory kf = null; + PKCS8EncodedKeySpec keySpec = null; + try { + kf = SecurityUtils.getKeyFactory(this.getPrivateKeyAlgorithm()); + keySpec = new PKCS8EncodedKeySpec(this.privateKeyInfo.getEncoded()); + + } catch (NoSuchAlgorithmException | IOException e) { + this.error.setError("PK019", "Error reading algorithm"); + } + ECPrivateKey pk = null; + if ((kf != null) && (keySpec != null)) { + try { + pk = (ECPrivateKey) kf.generatePrivate(keySpec); + } catch (InvalidKeySpecException e) { + this.error.setError("PK020", "Error reading key"); + } + } + return pk; + + } }