-
Notifications
You must be signed in to change notification settings - Fork 17
GamCryptography EO migration to GamUtils EO on Github #885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sgrampone
wants to merge
26
commits into
master
Choose a base branch
from
gamutils_eo
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
2d150fc
GamUtils + tests
sgrampone 083bef0
Fix test
sgrampone 77fab66
Fix quality issues and Log
sgrampone 9cb8c02
New features, tests and some needed refactoring
sgrampone a2c7ae2
Load encrypted private keys + tests
sgrampone 055badf
GamUtilsEO simplification and module refactor + tests
sgrampone 63abd1d
Fix cast type error for jwk keys on gamutils
sgrampone c1be143
Add DynamicCall EO to GamUtils
sgrampone 761a632
Merge branch 'master' into gamutils_eo
sgrampone 842a761
Add sha256 and encoding features for PKCE implementation
sgrampone 5322c50
Fix hash class
sgrampone 09ce4c3
Refactor Encoding class name
sgrampone be96dd3
Merge branch 'master' into gamutils_eo
sgrampone 2bc6616
Adding missing functions
sgrampone 84b897d
Delete usless function
sgrampone 038b14c
Merge branch 'master' into gamutils_eo
sgrampone 75fcc40
Adding Base64Url encoding functions and fixing symmetric and asymmetric
sgrampone c7e5e15
Adding Base64Url encoding functions and fixing symmetric and asymmetr…
sgrampone 788dff3
Fix JWTAlgorithm bug with RSA header
sgrampone 594c264
Add Base64ToHexa function
sgrampone a2e0259
GamUtilsEO add functions for PKCE
sgrampone 096fcb6
Merge branch 'master' into gamutils_eo
sgrampone f077408
Fix pkce functions
sgrampone 5c3eb3c
Change Base64Url functions
sgrampone 30563cc
Merge branch 'master' into gamutils_eo
sgrampone c8ba835
Fix key extension detection for azure OIDC discovery
sgrampone File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>com.genexus</groupId> | ||
<artifactId>parent</artifactId> | ||
<version>${revision}${changelist}</version> | ||
</parent> | ||
|
||
<artifactId>gamutils</artifactId> | ||
<name>GAM Utils EO</name> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>gxcommon</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.nimbusds</groupId> | ||
<artifactId>nimbus-jose-jwt</artifactId> | ||
<version>9.37.3</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.bouncycastle</groupId> | ||
<artifactId>bcprov-jdk18on</artifactId> | ||
<version>1.78.1</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.bouncycastle</groupId> | ||
<artifactId>bcpkix-jdk18on</artifactId> | ||
<version>1.78.1</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>commons-codec</groupId> | ||
<artifactId>commons-codec</artifactId> | ||
<version>1.15</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<finalName>gamutils</finalName> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.8.0</version> | ||
<configuration> | ||
<source>1.8</source> | ||
<target>1.8</target> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.genexus.gam; | ||
|
||
import com.genexus.gam.utils.*; | ||
|
||
public class GamUtilsEO { | ||
|
||
/********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ | ||
|
||
//**HASH**// | ||
public static String sha512(String plainText) { | ||
return Hash.sha512(plainText); | ||
} | ||
|
||
//**RANDOM**// | ||
public static String randomAlphanumeric(int length) { | ||
return Random.randomAlphanumeric(length); | ||
} | ||
|
||
public static String randomNumeric(int length) { | ||
return Random.randomNumeric(length); | ||
} | ||
|
||
|
||
//**JWK**// | ||
|
||
public static String generateKeyPair() { | ||
return Jwk.generateKeyPair(); | ||
} | ||
|
||
public static String getPublicJwk(String jwkString) { | ||
return Jwk.getPublic(jwkString); | ||
} | ||
|
||
public static boolean jwk_verifyJWT(String jwkString, String token) { | ||
return Jwk.verifyJWT(jwkString, token); | ||
} | ||
|
||
public static String jwk_createJwt(String jwkString, String payload, String header) { | ||
return Jwk.createJwt(jwkString, payload, header); | ||
} | ||
|
||
//**JWKS**// | ||
|
||
public static boolean jwks_verifyJWT(String jwksString, String token, String kid) { | ||
return Jwks.verifyJWT(jwksString, token, kid); | ||
} | ||
|
||
//**JWT**// | ||
public static boolean verifyJWTWithFile(String path, String alias, String password, String token) { | ||
return Jwt.verify(path, alias, password, token); | ||
} | ||
|
||
/********EXTERNAL OBJECT PUBLIC METHODS - END ********/ | ||
} |
113 changes: 113 additions & 0 deletions
113
gamutils/src/main/java/com/genexus/gam/utils/CertificateUtil.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package com.genexus.gam.utils; | ||
|
||
import com.genexus.diagnostics.core.ILogger; | ||
import com.genexus.diagnostics.core.LogManager; | ||
import org.apache.commons.io.FilenameUtils; | ||
import org.bouncycastle.cert.X509CertificateHolder; | ||
import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory; | ||
import org.bouncycastle.openssl.PEMParser; | ||
|
||
import java.io.*; | ||
import java.security.KeyStore; | ||
import java.security.cert.X509Certificate; | ||
|
||
public enum CertificateUtil { | ||
|
||
crt, cer, pfx, jks, pkcs12, p12, pem, key; | ||
|
||
public static final ILogger logger = LogManager.getLogger(CertificateUtil.class); | ||
|
||
public static CertificateUtil value(String ext) { | ||
switch (ext.toLowerCase().trim()) { | ||
case "crt": | ||
return crt; | ||
case "cer": | ||
return cer; | ||
case "pfx": | ||
return pfx; | ||
case "jks": | ||
return jks; | ||
case "pkcs12": | ||
return pkcs12; | ||
case "p12": | ||
return p12; | ||
case "pem": | ||
return pem; | ||
case "key": | ||
return key; | ||
default: | ||
logger.error("Invalid certificate file extension"); | ||
return null; | ||
} | ||
} | ||
|
||
public static X509Certificate getCertificate(String path, String alias, String password) { | ||
CertificateUtil ext = CertificateUtil.value(FilenameUtils.getExtension(path)); | ||
if (ext == null) { | ||
logger.error("Error reading certificate path"); | ||
return null; | ||
} | ||
switch (ext) { | ||
case crt: | ||
case cer: | ||
return loadFromDer(path); | ||
case pfx: | ||
case jks: | ||
case pkcs12: | ||
case p12: | ||
return loadFromPkcs12(path, alias, password); | ||
case pem: | ||
case key: | ||
return loadFromPkcs8(path); | ||
default: | ||
logger.error("Invalid certificate file extension"); | ||
return null; | ||
} | ||
} | ||
|
||
private static X509Certificate loadFromPkcs8(String path) { | ||
try (FileReader privateKeyReader = new FileReader(new File(path))) { | ||
try (PEMParser parser = new PEMParser(privateKeyReader)) { | ||
Object obj = parser.readObject(); | ||
if (obj instanceof X509CertificateHolder) { | ||
X509CertificateHolder x509 = (X509CertificateHolder) obj; | ||
try (InputStream in = new ByteArrayInputStream(x509.getEncoded())) { | ||
CertificateFactory certFactory = new CertificateFactory(); | ||
return (X509Certificate) certFactory.engineGenerateCertificate(in); | ||
} | ||
} else { | ||
logger.error("Error reading certificate"); | ||
return null; | ||
} | ||
} | ||
} catch (Exception e) { | ||
logger.error("loadFromPem", e); | ||
return null; | ||
} | ||
} | ||
|
||
private static X509Certificate loadFromPkcs12(String path, String alias, String password) { | ||
try (FileInputStream inStream = new FileInputStream(path)) { | ||
KeyStore ks = KeyStore.getInstance("PKCS12"); | ||
ks.load(inStream, password.toCharArray()); | ||
if (alias.equals("") || alias.isEmpty()) { | ||
return (X509Certificate) ks.getCertificate(ks.aliases().nextElement()); | ||
} else { | ||
return (X509Certificate) ks.getCertificate(alias); | ||
} | ||
} catch (Exception e) { | ||
logger.error("loadFromPkcs12", e); | ||
return null; | ||
} | ||
} | ||
|
||
private static X509Certificate loadFromDer(String path) { | ||
try (FileInputStream inStream = new FileInputStream(path)) { | ||
CertificateFactory cf = new CertificateFactory(); | ||
return (X509Certificate) cf.engineGenerateCertificate(inStream); | ||
} catch (Exception e) { | ||
logger.error("loadFromDer", e); | ||
return null; | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.genexus.gam.utils; | ||
|
||
import com.genexus.diagnostics.core.ILogger; | ||
import com.genexus.diagnostics.core.LogManager; | ||
import org.bouncycastle.crypto.Digest; | ||
import org.bouncycastle.crypto.digests.SHA512Digest; | ||
import org.bouncycastle.util.encoders.Base64; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
|
||
public class Hash { | ||
public static final ILogger logger = LogManager.getLogger(Hash.class); | ||
|
||
public static String sha512(String plainText) { | ||
if (plainText.isEmpty()) { | ||
logger.error("sha512 plainText is empty"); | ||
return ""; | ||
} | ||
byte[] inputBytes = plainText.getBytes(StandardCharsets.UTF_8); | ||
Digest alg = new SHA512Digest(); | ||
byte[] retValue = new byte[alg.getDigestSize()]; | ||
alg.update(inputBytes, 0, inputBytes.length); | ||
alg.doFinal(retValue, 0); | ||
return Base64.toBase64String(retValue); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.genexus.gam.utils; | ||
|
||
import com.genexus.diagnostics.core.ILogger; | ||
import com.genexus.diagnostics.core.LogManager; | ||
import com.nimbusds.jose.Algorithm; | ||
import com.nimbusds.jose.jwk.JWK; | ||
import com.nimbusds.jose.jwk.KeyUse; | ||
import com.nimbusds.jose.jwk.RSAKey; | ||
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; | ||
|
||
import java.util.UUID; | ||
|
||
public class Jwk { | ||
|
||
public static final ILogger logger = LogManager.getLogger(Jwk.class); | ||
|
||
public static String generateKeyPair() { | ||
try { | ||
String kid = UUID.randomUUID().toString(); | ||
RSAKey key = new RSAKeyGenerator(2048) | ||
.keyUse(KeyUse.SIGNATURE) | ||
.keyID(kid) | ||
.algorithm(Algorithm.parse("RS256")) | ||
.generate(); | ||
return key.toString(); | ||
|
||
} catch (Exception e) { | ||
logger.error("generateKeyPair", e); | ||
return ""; | ||
} | ||
} | ||
|
||
public static String getPublic(String jwkString) { | ||
if (jwkString.isEmpty()) { | ||
logger.error("getPublic jwkString parameter is empty"); | ||
return ""; | ||
} | ||
try { | ||
JWK jwk = JWK.parse(jwkString); | ||
return jwk.toPublicJWK().toString(); | ||
} catch (Exception e) { | ||
logger.error("getPublic", e); | ||
return ""; | ||
} | ||
} | ||
|
||
public static boolean verifyJWT(String jwkString, String token) { | ||
if (jwkString.isEmpty()) { | ||
logger.error("verifyJWT jwkString parameter is empty"); | ||
return false; | ||
} | ||
if (token.isEmpty()) { | ||
logger.error("verifyJWT token parameter is empty"); | ||
return false; | ||
} | ||
try { | ||
JWK jwk = JWK.parse(jwkString); | ||
return Jwt.verify(jwk.toRSAKey().toRSAPublicKey(), token); | ||
} catch (Exception e) { | ||
logger.error("verifyJWT", e); | ||
return false; | ||
} | ||
|
||
} | ||
|
||
public static String createJwt(String jwkString, String payload, String header) { | ||
if (jwkString.isEmpty()) { | ||
logger.error("createJwt jwkString parameter is empty"); | ||
return ""; | ||
} | ||
if (payload.isEmpty()) { | ||
logger.error("createJwt payload parameter is empty"); | ||
return ""; | ||
} | ||
if (header.isEmpty()) { | ||
logger.error("createJwt header parameter is empty"); | ||
return ""; | ||
} | ||
try { | ||
JWK jwk = JWK.parse(jwkString); | ||
return Jwt.create(jwk.toRSAKey().toRSAPrivateKey(), payload, header); | ||
} catch (Exception e) { | ||
logger.error("createJwt", e); | ||
return ""; | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.genexus.gam.utils; | ||
|
||
import com.genexus.diagnostics.core.ILogger; | ||
import com.genexus.diagnostics.core.LogManager; | ||
import com.nimbusds.jose.jwk.JWK; | ||
import com.nimbusds.jose.jwk.JWKSet; | ||
|
||
public class Jwks { | ||
|
||
public static final ILogger logger = LogManager.getLogger(Jwks.class); | ||
|
||
public static boolean verifyJWT(String jwksString, String token, String kid) { | ||
if (jwksString.isEmpty()) { | ||
logger.error("verifyJWT jwksString parameter is empty"); | ||
return false; | ||
} | ||
if (token.isEmpty()) { | ||
logger.error("verifyJWT token parameter is empty"); | ||
return false; | ||
} | ||
if (kid.isEmpty()) { | ||
logger.error("verifyJWT kid parameter is empty"); | ||
return false; | ||
} | ||
try { | ||
JWKSet set = JWKSet.parse(jwksString); | ||
JWK jwk = set.getKeyByKeyId(kid); | ||
return Jwt.verify(jwk.toRSAKey().toRSAPublicKey(), token); | ||
} catch (Exception e) { | ||
logger.error("verifyJWT", e); | ||
return false; | ||
} | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.