Skip to content
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

SecurityAPI repository migration. #863

Open
wants to merge 51 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
9598a93
SecurityAPI repository migration.
sgrampone May 15, 2024
d291dc4
Add tests and test resources
sgrampone May 16, 2024
552c607
First commit, GeneXusJWT module + some tests and test resources
sgrampone May 16, 2024
b393bc3
Trying to fix remote test failures
sgrampone May 17, 2024
8b6a86b
Debug remote tests
sgrampone May 17, 2024
ec33b04
Delete unused package
sgrampone May 17, 2024
943d56e
Fix key's path
sgrampone May 17, 2024
3b658bc
Print error
sgrampone May 17, 2024
d3b178c
Change test organization
sgrampone May 17, 2024
56d005f
Debug github test failure
sgrampone May 17, 2024
6b55eb2
Delete test and debug information
sgrampone May 17, 2024
c3f6a01
Delete unused test resources
sgrampone May 17, 2024
2592e3d
Add JWT tests
sgrampone May 17, 2024
983d088
Debug failing test
sgrampone May 20, 2024
09d889b
Set timezone for UnixTimeStampCreator to GMT
sgrampone May 20, 2024
f00d20c
Put tests on separate jar
sgrampone May 20, 2024
83e2ab6
Delete test debug information
sgrampone May 20, 2024
8f58cc9
Merge branch 'master' into securityapicommons
sgrampone May 20, 2024
8ace20d
GeneXusCryptography sources commit
sgrampone May 20, 2024
3a3d274
Add hash tests
sgrampone May 20, 2024
0344d88
Add MAC tests
sgrampone May 20, 2024
45adc1e
Add password derivation tests
sgrampone May 20, 2024
8d1b90b
Add symmetric encryption tests
sgrampone May 20, 2024
b4443ef
Test temporary folder and add file encryption tests
sgrampone May 20, 2024
cee5423
Add missing test resource
sgrampone May 20, 2024
ece5216
Add tests and test resources for ECDSA cryptography
sgrampone May 20, 2024
aeff150
Add asymmetric and checksum tests and resources
sgrampone May 20, 2024
d8fd200
Fix test failures
sgrampone May 21, 2024
42d3ac4
Add Checksum test
sgrampone May 21, 2024
5a49560
Debug test
sgrampone May 21, 2024
1635e13
Fix test
sgrampone May 21, 2024
c3f75a3
Merge branch 'master' into securityapicommons
sgrampone May 21, 2024
d416c87
Checksum file test, resource issue
sgrampone May 21, 2024
14b550a
Debug remote test
sgrampone May 21, 2024
876ce82
Fix checksum failing tests
sgrampone May 22, 2024
369cd9f
Add signature standard tests
sgrampone May 22, 2024
9bf3f29
Debug remote failing test
sgrampone May 22, 2024
8fe639e
Get remote exception stacktrace
sgrampone May 22, 2024
d2fb8f8
Delete ECDSA test for standard signature
sgrampone May 22, 2024
89dcdaa
XMlSignature complete module. Update commons-codec to version 1.13 an…
sgrampone May 22, 2024
0598627
Bump commons-codec to version 1.15 and java-jwt to version 4.4.0
sgrampone May 23, 2024
10a338e
XmlSignature tests and resources
sgrampone May 30, 2024
131a6e5
GeneXusSFTP module sources
sgrampone May 30, 2024
93f2373
GeneXusFTPS module sources
sgrampone May 30, 2024
1d96599
Housekeeping, using property to define bouncy castle version
sgrampone May 30, 2024
e136390
Add new modules to readme file
sgrampone May 31, 2024
c0e7f3e
New feature, load first certificate or public key from keystore
sgrampone Jun 21, 2024
1cdf32d
New feature, import public key from jkws
sgrampone Jun 21, 2024
2e4cc03
Merge branch 'master' into securityapicommons
sgrampone Jul 1, 2024
a8cd6e9
Fix quality issues, upgrade tests to JUnit 4 and add tests
sgrampone Sep 20, 2024
ac47e3b
Merge branch 'master' into securityapicommons
sgrampone Sep 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<software.azure.cosmos.version>4.42.0</software.azure.cosmos.version>
<log4j.version>2.21.1</log4j.version>
<io.opentelemetry.version>1.28.0</io.opentelemetry.version>
<org.bouncycastle.version>1.78.1</org.bouncycastle.version>
</properties>

<organization>
Expand Down Expand Up @@ -114,6 +115,7 @@
<module>gxcloudstorage-tests</module>
<module>gxobservability</module>
<module>gxcloudstorage-awss3-v2</module>
<module>securityapicommons</module>
</modules>

<dependencies>
Expand Down
40 changes: 40 additions & 0 deletions securityapicommons/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?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>securityapicommons</artifactId>
<name>GeneXus Security API Commons</name>
<dependencies>


<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>${org.bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>${org.bouncycastle.version}</version>
</dependency>
</dependencies>

<build>
<finalName>SecurityAPICommons</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.genexus.securityapicommons.commons;

public abstract class Certificate extends PublicKey {

public Certificate() {
super();
}

public abstract boolean load(String path);
public abstract boolean loadPKCS12(String path, String alias, String password);
public abstract boolean fromBase64(String base64Data);
public abstract String toBase64();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

package com.genexus.securityapicommons.commons;

/**
* @author sgrampone
*
*/
public class Error {

private boolean exists;
private String code;
private String description;

/**
* @return error code string
*/
public String getCode() {
return code;
}

/**
* @return error description string
*/
public String getDescription() {
return description;
}

/**
* Error constructor
*/
public Error() {
this.exists = false;
this.code = "";
this.description = "";
}

public Error(String code, String description)
{
this.code = code;
this.description = description;
this.exists = true;
}

/**
* Set error values
*
* @param errorCode
* String error internal code
* @param errorDescription
* String error internal description
*/
public void setError(String errorCode, String errorDescription) {
this.exists = true;
this.code = errorCode;
this.description = errorDescription;

}

/**
* If an error exists
*
* @return 1 if an error exists, 0 if not
*/
public boolean existsError() {
return this.exists;
}

/**
* Sets initial parameters
*/
public void cleanError() {
this.exists = false;
this.code = "";
this.description = "";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.genexus.securityapicommons.commons;

import org.bouncycastle.crypto.params.AsymmetricKeyParameter;

public class Key extends SecurityAPIObject {

public Key() {
super();
}

protected String algorithm;

public String getAlgorithm()
{
return this.algorithm;
}

public boolean load(String path) {return false; }
public boolean loadPKCS12(String path, String alias, String password) { return false; }
public boolean fromBase64(String base64) { return false; }
public String toBase64() { return ""; }
protected void setAlgorithm() {}
public AsymmetricKeyParameter getAsymmetricKeyParameter() {return null; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.genexus.securityapicommons.commons;

public abstract class PrivateKey extends Key{

public PrivateKey() {
super();
}

public abstract boolean loadEncrypted(String privateKeyPath, String encryptionPassword);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package com.genexus.securityapicommons.commons;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;

import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.util.encoders.Base64;

import com.genexus.securityapicommons.utils.SecurityUtils;

public class PublicKey extends Key {

protected SubjectPublicKeyInfo subjectPublicKeyInfo;

public PublicKey() {
super();
}

/******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/
@Override
public boolean load(String path) {

/******* INPUT VERIFICATION - BEGIN *******/
SecurityUtils.validateStringInput("path", path, this.error);
if (!(SecurityUtils.extensionIs(path, ".pem") || SecurityUtils.extensionIs(path, "key"))) {
this.error.setError("PU001", "Public key should be loaded from a .pem or .key file");
return false;
}
/******* INPUT VERIFICATION - END *******/
boolean loaded = false;
try {
loaded = loadPublicKeyFromFile(path);
} catch (Exception e) {
this.error.setError("PU002", e.getMessage());
return false;
}
return loaded;
}

@Override
public boolean fromBase64(String base64Data) {

/******* INPUT VERIFICATION - BEGIN *******/
SecurityUtils.validateStringInput("base64Data", base64Data, this.error);
if (this.hasError()) {
return false;
}

/******* INPUT VERIFICATION - END *******/

boolean flag;
try {
byte[] dataBuffer = Base64.decode(base64Data);
this.subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(dataBuffer));
flag = true;
} catch (Exception e) {
this.error.setError("PU003", e.getMessage());
flag = false;
}
setAlgorithm();

return flag;
}

@Override
public String toBase64() {
if (this.subjectPublicKeyInfo == null) {
this.error.setError("PU004", "Not loaded key");
return "";
}
String base64Encoded = "";

try {
base64Encoded = new String(Base64.encode(this.subjectPublicKeyInfo.getEncoded()));

} catch (Exception e) {
this.error.setError("PU005", e.getMessage());
}

return base64Encoded;
}

/******** EXTERNAL OBJECT PUBLIC METHODS - END ********/

@Override
protected void setAlgorithm() {
if (this.subjectPublicKeyInfo == null) {
return;
}
String alg = this.subjectPublicKeyInfo.getAlgorithm().getAlgorithm().getId();
switch (alg) {
case "1.2.840.113549.1.1.1":
this.algorithm = "RSA";
break;
case "1.2.840.10045.2.1":
this.algorithm = "ECDSA";
break;
}

}

@Override
public AsymmetricKeyParameter getAsymmetricKeyParameter() {
AsymmetricKeyParameter akp = null;
try {
akp = PublicKeyFactory.createKey(this.subjectPublicKeyInfo);
} catch (Exception e) {
this.error.setError("PU006", e.getMessage());
return null;
}
return akp;
}

/**
* @return PublicKey type for the key type
*/
public java.security.PublicKey getPublicKey() {
java.security.PublicKey pk = null;
try {
KeyFactory kf = SecurityUtils.getKeyFactory(this.algorithm);
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(this.subjectPublicKeyInfo.getEncoded());
pk = kf.generatePublic(encodedKeySpec);
} catch (Exception e) {
this.error.setError("PU007", e.getMessage());
return null;
}
return pk;
}

private boolean loadPublicKeyFromFile(String path) throws IOException {
boolean flag = false;
try (FileReader privateKeyReader = new FileReader(new File(path))) {
try (PEMParser parser = new PEMParser(privateKeyReader)) {
Object obj;
obj = parser.readObject();
if (obj instanceof PrivateKeyInfo) {
this.error.setError("PU008", "The file contains a private key");
flag = false;
}
if (obj instanceof SubjectPublicKeyInfo) {
this.subjectPublicKeyInfo = (SubjectPublicKeyInfo) obj;
setAlgorithm();
flag = true;
}
if (obj instanceof PEMKeyPair) {
PEMKeyPair keypair = (PEMKeyPair) obj;
this.subjectPublicKeyInfo = keypair.getPublicKeyInfo();
setAlgorithm();
flag = true;
}
if (obj instanceof ECPublicKeyParameters) {
ECPublicKeyParameters ecParms = (ECPublicKeyParameters) obj;
this.subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(ecParms);
setAlgorithm();
flag = true;
}
if (obj instanceof RSAKeyParameters) {
RSAKeyParameters rsaParms = (RSAKeyParameters) obj;
this.subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(rsaParms);
setAlgorithm();
flag = true;
}
if (obj instanceof X509CertificateHolder) {
this.error.setError("PU009", "This file contains a certificate, use the Certificate object instead");
flag = false;
}
}
}
if (!flag && !this.hasError()) {
this.error.setError("PU010", "Error loading public key from file");
}
return flag;
}

}
Loading
Loading