feat: webauthn tests
This commit is contained in:
63
.gitignore
vendored
63
.gitignore
vendored
@@ -1,54 +1,11 @@
|
|||||||
# ---> Java
|
out/
|
||||||
# Compiled class file
|
build
|
||||||
*.class
|
classes
|
||||||
|
|
||||||
# Log file
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# BlueJ files
|
|
||||||
*.ctxt
|
|
||||||
|
|
||||||
# Mobile Tools for Java (J2ME)
|
|
||||||
.mtj.tmp/
|
|
||||||
|
|
||||||
# Package Files #
|
|
||||||
*.jar
|
|
||||||
*.war
|
|
||||||
*.nar
|
|
||||||
*.ear
|
|
||||||
*.zip
|
|
||||||
*.tar.gz
|
|
||||||
*.rar
|
|
||||||
|
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
|
||||||
hs_err_pid*
|
|
||||||
replay_pid*
|
|
||||||
|
|
||||||
# ---> macOS
|
|
||||||
# General
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.AppleDouble
|
.gradle
|
||||||
.LSOverride
|
.classpath
|
||||||
|
.project
|
||||||
# Icon must end with two \r
|
.settings
|
||||||
Icon
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
# Thumbnails
|
|
||||||
._*
|
|
||||||
|
|
||||||
# Files that might appear in the root of a volume
|
|
||||||
.DocumentRevisions-V100
|
|
||||||
.fseventsd
|
|
||||||
.Spotlight-V100
|
|
||||||
.TemporaryItems
|
|
||||||
.Trashes
|
|
||||||
.VolumeIcon.icns
|
|
||||||
.com.apple.timemachine.donotpresent
|
|
||||||
|
|
||||||
# Directories potentially created on remote AFP share
|
|
||||||
.AppleDB
|
|
||||||
.AppleDesktop
|
|
||||||
Network Trash Folder
|
|
||||||
Temporary Items
|
|
||||||
.apdisk
|
|
||||||
|
|||||||
100
build.gradle
Normal file
100
build.gradle
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'eclipse'
|
||||||
|
apply plugin: 'idea'
|
||||||
|
|
||||||
|
def JsonSlurper = Class.forName('groovy.json.JsonSlurper');
|
||||||
|
def buildJSON = JsonSlurper.newInstance().parseText(new File("build.json").text)
|
||||||
|
|
||||||
|
if (buildJSON.application) { apply plugin: 'application' }
|
||||||
|
|
||||||
|
def baseProjectName = buildJSON?.project?.name ?: '__project_name__';
|
||||||
|
def shellCommandName = baseProjectName
|
||||||
|
def eclipseProjectName = baseProjectName
|
||||||
|
def eclipseProjectComment = buildJSON?.project?.comment ?: '__project_name_comment__'
|
||||||
|
def jarManifestMainClass = buildJSON?.project?.main ?: 'SampleMain'
|
||||||
|
|
||||||
|
if (buildJSON.application) { mainClassName = jarManifestMainClass }
|
||||||
|
archivesBaseName = buildJSON?.project?.archiveName ?: baseProjectName
|
||||||
|
sourceCompatibility = 1.8
|
||||||
|
targetCompatibility = 1.8
|
||||||
|
|
||||||
|
def addRepo = new File(System.getProperty("user.home"), ".build_add.repo")
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
maven() { url 'https://maven.aliyun.com/repository/central' }
|
||||||
|
if (addRepo.exists()) { maven() { url addRepo.text.trim() } }
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
// '-x test' skip unit test
|
||||||
|
defaultTasks 'packjar'
|
||||||
|
|
||||||
|
task packjarsrc << {
|
||||||
|
ant.jar(destfile: "${baseProjectName}-sources.jar") {
|
||||||
|
fileset(dir: 'src/main/java', includes: '**/*.java')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packjarsrc.dependsOn build
|
||||||
|
|
||||||
|
task packjar << {
|
||||||
|
def packtempclasses = "packtempclasses"
|
||||||
|
def libs = ant.path {
|
||||||
|
fileset(dir: 'build/libs', includes: '*.jar')
|
||||||
|
}
|
||||||
|
libs.list().each {
|
||||||
|
ant.unzip(dest: packtempclasses, src: it)
|
||||||
|
}
|
||||||
|
new File(packtempclasses + "/jar-version-build.txt").write(new Date().format("yyyyMMdd"), "UTF-8")
|
||||||
|
ant.jar(destfile: "${baseProjectName}.jar") {
|
||||||
|
fileset(dir: packtempclasses, includes: '**/*.*')
|
||||||
|
}
|
||||||
|
ant.delete(dir: packtempclasses)
|
||||||
|
}
|
||||||
|
packjar.dependsOn packjarsrc
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile files(fileTree(dir: 'lib', includes: ['*.jar'], excludes: ['*-sources.jar', '*-javadoc.jar']))
|
||||||
|
|
||||||
|
if (buildJSON.repo != null && buildJSON.repo.dependencies != null) {
|
||||||
|
buildJSON.repo.dependencies.each {
|
||||||
|
compile("${it}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buildJSON.repo != null && buildJSON.repo.testDependencies != null) {
|
||||||
|
buildJSON.repo.testDependencies.each {
|
||||||
|
testCompile("${it}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eclipse {
|
||||||
|
project {
|
||||||
|
name = eclipseProjectName
|
||||||
|
comment = eclipseProjectComment
|
||||||
|
}
|
||||||
|
classpath {
|
||||||
|
defaultOutputDir = file('classes')
|
||||||
|
downloadSources = true
|
||||||
|
file {
|
||||||
|
whenMerged { classpath ->
|
||||||
|
classpath.entries.findAll { it.kind=='lib' }.each {
|
||||||
|
if ((it.path != null) && (it.sourcePath == null) && file(it.path.replace(".jar", "-sources.jar")).exists()) {
|
||||||
|
it.sourcePath = getFileReferenceFactory().fromPath(it.path.replace(".jar", "-sources.jar"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eclipseJdt << {
|
||||||
|
File f = file('.settings/org.eclipse.core.resources.prefs')
|
||||||
|
f.write('eclipse.preferences.version=1\n')
|
||||||
|
f.append('encoding/<project>=utf-8')
|
||||||
|
}
|
||||||
|
|
||||||
25
build.json
Normal file
25
build.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"project": {
|
||||||
|
"name": "webauthnn4j-tests",
|
||||||
|
"main": "SampleMain",
|
||||||
|
"archiveName": "sample"
|
||||||
|
},
|
||||||
|
"application": false,
|
||||||
|
"java": "1.8",
|
||||||
|
"builder": {
|
||||||
|
"name": "gradle",
|
||||||
|
"version": "3.1"
|
||||||
|
},
|
||||||
|
"repo": {
|
||||||
|
"dependencies": [
|
||||||
|
"me.hatter:commons:3.0",
|
||||||
|
"com.webauthn4j:webauthn4j-core:0.20.3.RELEASE",
|
||||||
|
"com.webauthn4j:webauthn4j-util:0.20.3.RELEASE",
|
||||||
|
"com.webauthn4j:webauthn4j-metadata:0.20.3.RELEASE",
|
||||||
|
"com.webauthn4j:webauthn4j-device-check:0.20.3.RELEASE"
|
||||||
|
],
|
||||||
|
"testDependencies": [
|
||||||
|
"junit:junit:4.12"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/main/java/me/hatter/webauthn/tests/MdsTest.java
Normal file
52
src/main/java/me/hatter/webauthn/tests/MdsTest.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package me.hatter.webauthn.tests;
|
||||||
|
|
||||||
|
import com.webauthn4j.converter.util.ObjectConverter;
|
||||||
|
import com.webauthn4j.metadata.FidoMDS3MetadataBLOBProvider;
|
||||||
|
import com.webauthn4j.metadata.MetadataBLOBProvider;
|
||||||
|
import com.webauthn4j.metadata.data.MetadataBLOB;
|
||||||
|
import com.webauthn4j.metadata.data.MetadataBLOBPayload;
|
||||||
|
import com.webauthn4j.metadata.data.statement.MetadataStatement;
|
||||||
|
import com.webauthn4j.util.Base64Util;
|
||||||
|
import com.webauthn4j.util.CertificateUtil;
|
||||||
|
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
public class MdsTest {
|
||||||
|
static final X509Certificate rootCertificate = CertificateUtil.generateX509Certificate(Base64Util.decode(
|
||||||
|
"MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G" +
|
||||||
|
"A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp" +
|
||||||
|
"Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4" +
|
||||||
|
"MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG" +
|
||||||
|
"A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI" +
|
||||||
|
"hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8" +
|
||||||
|
"RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT" +
|
||||||
|
"gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm" +
|
||||||
|
"KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd" +
|
||||||
|
"QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ" +
|
||||||
|
"XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw" +
|
||||||
|
"DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o" +
|
||||||
|
"LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU" +
|
||||||
|
"RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp" +
|
||||||
|
"jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK" +
|
||||||
|
"6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX" +
|
||||||
|
"mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs" +
|
||||||
|
"Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH" +
|
||||||
|
"WD9f"));
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final MetadataBLOBProvider metadataBLOBProvider = new FidoMDS3MetadataBLOBProvider(
|
||||||
|
new ObjectConverter(), rootCertificate);
|
||||||
|
final MetadataBLOB metadataBLOB = metadataBLOBProvider.provide();
|
||||||
|
// System.out.println(metadataBLOB.getHeader());
|
||||||
|
final MetadataBLOBPayload metadataBLOBPayload = metadataBLOB.getPayload();
|
||||||
|
metadataBLOBPayload.getEntries().forEach(entry -> {
|
||||||
|
System.out.println(entry.getAaguid());
|
||||||
|
final MetadataStatement metadataStatement = entry.getMetadataStatement();
|
||||||
|
if (metadataStatement != null) {
|
||||||
|
System.out.println("- " + metadataStatement.getDescription());
|
||||||
|
System.out.println("- " + metadataStatement.getProtocolFamily());
|
||||||
|
System.out.println("- " + metadataStatement.getKeyProtection());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
87
src/main/java/me/hatter/webauthn/tests/RegistrationTest.java
Normal file
87
src/main/java/me/hatter/webauthn/tests/RegistrationTest.java
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
package me.hatter.webauthn.tests;
|
||||||
|
|
||||||
|
import com.webauthn4j.WebAuthnManager;
|
||||||
|
import com.webauthn4j.authenticator.Authenticator;
|
||||||
|
import com.webauthn4j.authenticator.AuthenticatorImpl;
|
||||||
|
import com.webauthn4j.converter.exception.DataConversionException;
|
||||||
|
import com.webauthn4j.data.RegistrationData;
|
||||||
|
import com.webauthn4j.data.RegistrationParameters;
|
||||||
|
import com.webauthn4j.data.RegistrationRequest;
|
||||||
|
import com.webauthn4j.data.client.Origin;
|
||||||
|
import com.webauthn4j.data.client.challenge.Challenge;
|
||||||
|
import com.webauthn4j.server.ServerProperty;
|
||||||
|
import com.webauthn4j.validator.attestation.statement.androidkey.AndroidKeyAttestationStatementValidator;
|
||||||
|
import com.webauthn4j.validator.attestation.statement.none.NoneAttestationStatementValidator;
|
||||||
|
import com.webauthn4j.validator.attestation.statement.packed.PackedAttestationStatementValidator;
|
||||||
|
import com.webauthn4j.validator.attestation.statement.u2f.FIDOU2FAttestationStatementValidator;
|
||||||
|
import com.webauthn4j.validator.attestation.trustworthiness.certpath.NullCertPathTrustworthinessValidator;
|
||||||
|
import com.webauthn4j.validator.attestation.trustworthiness.self.DefaultSelfAttestationTrustworthinessValidator;
|
||||||
|
import com.webauthn4j.validator.exception.ValidationException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class RegistrationTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
NoneAttestationStatementValidator noneAttestationStatementValidator = new NoneAttestationStatementValidator();
|
||||||
|
PackedAttestationStatementValidator packedAttestationStatementValidator = new PackedAttestationStatementValidator();
|
||||||
|
FIDOU2FAttestationStatementValidator fidoU2FAttestationStatementValidator = new FIDOU2FAttestationStatementValidator();
|
||||||
|
AndroidKeyAttestationStatementValidator androidKeyAttestationStatementValidator = new AndroidKeyAttestationStatementValidator();
|
||||||
|
WebAuthnManager webAuthnManager = new WebAuthnManager(
|
||||||
|
Arrays.asList(
|
||||||
|
noneAttestationStatementValidator,
|
||||||
|
packedAttestationStatementValidator,
|
||||||
|
fidoU2FAttestationStatementValidator,
|
||||||
|
androidKeyAttestationStatementValidator),
|
||||||
|
new NullCertPathTrustworthinessValidator(),
|
||||||
|
new DefaultSelfAttestationTrustworthinessValidator()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Client properties
|
||||||
|
byte[] attestationObject = null /* set attestationObject */;
|
||||||
|
byte[] clientDataJSON = null /* set clientDataJSON */;
|
||||||
|
String clientExtensionJSON = null; /* set clientExtensionJSON */
|
||||||
|
Set<String> transports = null /* set transports */;
|
||||||
|
|
||||||
|
// Server properties
|
||||||
|
Origin origin = null /* set origin */;
|
||||||
|
String rpId = null /* set rpId */;
|
||||||
|
Challenge challenge = null /* set challenge */;
|
||||||
|
byte[] tokenBindingId = null /* set tokenBindingId */;
|
||||||
|
ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, tokenBindingId);
|
||||||
|
|
||||||
|
// expectations
|
||||||
|
boolean userVerificationRequired = false;
|
||||||
|
boolean userPresenceRequired = true;
|
||||||
|
|
||||||
|
RegistrationRequest registrationRequest = new RegistrationRequest(attestationObject, clientDataJSON, clientExtensionJSON, transports);
|
||||||
|
RegistrationParameters registrationParameters = new RegistrationParameters(serverProperty,
|
||||||
|
// Arrays.asList(
|
||||||
|
// new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.RS256),
|
||||||
|
// new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256)
|
||||||
|
// ),
|
||||||
|
null,
|
||||||
|
userVerificationRequired, userPresenceRequired);
|
||||||
|
RegistrationData registrationData;
|
||||||
|
try {
|
||||||
|
registrationData = webAuthnManager.parse(registrationRequest);
|
||||||
|
} catch (DataConversionException e) {
|
||||||
|
// If you would like to handle WebAuthn data structure parse error, please catch DataConversionException
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
webAuthnManager.validate(registrationData, registrationParameters);
|
||||||
|
} catch (ValidationException e) {
|
||||||
|
// If you would like to handle WebAuthn data validation error, please catch ValidationException
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// please persist Authenticator object, which will be used in the authentication process.
|
||||||
|
Authenticator authenticator = new AuthenticatorImpl(
|
||||||
|
// You may create your own Authenticator implementation to save friendly authenticator name
|
||||||
|
registrationData.getAttestationObject().getAuthenticatorData().getAttestedCredentialData(),
|
||||||
|
registrationData.getAttestationObject().getAttestationStatement(),
|
||||||
|
registrationData.getAttestationObject().getAuthenticatorData().getSignCount()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user