Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ These are the source of the GeneXus Standard Classes for Java, valid since GeneX

## Modules

| Name | Description
|---|---
| common | Classes common to Android and Java
| gxcryptocommon | Classes common to Android and Java related to Cryptography
| gxmail | Classes related to mail handling
| java | Java standard classes, output is gxclassr.jar
| wrappercommon | Interfaces to encapsulate Java EE and Jakarta EE support, output is gxwrappercommon.jar
| wrapperjavax | Implement the interfaces defined in wrappercommon in Java EE, output is gxwrapperjavax.jar
| wrapperjakarta | Implement the interfaces defined in wrappercommon in Jakarta EE, output is gxwrapperjakarta.jar
| gxoffice | Formerly Java classes are now separated to be included only when using office.
| gxsearch | Formerly in Java classes are now separated to be included only when using search.
| Name | Description
|--------------------------------|---
| common | Classes common to Android and Java
| gxcryptocommon | Classes common to Android and Java related to Cryptography
| gxmail | Classes related to mail handling
| java | Java standard classes, output is gxclassr.jar
| wrappercommon | Interfaces to encapsulate Java EE and Jakarta EE support, output is gxwrappercommon.jar
| wrapperjavax | Implement the interfaces defined in wrappercommon in Java EE, output is gxwrapperjavax.jar
| wrapperjakarta | Implement the interfaces defined in wrappercommon in Jakarta EE, output is gxwrapperjakarta.jar
| gxoffice | Formerly Java classes are now separated to be included only when using office.
| gxsearch | Formerly in Java classes are now separated to be included only when using search.
| gxandroidpublisher and javapns | They are necessary for when you have Push Notifications in your old implementation. These are projects that should disappear in the short term.
| android | The standard Android classes. **Note that this is not the full runtime for Android, the full runtime can be created by using the Android Flexible Client project**.
| gxexternalproviders | Implements service provider for IBM Cloud, Google, Azure, Amazon
Expand All @@ -32,6 +32,7 @@ These are the source of the GeneXus Standard Classes for Java, valid since GeneX
| gxftps | SecurityAPI's GeneXusFTPS module
| gxsftp | SecurityAPI's GeneXusSFTP module
| gamutils | GAM external object with utilities
| gamtotp | GAM external object for RFC6238 implementation

The dependencies between the projects are specified in each pom.xml within their directory.

Expand Down
51 changes: 51 additions & 0 deletions gamtotp/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?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>gamtotp</artifactId>
<name>GAM TOTP</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>dev.samstevens.totp</groupId>
<artifactId>totp</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.78</version>
</dependency>


</dependencies>

<build>
<finalName>gamtotp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
</project>
94 changes: 94 additions & 0 deletions gamtotp/src/main/java/com/genexus/totp/TOTPAuthenticator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.genexus.totp;

import dev.samstevens.totp.code.CodeGenerator;
import dev.samstevens.totp.code.DefaultCodeGenerator;
import dev.samstevens.totp.code.DefaultCodeVerifier;
import dev.samstevens.totp.code.HashingAlgorithm;
import dev.samstevens.totp.qr.QrData;
import dev.samstevens.totp.qr.QrGenerator;
import dev.samstevens.totp.qr.ZxingPngQrGenerator;
import dev.samstevens.totp.secret.DefaultSecretGenerator;
import dev.samstevens.totp.secret.SecretGenerator;
import dev.samstevens.totp.time.SystemTimeProvider;
import dev.samstevens.totp.time.TimeProvider;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import static dev.samstevens.totp.util.Utils.getDataUriForImage;

@SuppressWarnings("unused")
public class TOTPAuthenticator {

private static final Logger logger = LogManager.getLogger(TOTPAuthenticator.class);

public static String GenerateKey(int keyLength) {
logger.debug("GenerateKey");
SecretGenerator secretGenerator = new DefaultSecretGenerator(keyLength * 8);
String str = secretGenerator.generate();
try {
return str.substring(0, keyLength);
} catch (Exception e) {
logger.error("GenerateKey", e);
return str;
}
}

public static String GenerateQRData(String accountName, String secretKey, String appName, String algorithm, int digits, int period) {
logger.debug("GenerateQRData");
HashingAlgorithm hashAlg;
if (algorithm.equalsIgnoreCase("SHA512")) {
hashAlg = HashingAlgorithm.SHA512;
} else if (algorithm.equalsIgnoreCase("SHA256")) {
hashAlg = HashingAlgorithm.SHA256;
} else {
hashAlg = HashingAlgorithm.SHA1;
}

QrData data = new QrData.Builder()
.label(accountName)
.secret(secretKey)
.issuer(appName)
.algorithm(hashAlg)
.digits(digits)
.period(period)
.build();


QrGenerator generator = new ZxingPngQrGenerator();
try {
return getDataUriForImage(generator.generate(data), generator.getImageMimeType());
} catch (Exception e) {
logger.error("GenerateQRData", e);
return null;
}
}

public static boolean VerifyTOTPCode(String secretKey, String code, String algorithm, int digits, int period) {
logger.debug("VerifyTOTPCode");
HashingAlgorithm hashAlg;
if (algorithm.equalsIgnoreCase("SHA512")) {
hashAlg = HashingAlgorithm.SHA512;
} else if (algorithm.equalsIgnoreCase("SHA256")) {
hashAlg = HashingAlgorithm.SHA256;
} else {
hashAlg = HashingAlgorithm.SHA1;
}

TimeProvider timeProvider = new SystemTimeProvider();

CodeGenerator codeGenerator = new DefaultCodeGenerator(hashAlg, digits);
DefaultCodeVerifier verifier = new DefaultCodeVerifier(codeGenerator, timeProvider);

// sets the time period for codes to be valid for to X seconds
verifier.setTimePeriod(period);

// allow codes valid for 1 time periods before/after to pass as valid
verifier.setAllowedTimePeriodDiscrepancy(0);

// secret = the shared secret for the user
// code = the code submitted by the user
return verifier.isValidCode(secretKey, code);
}
}


1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<module>gxsftp</module>
<module>gxftps</module>
<module>gamutils</module>
<module>gamtotp</module>
</modules>

<dependencies>
Expand Down
Loading